Tha*_*Bui 5 python nlp gensim word2vec doc2vec
我Doc2vec用来从单词中获取向量。请看我下面的代码:
from gensim.models.doc2vec import TaggedDocument
f = open('test.txt','r')
trainings = [TaggedDocument(words = data.strip().split(","),tags = [i]) for i,data in enumerate(f)
model = Doc2Vec(vector_size=5, epochs=55, seed = 1, dm_concat=1)
model.build_vocab(trainings)
model.train(trainings, total_examples=model.corpus_count, epochs=model.epochs)
model.save("doc2vec.model")
model = Doc2Vec.load('doc2vec.model')
for i in range(len(model.docvecs)):
print(i,model.docvecs[i])
Run Code Online (Sandbox Code Playgroud)
我有一个test.txt文件,它的内容有2行,并且这2行的内容是相同的(它们是“ a”),我用doc2vec训练并得到了模型,但是问题是尽管2行的内容是相同的,doc2vec给了我两个不同的向量
0 [ 0.02730868 0.00393569 -0.08150548 -0.04009786 -0.01400406]
1 [ 0.03916578 -0.06423566 -0.05350181 -0.00726833 -0.08292392]
Run Code Online (Sandbox Code Playgroud)
我不知道为什么会这样。我认为这些向量将是相同的。你能解释一下吗?如果我想为相同的单词制作相同的向量,在这种情况下该怎么办?
Doc2Vec(和Word2Vec)算法中存在固有的随机性,例如,初始向量已经是随机的,即使对于相同的句子也有所不同。您可以评论model.train call and see this for yourself.
如果您感兴趣,请提供详细信息:向量在vocab生成后立即初始化:在您的情况下,它被model.build_vocab(...)调用,后者依次调用model.reset_doc_weights()方法(请参阅参考资料中的源代码gensim/models/doc2vec.py),该方法随机初始化所有向量,而不管句子是什么。如果此时您重置了初始化并分配了相等的向量,则它们不应再发散了。
从理论上讲,如果您对相同的句子训练的时间足够长,即使初始化不同,该算法也应收敛到相同的向量。但是实际上,这不会发生,我不认为您应该为此担心。
@Maxim's answer关于算法使用的固有随机性是正确的,但是这个例子还有其他问题:
Doc2Vec在微小的、玩具大小的例子上没有给出有意义的结果。只有当向量是大量不同的对比训练上下文的结果时,向量才会获得良好的相对意义。您的 2 行数据集经过 55 个训练周期,实际上只是为模型提供了 1 个独特的文本,110 次。
即使您明智地将向量大小减小到一个很小的数字 (5) 以反映微小的数据,但对于仅 2 个示例而言,它仍然是一个太大的模型,容易完全“过度拟合”。该模型可以随机分配第 1 行的向量 [1.0, 0.0, 0.0, 0.0, 0.0] 和第 2 行 [0.0, 1.0, 0.0, 0.0, 0.0]。然后,通过它的所有训练,只更新其内部权重(从不更新文档向量本身),但仍然实现与真实场景一样好或更好的内部单词预测,在真实场景中,一切都是增量更新的,因为有足够的免费在模型中声明从来没有任何必要的竞争/压缩/权衡迫使两个句子在相似的地方收敛。(有很多解决方案,大多数不涉及任何有用的广义“学习”。只有大型数据集,
dm_concat=1是一种非默认的实验模式,需要更多的数据来训练,并导致模型更大/更慢。避免使用它,除非您确定 - 并且可以用结果证明 - 它有助于您的使用。
即使这些是固定的,完全确定性也不是自动的Doc2Vec——你不应该真的试图消除它。(运行之间的小抖动是该算法中基本差异的有用信号/提醒——如果您的训练/评估在如此小的差异中保持稳定,那就是它起作用的额外指标。)