Gensim Doc2Vec Most_Similar

J. *_*ins 0 python nlp gensim deep-learning doc2vec

我在使用 Gensim 的 Doc2Vec 模型中的 most_similar 方法时遇到了麻烦。当我运行 most_similar 时,我只得到前 10 个标记文档的相似性(基于它们的标签——总是从 0-9)。对于此代码,我有 topn=5,但我使用了 topn=len(documents) 并且我仍然只获得前 10 个文档的相似度

标记文件:

tokenizer = RegexpTokenizer(r'\w+')
taggeddoc=[]

for index,wod in enumerate(model_data):
    wordslist=[]
    tagslist=[]
    tokens = tokenizer.tokenize(wod)

    td = TaggedDocument(gensim.utils.to_unicode(str.encode(' '.join(tokens))).split(), str(index)) 
    taggeddoc.append(td)

documents=taggeddoc
Run Code Online (Sandbox Code Playgroud)

实例化模型:

model=gensim.models.Doc2Vec(documents, dm=0, dbow_words=1, iter=1, alpha=0.025, min_alpha=0.025, min_count=10)
Run Code Online (Sandbox Code Playgroud)

训练模型:

for epoch in range(100):
    if epoch % 10 == 0:
        print("Training epoch {}".format(epoch))
    model.train(documents, total_examples=model.corpus_count, epochs=model.iter)
    model.alpha -= 0.002
    model.min_alpha = model.alpha
Run Code Online (Sandbox Code Playgroud)

问题在这里(我认为):

new = model_data[100].split()
new_vector = model.infer_vector(new)
sims = model.docvecs.most_similar([new_vector], topn=5)
print(sims)
Run Code Online (Sandbox Code Playgroud)

输出:

[('3', 0.3732905089855194), ('1', 0.36121609807014465), ('7', 0.35790640115737915), ('9', 0.3569292724132538), ('2', 0.3521473705768585)]
Run Code Online (Sandbox Code Playgroud)

训练模型前后的文档长度相同。不知道为什么它只返回前 10 个文档的相似性。

附带问题:根据任何人的经验,如果输入文档很短(约 50 个字)并且文档超过 2,000,那么使用 Word2Vec 还是 Doc2Vec 更好?谢谢您的帮助!

goj*_*omo 5

第二个参数TaggedDocument()tags应该是一个列表的标签,不是一个字符串。

通过提供像 这样的简单整数的单个字符串'109',它被解释为标签列表['1', '0', '9']- 因此在整个语料库中,只会遇到/训练 10 个唯一标签,即数字 0-9。

将其设为单标签列表,例如[str(index)],您将获得更符合您预期的结果。

关于你身边的问题,都Word2VecDoc2Vec工作最好与数以百万计的训练数据字的大语料库。仅 2,000 个文档 * 每个最多 50 个单词,最多提供 100,000 个训练单词,对于这些算法来说非常非常小。您可能能够通过使用更小得多的size模型和更多的训练次数来勉强获得一些轻微的结果iter,但这并不是这些算法在处理数据集/问题时表现良好的类型。

另外,您的训练代码完全错误。

  • 如果你提供documentsDoc2Vec初始化时,它会做所有需要的词汇,发现和iter培养会自动将-不叫train()了。

  • 如果由于某种原因你没有documents在初始化时提供,你通常应该同时调用两者build_vocab()train()每一个。

  • 几乎没有人应该在显式循环中多次更改min_alpha或调用train():您几乎肯定会做错,就像这里,您将alpha在 100 次循环中将有效值从 0.025 减少 0.002,最后得到一个无意义的否定学习率为 -0.175。不要这样,如果您从看似可靠的在线来源复制了这种方法,请让该来源知道他们的代码是混乱的。