doc2vec:从推断文档中提取文档

doc2vec: Pull documents from inferred document

我是 word/paragraph 的新手,正在尝试通过 GENSIM 中的 doc2vec 进行嵌入和理解。我想请教一下我的理解是否有误。我的理解是 doc2vec 有可能 return 可能具有语义相似内容的文档。作为测试,我尝试了以下并有以下问题。

问题 1:我注意到每次 运行 使用完全相同的参数和示例进行训练都会产生与之前的训练结果截然不同的模型(例如,不同的向量和相似文档的不同排名 everytime).. 为什么这如此不确定?因此,这是否可以可靠地用于任何实际工作?

问题 2:为什么我没有获取排名靠前的相似文档的标签 ID? 结果:[('day',0.477),('2016',0.386)....

问题2回答:问题是由于model.most_similar,应该用model.docvecs.most_similar代替

如有误会请指教?

数据准备

我创建了多个文档,每个文档都有一个句子。我故意让它们在语义上明显不同。

A: 夏日晴好,鸟语花香,阳光明媚。

B: 这真是美好的一天,要是我有一点鉴赏力就好了。

C:地球科学地球大学2016-2017学位

D: 2009-2010 Dip in Life and Nature 生命学院

查询:思想大学2009年至2010年哲学学位

培训

我训练了文档(tokens 为单词,运行ning 索引为标签)

tdlist=[]
docstring=['It is a fine summer weather, with the birds singing and sun shining bright.',
           'It is a lovely day indeed, if only i had a degree in appreciating.',
           '2016-2017 Degree in Earth Science Earthly University',
           '2009-2010 Dip in Life and Nature Life College']
counter=1
for para in docstring:
   tokens=tokenize(para) #This will also strip punctuation 
   td=TaggedDocument(gensim.utils.to_unicode(str.encode(' '.join(tokens))).split(), str(counter))
   tdlist.append(td)
   counter=counter+1

model=gensim.models.Doc2Vec(tdlist,dm=0,alpha=0.025, size=20, min_alpha=0.025, min_count=0)
for epoch in range(200):
    model.train(tdlist, total_examples=model.corpus_count, epochs=model.iter)

推理

然后我试图推断查询。尽管查询的词汇中有很多缺失的词,但我希望 C 和 D 的文档相似性结果最接近。但结果只给了我一个 'words' 的列表,后跟一个相似性分数。我不确定我的理解是否错误。下面是我的代码摘录。

mydocvector=model.infer_vector(['Degree' ,'in' ,'Philosophy' ,'from' ,'Thinking' ,'University', 'from', '2009', 'to', '2010'])
print(model.docvecs.most_similar(positive=[mydocvector])

Doc2Vec 在玩具大小的数据集上效果不佳 - 文档很少,总字数很少,每个文档的字数很少。您绝对需要比矢量维度 (size) 更多的文档,理想情况下是数万个或更多文档。

TaggedDocument 的第二个参数应该是标签的 列表 。通过提供一个 string-of-an-int,它的每个元素(字符)都将被视为标签。 (只有文档 14 这还不会造成伤害,但是只要你有文档 10,Doc2Vec 就会将其视为标签 10,除非您将其作为 ['10'](单元素列表)提供。

是的,要查找最相似的文档,您可以使用 model.docvecs.most_similar() 而不是 model.most_similar()(它只对学习过的单词进行操作,如果有的话)。

您正在使用 dm=0 模式,这是一个很好的开始想法 – 它速度很快,而且通常表现最好。但请注意,此模式 也不会 训练词向量。所以你从顶级模型中请求的任何东西,比如 model['summer']model.most_similar('sun'),都将是基于随机初始化但从未训练过的单词的无意义结果。 (如果你也需要训练单词,要么将 dbow_words=1 添加到 dm=0 模式,要么使用 dm=1 模式。但是对于纯文档向量,dm=0 是一个很好的选择选择。)

没有必要在循环中调用 train() - 或者根本不需要,因为它上面有一行。您用来实例化 Doc2Vec 的表单,使用实际语料库 tdlist 作为第一个参数,已经使用默认数字触发模型设置 训练的 iter 通过 (5) 和提供的 alphamin_alpha。现在,对于 Doc2Vec 训练,您通常需要更多遍(10 到 20 遍很常见,尽管较小的数据集可能受益于更多遍)。对于任何训练,对于适当的梯度下降,您希望有效学习率 alpha 逐渐下降到可忽略不计的值,例如默认值 0.0001(而不是强制的相同起始值价值)。

您通常会显式调用 train() 的唯一情况是您实例化模型 而没有 语料库。在这种情况下,您需要同时调用 model.build_vocab(tdlist) (让模型使用发现的词汇表进行初始化),然后调用某种形式的 train() - 但您仍然只需要一次调用来训练,提供所需的遍数。 (允许默认 model.iter 5 次传递,在 200 次迭代的外循环内,意味着总共传递 1000 次数据...并且所有传递都固定 alpha,这不是正确的梯度-血统。)

当您拥有更强大的数据集时,您可能会发现更高的 min_count 结果会有所改善。通常只出现几次的词不会产生太多意义,因此只能作为噪声减慢训练并干扰其他向量变得更具表现力。 (不要假设 "more words must equal better results"。)丢弃单例或更多单例通常会有所帮助。

关于推理,你的推理文本中几乎 none 的单词都在训练集中。 (我只看到 'Degree'、'in' 和 'University' 重复。)因此,除了上述所有问题之外,很难为示例文本推断出一个好的向量。使用更丰富的训练集,您可能会获得更好的结果。将 steps 可选参数增加到 infer_vector() 远高于其默认值 5 通常也有帮助。