该程序应该返回列表中最相似的第二个文本,因为它是相同的单词。但是这里不是这种情况。
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)]
它显示列表中的第一个文本最相似,而不是第二个文本。您能帮忙吗?
首先,从具有玩具大小的数据集的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()