基于Quora数据集的Doc2Vec模型:相同句子余弦相似度0.7是否正常?
Doc2Vec模型输出相同句子余弦相似度仅0.7?这肯定有问题!
兄弟,先给你拍板:完全相同的两个句子,余弦相似度只到0.7,这绝对不符合预期——正常情况下,这个值应该非常接近1才对。结合你贴的代码片段,我帮你梳理几个最可能的问题点,以及排查方向:
一、先排查数据预处理环节
你代码里的words1 = train1[i]和words2 = train2[i],有没有确认过当原句完全相同时,words1和words2的分词结果是完全一致的?
- 比如有没有大小写差异:原句是"Hello World",一个转成了小写,另一个没转?
- 标点符号处理:一个句子保留了末尾的问号/感叹号,另一个去掉了?
- 分词工具不一致:比如一个用NLTK分词,另一个用spaCy,导致相同句子拆出来的词列表不一样?
- 停用词/词干化处理:有没有对其中一个句子做了停用词过滤,另一个没做?
先把相同原句对应的words1和words2打印出来对比,这是最基础也是最容易踩坑的点。
二、检查Doc2Vec的训练参数是否合理
Doc2Vec的训练参数直接影响向量质量,以下几个参数如果设置不当,很可能导致相同句子的向量偏差:
vector_size:如果设置得太小(比如小于50),向量的表达能力不足,容易出现相似文本向量差异大的情况,建议至少设为100以上。epochs:训练轮数不够,模型还没充分学习到文本的特征,建议设置为15-20甚至更高(根据数据集大小调整)。min_count:如果这个值设得太高,会过滤掉低频词,要是相同句子里包含不少低频词,模型就没法准确捕捉它们的特征,建议先设为1试试。window:窗口大小太小,模型无法学习到上下文的关联,建议设为3-5。
三、模型输入的构建是否有问题
从你的代码片段看,你把每个问答对的两个句子分别包装成AnalyzedDocument,标签用2*i和2*i+1——这个逻辑本身没问题,但要注意:
- 有没有确保每个
AnalyzedDocument的words是正确的分词结果?比如会不会把整个句子当成一个词传进去了? - 标签是否唯一?虽然你的逻辑是生成唯一标签,但如果数据集里有重复的标签,会干扰模型训练。
四、向量获取的方式是否正确
你是怎么获取句子向量的?如果用的是infer_vector方法,这里有两个关键参数很容易被忽略:
steps:这个参数控制推断时的迭代次数,默认值可能很小(比如5),导致向量推断不充分,建议设为50-100。alpha:初始学习率,建议设为0.025(和训练时的初始学习率一致),逐步衰减。
举个正确的小示例供你参考:
from gensim.models.doc2vec import Doc2Vec, TaggedDocument from sklearn.metrics.pairwise import cosine_similarity # 模拟你的数据:完全相同的句子对 train1 = ["how to learn machine learning".split(), "same test sentence".split()] train2 = ["how to learn machine learning".split(), "same test sentence".split()] # 构建训练数据 docs = [] for idx in range(len(train1)): docs.append(TaggedDocument(train1[idx], tags=[2*idx])) docs.append(TaggedDocument(train2[idx], tags=[2*idx+1])) # 初始化并训练模型 model = Doc2Vec( vector_size=100, window=5, min_count=1, epochs=20, dm=1 # 使用分布式内存模式,也可以试试dm=0的分布式词袋模式 ) model.build_vocab(docs) model.train(docs, total_examples=model.corpus_count, epochs=model.epochs) # 获取相同句子的向量(用infer_vector,设置足够的steps) vec1 = model.infer_vector(train1[0], steps=50, alpha=0.025) vec2 = model.infer_vector(train2[0], steps=50, alpha=0.025) # 计算余弦相似度 similarity = cosine_similarity([vec1], [vec2])[0][0] print(f"相同句子的余弦相似度: {similarity:.4f}") # 正常应该接近1.0
按照上面的步骤逐一排查,应该能找到问题所在。记住,完全相同的文本向量相似度接近1是Doc2Vec的基本预期,0.7的结果说明模型要么没学好,要么数据处理环节出了错。
内容的提问来源于stack exchange,提问作者Gautam Kumar
相关产品推荐
相关产品推荐

