Gensim的Doc2vec - 推断向量并不相似

时间:2018-03-07 15:19:25

标签: python gensim doc2vec

当我在大约10k文档的语料库中训练Doc2vec(使用Gensim的Python中的Doc2vec)(每个文档有几百个单词)然后使用相同的文档推断文档向量时,它们与训练的文档完全不相似文件向量。我希望它们至少会有些相似。

我做model.docvecs['some_doc_id']model.infer_vector(documents['some_doc_id'])

少数第一份文件的训练和推断向量之间的余弦距离:

0.38277733326
0.284007549286
0.286488652229
0.173178792
0.370117008686
0.275438070297
0.377647638321
0.171194493771
0.350615143776
0.311795353889
0.342757165432

正如你所看到的,它们并不是很相似。如果即使对于用于培训的文档来说相似性太可怕了,我甚至无法开始尝试推断看不见的文档。

培训配置:

model = Doc2Vec(documents=documents, dm=1, size=100, window=6, alpha=0.1, workers=4, 
seed=44, sample=1e-5, iter=15, hs=0, negative=8, dm_mean=1, min_alpha=0.01, min_count=2)

推断:

model.infer_vector(tokens, steps=20, alpha=0.025)

侧面注意:文档总是以相同的方式进行预处理(我检查了相同的令牌列表进入训练和推断)。

我也玩了一些参数,结果也很相似。因此,如果你的建议类似于"尝试增加或减少这个或那个训练参数",我很可能尝试过。也许我只是没有碰到正确的'参数虽然。

感谢您提出任何建议,以便我们能够做得更好。

编辑:我愿意并且能够使用任何其他可用的段落向量的Python实现(doc2vec)。它不一定是这个。如果你知道另一个可以取得更好结果。

编辑:最小工作示例

import fnmatch
import os
from scipy.spatial.distance import cosine
from gensim.models import Doc2Vec
from gensim.models.doc2vec import TaggedDocument
from keras.preprocessing.text import text_to_word_sequence

files = {}
folder = 'some path'  # each file contains few regular sentences
for f in fnmatch.filter(os.listdir(folder), '*.sent'):
    files[f] = open(folder + '/' + f, 'r', encoding="UTF-8").read()

documents = []
for k, v in files.items():
    words = text_to_word_sequence(v, lower=True)  # converts string to list of words, removes commas etc.
    documents.append(TaggedDocument(tags=[k], words=words))

d2 = Doc2Vec(size=200, documents=documents)

for doc in documents:
    trained = d2.docvecs[doc.tags[0]]
    inferred = d2.infer_vector(doc.words, steps=50)
    print(cosine(trained, inferred))  # cosine similarity from scipy

1 个答案:

答案 0 :(得分:1)

您的documents对象的类型是什么,并且您确定它是一个可乘法迭代的对象,以便模型可以通过TaggedDocument集合执行所有16次传递 - 形文字的例子?也就是说,iter(documents)总是返回一个新的迭代器,所有项目都是TaggedDocument - 形状对象,words中有正确的单词列表,tags中的列表标签1}? (一个常见的错误是提供一个只能迭代一次的语料库,然后忽略没有真正训练发生的任何记录提示/警告。这种模型的推断/相似性结果基本上是随机的。)

然后对于infer_vector()documents[tag]是否真的只返回它所期望的单词列表(不是TaggedDocument或字符串)? (用户经常提供字符串,而不是令牌列表,用于训练或推理words,并获得仅仅是噪音的结果。)

是否存在评估引导的原因,可以更改各种默认值(一点window=6negative=8)或一点(alpha=0.1min_count=2)?这样的调整可能不是你问题的主要因素,并且类默认值没有什么神奇之处。但是在你掌握了基础知识之前,最好坚持使用通用配置。 (然后,即使在基础工作之后,也可以通过可重复的评分过程将变化限制在可以证明更好的那些。)

某些报告需要更高的steps值--100或更多 - 以获得更好的推理结果,尽管这对于非常小的文档(少数几十个单词)而不是少数文件来说是最关键的 - 你描述的百字文件。

10k文档的语料库对于段落向量(Doc2Vec)来说很小,但是使用小的向量大小(100)和更大的迭代次数(15),它可能是可行的。

如果您仍然遇到问题,则应该使用更多代码展示您的问题,其中显示documents如何运作,一些具有启发性的示例文档以及您的余弦相似度评估流程 - 以确定每个代码是否存在任何疏忽这些步骤。