You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用BERTClient计算余弦相似度时代码运行不终止,如何优化?

问题分析与代码优化

你的代码一直跑停不下来,核心问题是效率极低,还有几个细节疏漏,我给你拆解下问题和优化方案:

核心问题拆解

  1. 逐词编码的巨大开销:你在嵌套循环里每次单独调用bc.encode([w]),20万个单词就要发起20万次编码请求(不管BERT服务是本地还是远程),这会产生海量的网络/计算开销,运行时间会夸张到离谱。
  2. 关键词未处理换行符:从文件读取的keyword会自带换行符\n,比如原本是"apple",读出来会变成"apple\n",这会让BERT编码出错误的向量,影响相似度计算的准确性。
  3. 无意义的全量打印:你打印了100*20万=2亿个余弦值,这不仅完全没必要,还会拖慢程序运行速度。
  4. 未实现top50筛选逻辑:你的代码没有保存和排序相似度结果,根本没法得到每个关键词对应的top50相似词。

优化后的代码

下面是修正后的版本,用批量编码+批量计算相似度的方式,效率会提升几个数量级,同时实现你需要的top50功能:

from sklearn.metrics.pairwise import cosine_similarity
from bert_serving.client import BertClient

# 初始化BERT客户端
bc = BertClient()

# 1. 读取并预处理所有单词:过滤空字符串,批量编码
with open("./words.txt", "r", encoding='utf8') as textfile:
    words = [word.strip() for word in textfile.read().split() if word.strip()]
# 一次性批量编码所有单词,大幅减少编码请求次数
word_vectors = bc.encode(words)

# 2. 读取并预处理关键词:过滤空行,去掉换行符
with open("./100_keywords.txt", "r", encoding='utf8') as keyword_file:
    keywords = [kw.strip() for kw in keyword_file if kw.strip()]

# 3. 遍历每个关键词,计算相似度并筛选top50
for keyword in keywords:
    # 编码当前关键词
    keyword_vector = bc.encode([keyword])
    # 批量计算当前关键词与所有单词的余弦相似度
    similarities = cosine_similarity(keyword_vector, word_vectors)[0]  # 获取一维相似度数组
    # 将单词与相似度配对,按相似度降序排序
    word_similarity_pairs = list(zip(words, similarities))
    word_similarity_pairs.sort(key=lambda x: x[1], reverse=True)
    # 提取top50结果
    top50 = word_similarity_pairs[:50]
    
    # 输出结果(也可以写入文件方便后续查看)
    print(f"=== 关键词: {keyword} 的Top50相似词 ===")
    for idx, (word, score) in enumerate(top50, 1):
        print(f"{idx}. {word} - 相似度: {score:.4f}")
    print("\n")

额外优化建议

  • 如果你的BERT服务是远程部署的,可以检查客户端的连接配置,确保批量传输的效率最优。
  • 20万词的BERT向量(768维)大概占用600MB内存,一般机器都能承载;如果内存不足,可以分批次处理单词。
  • 可以把结果写入文件而非打印,比如用with open(f"{keyword}_top50.txt", "w", encoding='utf8') as f:来保存每个关键词的结果。

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

火山引擎 最新活动