首页 > 解决方案 > doc2vec 不准确的余弦相似度

问题描述

我已经在 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 钢化玻璃防护罩 for micromax canvas juice ”作为与“nokia pewter black 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)

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

标签: pythonmachine-learninggensimword2vecdoc2vec

解决方案


Doc2Vec使用较短的文本会更难——而且看起来你的文本可能只有 5-10 个标记。

您的文本似乎也不是自然语言句子,而是产品名称。Doc2Vec/ -like 分析是否Word2Vec会对这样的文本片段做任何有用的事情,这些文本片段具有与自然口语/书面语言相同的共现多样性,这将取决于数据的特征。我不确定它会不会,但它是正确的——只有尝试/调整它会告诉你。

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

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

Much Doc2Vec/ Word2Vecwork 不会为删除停用词而烦恼,并且可能会将标点符号保留为独立词。

您应该展示“training_data.csv”文件中实际内容的示例,以查看算法实际使用的内容。请注意,它TaggedLineDocument不会正确处理真正的逗号分隔值文件 - 它期望每行只有一个文本,已经用空格分隔。(任何逗号都会留在原地,可能会附加到字段标记上。)

降低min_count到 1 通常会使结果变差,因为这种罕见的标记(只有 1 次或几次出现)不会得到好的向量,但如果它们聚合起来很多(在普通文本中有但可能不在此处) ) 可以作为训练噪声降低其他向量。

您不需要更改min_alpha,一般来说,如果您确定默认值的含义并且有一个严格的、可重复的评分过程来测试更改是否会改善结果,则通常只应修改默认值。(在实现良好的相似性度量的情况下,这样的分数可能是一组应该比第三个项目更相似的项目对。对于您尝试的每个算法/参数,有多少这样的对被正确发现为“比任何一项与第三项更相似”?)

推理,尤其是短文本,可能会受益于不同的参数(例如更多的推理传递)——最新的 gensim 版本(3.5.0,2018 年 7 月)包括对infer_vector(). 所以一定要使用那个版本,并测试提供更大epochs值的改进。

总的来说,我建议:

  • 清楚一个好的相似性结果应该是什么:以最相似和最不相似的项目为例

  • 使用此类示例创建对模型质量的严格自动评估

  • 以保留有意义的区别的领域敏感方式进行预处理;尝试获取/创建不会将品牌词孤立到隐藏潜在跨品牌关系的微小单一产品示例中的文本

  • 除非您确定它有帮助,否则不要更改默认值

  • 在 INFO 级别启用日志记录,以便您可以查看算法的进度和报告有效词汇等内容

根据您真正的“相似性”目标是什么,您仍然可能不会得到很好的结果——产品名称不是Doc2Vec最适合的自然语言。

另一个要考虑的基线是将每个产品名称视为一个“词袋”,这会产生一个单热向量,其中包含哪些词(来自完整的词汇表)。这些 one-hot 向量的余弦相似度(可能带有额外的项权重)将是一个简单的度量,并且至少可以捕获诸如将所有“黑色”项目彼此靠近一些或所有“诺基亚”项目等。


推荐阅读