Doc2Vec infer_vector无法按预期工作

问题描述 投票:1回答:1

该程序应该返回列表中最相似的第二个文本,因为它是相同的单词。但是这里不是这种情况。

import gensim
from nltk.tokenize import word_tokenize
from gensim.models import Word2Vec
from gensim.models.doc2vec import Doc2Vec, TaggedDocument


data = ["I love machine learning. Its awesome.",
        "I love coding in python",
        "I love building chatbots",
        "they chat amagingly well"]


tagged_data=[TaggedDocument(word_tokenize(_d.lower()),tags=[str(i)]) for i,_d in enumerate(data)]

max_epochs = 100
vec_size = 20
alpha = 0.025

model = Doc2Vec(size=vec_size,
                alpha=alpha, 
                min_alpha=0.00025,
                min_count=1,
                negative=0,
                dm =1)

model.build_vocab(tagged_data)

for epoch in range(max_epochs):
    #print('iteration {0}'.format(epoch))
    model.train(tagged_data,
                total_examples=model.corpus_count,
                epochs=model.iter)
    # decrease the learning rate
    model.alpha -= 0.0002
    # fix the learning rate, no decay
    model.min_alpha = model.alpha

model.save("d2v.model")


loaded_model=Doc2Vec.load("d2v.model")
test_data=["I love coding in python".lower()]

v1=loaded_model.infer_vector(test_data)

similar_doc=loaded_model.docvecs.most_similar([v1])
print similar_doc

输出:

[('0', 0.17585766315460205), ('2', 0.055697083473205566), ('3', -0.02361609786748886), ('1', -0.2507985532283783)]

它显示列表中的第一个文本最相似,而不是第二个文本。您能帮忙吗?

python text-classification doc2vec
1个回答
0
投票

首先,从具有玩具大小的数据集的Doc2Vec样式的模型中,您将不会获得良好的结果。仅四个文档和大约20个唯一单词的词汇表就无法创建充满20维向量的,有意义的对比“密集嵌入”向量模型。

[其次,如果您在模型初始化中设置negative=0,则将禁用默认的模型训练校正模式(negative=5)–而不是启用非默认的,建议较少的替代方法([ C0])。完全不会进行任何培训。代码输出中可能还会显示错误-但是,如果运行的是至少hs=1级日志记录,则可能会在输出中注意到其他问题。

第三,INFO要求使用单词表作为其参数。您正在提供一个纯字符串。这看起来像是代码中的一个单字符单词的列表,所以就像您要它推断23个单词的句子一样:

infer_vector()

['i', ' ', 'l', 'o', 'v', 'e', ' ', 'c', ...] 的参数应被标记化,与训练文本被标记化完全相同。 (如果您在训练中使用了infer_vector(),也可以在推理中使用它。)

word_tokenize()还将在与infer_vector()模型中的“历元”值相等的文本上使用多次重复的推理传递,除非您指定其他值。由于未指定Doc2Vec,因此模型的默认值(从epochs继承)仍为Word2Vec。大多数epochs=5工作在训练过程中使用10-20个纪元,在推理中至少使用几个纪元是一个好习惯。

而且:

除非您是专家,否则请不要尝试多次循环调用Doc2Vec,或使用自己的代码管理train()

任何在线示例建议使用类似您的代码块...

alpha

...是bad示例。它错误地上下发送有效的for epoch in range(max_epochs): #print('iteration {0}'.format(epoch)) model.train(tagged_data, total_examples=model.corpus_count, epochs=model.iter) # decrease the learning rate model.alpha -= 0.0002 # fix the learning rate, no decay model.min_alpha = model.alpha 速率,如果您想更改alpha的数量,则非常脆弱,它实际上结束了运行500个纪元(100 * model.iter),这是更多代码超出了必要。

相反,请勿更改默认的epochs选项,并在创建模型时指定所需的时期数。因此,模型将缓存一个有意义的alpha值,以供以后的epochs使用。

然后,仅调用train()一次。它将正确处理所有纪元和Alpha管理。例如:

infer_vector()
© www.soinside.com 2019 - 2024. All rights reserved.