Skip to main content
 首页 » 编程设计

python之doc2vec的余弦相似度不准确

2025年05月04日10java哥

我已经在400万条记录上训练了doc2vec模型。我想从数据中查找与我输入的新句子最相似的句子,但结果却很糟糕。

数据样本:

Xolo Era (Black, 8 GB)(1 GB RAM). 
Sugar C6 (White, 16 GB)(2 GB RAM). 
Celkon Star 4G+ (Black & Dark Blue, 4 GB)(512 MB RAM). 
Panasonic Eluga I2 (Metallic Grey, 16 GB)(2 GB RAM). 
Itel IT 5311(Champagne Gold). 
Itel A44 Pro (Champagne, 16 GB)(2 GB RAM). 
Nokia 2 (Pewter/ Black, 8 GB)(1 GB RAM). 
InFocus Snap 4 (Midnight Black, 64 GB)(4 GB RAM). 
Panasonic P91 (Black, 16 GB)(1 GB RAM). 


在传递此数据之前,我已经完成了预处理,包括
1)停止单词删除。
2)去除特殊字符和数值。
3)小写数据。
我在测试过程中也执行了相同的步骤。

我用于训练的代码:

sentences=doc2vec.TaggedLineDocument('training_data.csv') # i have used TaggedLineDocument which can generate label or tags for my data 
 
max_epochs = 100 
vec_size = 100 
alpha = 0.025 
 
model = doc2vec.Doc2Vec(vector_size=vec_size, 
                alpha=alpha,  
                min_alpha=0.00025, 
                dm =1, 
                min_count=1) 
model.build_vocab(sentences) 
model.train(sentences, epochs=100, total_examples=model.corpus_count) 
model.save('My_model.doc2vec') 


好吧,我是gensim和doc2vec的新手,所以我遵循了训练模型的示例,因此如果我使用了错误的参数,请更正我。

在测试方面

model = gensim.models.doc2vec.Doc2Vec.load('My_model.doc2vec') 
test = 'nokia pewter black gb gb ram'.split() 
new_vector = model.infer_vector(test) 
similar = model.docvecs.most_similar([new_vector])  
print(similar) # It returns index of sentence and similarity score 


为了进行测试,我通过了与训练数据中相同的句子,但是模型没有提供与类似文件相关的文档,例如,我得到了“ lootmela钢化玻璃防护罩,用于micromax帆布果汁”,这与“诺基亚锡合金黑gb gb”最为相似ram”,该句子的相似度为0.80。

So my questions to you:  
1) Do i need to reconsider parameters for model training? 
2) Training process is correct? 
3) How to build more accurate model for similarity? 
4) Apart from doc2vec what will be your suggestion for similarity (keeping in mind i have very large data so training and testing time should not be much longer) 


如果问题格式不好,请原谅。

请您参考如下方法:

Doc2Vec使用较短的文字会比较困难–看来您的文字可能只有5-10个标记。

您的文字也似乎不是自然语言的句子-而是产品名称。类似于Doc2Vec / Word2Vec的分析是否会对与自然口语/书面语言没有同等共生多样性的文本片段有用,这取决于数据的特征。我不确定会不会,但是可能会发生-只有尝试/调整它才能说明问题。

但是,尚不清楚您期望的结果是什么。什么样的产品名称应该以最相似的形式返回?同一个品牌?一样的颜色? (如果有任何一种,您可以使用比Doc2Vec培训简单得多的模型。)相同的规格,包括内存吗? (如果是这样,您将不希望丢弃数字信息–相反,您可能希望将其规范化为单个标记,这些标记在影响Doc2Vec的逐个单词级别有意义,例如将“ 64 GB”转换为“ 64gb”或“ 2 GB RAM”转换为“ 2gbram”。)

由于这不是常规的自然语言文本,因此您的词汇量可能非常小-可能只有数千个标记,而不是正常语言中的数万至数十万。而且,每个令牌只能出现在少数示例中(单个生产者的产品线),并且绝对不会与相似竞争产品中的密切相关术语一起出现(因为产品名称不会与竞争对手的专有名称混为一谈)。这也会给这种算法带来挑战-需要将单词的多种多样的重叠用法以及许多具有精细含义的单词逐渐转移到有用的排列中。词汇量较小可能需要使用小得多的模型(较低的vector_size),以避免过度拟合。如果您有一个数据集可以暗示人们认为哪些产品具有可比性-在同一评论中提到,或者由同一人搜索,或者由同一人购买-您可能要创建额外的合成文字示例,在其中包含这些多个产品相同的文本-这样算法就有机会学习这种关系。

Doc2Vec / Word2Vec的很多工作都不会消除停用词,并且可能会将标点符号保留为独立的词。

您应该显示“ training_data.csv”文件中实际内容的示例,以查看该算法实际使用的内容。请注意,TaggedLineDocument无法正确处理实际的逗号分隔值文件-期望每行只有一个文本,已经用空格分隔。 (任何逗号都将保留在原位,或者附加到字段令牌上。)

将min_count降低到1通常会使结果变差,因为这样的罕见标记(只有1个或几次出现)无法获得良好的向量,但是如果它们合计很多(正常文本中有,但是可能不在此处)可以用作降低其​​他向量的训练噪声。

您不需要更改min_alpha,通常,只有在您确定默认值并具有严格,可重复的评分过程以测试更改是否在改善结果时,才应修改默认值。 (在获得良好的相似性度量的情况下,这样的分数可能是一组项目对,它们应该比某些第三项更为相似。对于您尝试的每种算法/参数,可以正确发现多少对这样的对,例如“比第三个项目更相似”)

推理,尤其是短文本上的推理,可能会受益于不同的参数(例如,更多的推理过程)–最新的gensim版本(3.5.0,2018年7月)包括重要的修复程序和对infer_vector()默认值的调整。因此,请确保使用该版本,并测试为它提供更大的epochs值的改进。

总体而言,我建议:


清楚应说明相似性良好的结果:以最相似和最不相似的商品为例
使用此类示例创建对模型质量的严格自动化评估
以领域敏感的方式进行预处理,以保留有意义的区别;尝试获取/创建不会将品牌词弄乱的文本,以隐藏潜在的跨品牌关系的微型单产品示例
不要更改默认值,除非您确定它会有所帮助
在INFO级别启用日志记录,以便您可以查看算法的进度和报告有效词汇等情况


取决于您真正的“相似性”目标是什么,您仍然可能无法获得很好的结果–产品名称不是Doc2Vec的最佳自然语言。

要考虑的另一个基准是将每个产品名称都视为“单词袋”,这会产生一个“热”向量,其中包含单词(来自完整词汇)。这些单热点向量的余弦相似度(可能带有额外的词项加权)将是一种简单的度量,并且至少可以捕获诸如将所有“黑色”项目彼此之间或所有“诺基亚”项目彼此放置得更近的东西。