You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于两个DataFrame计算句子相似度时的性能优化问题

优化相似度计算的核心方案:从O(N*M)到O(N+M)

你的问题本质是低效的循环和重复计算导致的性能灾难:150万条评论 × 39个主题,嵌套iterrows循环加上每次都调用nlp()处理文本,光是重复计算主题向量就做了150万次——这完全是没必要的开销。下面是针对性的优化步骤,能把运行时间从小时级压缩到分钟级甚至更短:


1. 预计算所有主题的向量(只做一次)

39个主题的关键词是固定的,完全不需要在每次处理评论时重复解析。先一次性把所有主题的向量计算好,存成矩阵:

import numpy as np

# 预计算主题向量,仅执行一次
topic_vectors = []
topic_indices = []

for idx, row in topics_words_df.iterrows():
    doc = nlp2(row['TopicKeyWords'])
    if doc.vector_norm:
        # 保留有效向量
        topic_vectors.append(doc.vector)
    else:
        # 处理无向量的主题(比如空关键词),用全0向量代替
        topic_vectors.append(np.zeros(nlp2.vocab.vectors_length))
    topic_indices.append(idx)

# 转为numpy矩阵,形状:(39, 向量维度),比如300维
topic_matrix = np.array(topic_vectors)

2. 批量处理评论向量(利用spaCy的pipe)

spaCy的nlp.pipe()是专门为批量文本处理设计的,比逐行调用nlp()快数倍,还支持多进程/CPU加速(GPU会自动适配):

# 批量生成所有评论的向量
comment_vectors = []

# batch_size根据内存调整,n_process=-1用满所有CPU核心
for doc in nlp2.pipe(Post_sent_df['Sent_text'], batch_size=1000, n_process=-1):
    if doc.vector_norm:
        comment_vectors.append(doc.vector)
    else:
        comment_vectors.append(np.zeros(nlp2.vocab.vectors_length))

# 转为numpy矩阵,形状:(1500000, 向量维度)
comment_matrix = np.array(comment_vectors)

3. 用矩阵乘法一次性计算所有相似度

spaCy的similarity()本质是余弦相似度,我们可以用numpy的矩阵运算直接批量计算,这比循环快几个数量级:

# 归一化向量(余弦相似度需要除以向量的L2范数)
comment_norm = np.linalg.norm(comment_matrix, axis=1, keepdims=True)
topic_norm = np.linalg.norm(topic_matrix, axis=1, keepdims=True)

# 避免除以0的情况(全0向量的相似度设为0)
comment_norm[comment_norm == 0] = 1
topic_norm[topic_norm == 0] = 1

# 计算相似度矩阵:形状(1500000, 39),每个元素对应一条评论和一个主题的相似度
similarity_matrix = np.dot(comment_matrix / comment_norm, (topic_matrix / topic_norm).T)

4. 把结果合并到原DataFrame

最后把相似度矩阵转成DataFrame,和原表合并即可:

# 生成相似度列,列名对应主题索引
similarity_df = pd.DataFrame(
    similarity_matrix,
    columns=topic_indices,
    index=Post_sent_df.index
)

# 合并到原DataFrame
Post_sent_df = pd.concat([Post_sent_df, similarity_df], axis=1)

额外优化建议

  • GPU加速:如果Colab使用GPU实例,确保安装了GPU版本的spaCy(pip install spacy[cuda11x]),nlp.pipe()会自动利用GPU,速度再提升数倍。
  • 提前过滤无效文本:先清理Post_sent_df['Sent_text']中的空字符串、纯标点等无效内容,减少不必要的向量计算。
  • 内存优化:如果内存不够,可以把评论分成若干块(比如每次处理10万条),分块计算后再合并结果,避免一次性加载150万条向量。

这样优化后,整个流程的时间复杂度从O(N*M)降到O(N+M),运行时间会大幅降低,完全能在Colab中完成任务。

内容的提问来源于stack exchange,提问作者AHmDania

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 13:34:08