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

为何相同分词词列表下Doc2Vec的相似度结果异常?

问题:Doc2Vec计算相似句子余弦相似度接近0的排查与修复

我使用Doc2Vec模型,基于2万余篇维基百科文章完成预训练。测试模型效果时,选用了两句语义几乎完全一致的句子:

  1. The process of searching for a job can be very stressful.
  2. The job search process can be very stressful.

预处理分词后得到:

  • list_1 = ['process', 'search', 'job', 'stress']
  • list_2 = ['job', 'search', 'process', 'stress']

但通过doc2vec_model.infer_vector()生成向量,再用gensim.matutils.full2sparse转换为稀疏向量后计算余弦相似度,结果却接近0(如0.00709335870),与预期的接近1相差甚远。相关代码如下:

# model.tokenize_word(data['document_1'] 返回 ['process', 'search', 'job', 'stress']
vec_1 = doc2vec_model.infer_vector(model.tokenize_word(data['document_1'])) 
doc2vec_model.random.seed(0)

# model.tokenize_word(data['document_2'] 返回 ['job', 'search', 'process', 'stress']
vec_2 = doc2vec_model.infer_vector(model.tokenize_word(data['document_2']))
vec_1 = gensim.matutils.full2sparse(vec_1)
vec_2 = gensim.matutils.full2sparse(vec_2)

similarity = gensim.matutils.cossim(vec_1, vec_2)
print(similarity) # 输出 0.00709335870

问题原因

  • 随机种子设置时机错误:生成vec_1之后才设置随机种子,导致两次向量推断使用了不同的初始随机状态。Doc2Vec的infer_vector()依赖随机初始化的向量开始迭代,不同种子会让最终生成的向量差异极大。
  • 冗余的稀疏转换:infer_vector()返回的是密集向量,gensim.matutils.cossim本身支持直接计算密集向量的余弦相似度,转换成稀疏向量完全没必要,甚至可能引入计算误差。
  • 分词过度精简:原始句子被大量裁剪,仅保留4个核心词,上下文信息严重不足。Doc2Vec需要足够的文本长度来捕捉语义,过短的输入会让模型难以生成符合预期的向量。

修复方案

  1. 统一随机种子时机:在调用infer_vector()之前设置随机种子,确保两次推断使用相同的初始状态:
doc2vec_model.random.seed(0)
vec_1 = doc2vec_model.infer_vector(model.tokenize_word(data['document_1'])) 
vec_2 = doc2vec_model.infer_vector(model.tokenize_word(data['document_2']))
  1. 移除稀疏转换步骤:直接用密集向量计算相似度:
similarity = gensim.matutils.cossim(vec_1, vec_2)

也可以用numpy直接计算,结果更直观:

from numpy import dot
from numpy.linalg import norm

similarity = dot(vec_1, vec_2) / (norm(vec_1) * norm(vec_2))
  1. 优化分词策略:保留必要的功能词,避免过度精简。比如分词后保留更多上下文词汇(需与模型训练时的预处理逻辑一致,比如词形还原、小写转换):
  • list_1 = ['process', 'of', 'searching', 'for', 'job', 'can', 'be', 'very', 'stressful']
  • list_2 = ['job', 'search', 'process', 'can', 'be', 'very', 'stressful']
  1. 增加推断迭代次数:默认infer_vector()迭代次数为5,针对短文本可调高至20次左右,让模型更充分地调整向量:
vec_1 = doc2vec_model.infer_vector(model.tokenize_word(data['document_1']), steps=20)
vec_2 = doc2vec_model.infer_vector(model.tokenize_word(data['document_2']), steps=20)

内容的提问来源于stack exchange,提问作者Nguyễn Thanh Huyền

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 00:07:38