python - Doc2Vec infer_vector 未按预期工作

标签 python text-classification doc2vec

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

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) – 并且您未启用非默认、不太推荐的替代方案 (hs=1)。根本不会进行任何培训。代码输出中也可能会显示错误 - 而且,如果您至少使用 INFO 级别的日志记录运行,您可能会注意到输出中的其他问题。

第三,infer_vector() 需要一个单词标记列表作为其参数。您提供了一个纯字符串。对于代码来说,这看起来像是一个单字符单词列表,所以就像您要求它推断 23 个单词的句子:

['i', ' ', 'l', 'o', 'v', 'e', ' ', 'c', ...]

infer_vector() 的参数应与训练文本的标记化完全相同。 (如果您在训练期间使用了 word_tokenize(),请在推理期间也使用它。)

infer_vector() 还将对等于 Doc2Vec 模型内的“epochs”值的文本使用多次重复推理传递,除非您指定另一个值(value)。由于您没有指定epochs,因此模型仍将具有默认值epochs=5(继承自Word2Vec)。大多数 Doc2Vec 工作在训练期间使用 10-20 个时期,并且在推理期间至少使用同样多的时期似乎是一个很好的做法。

而且:

不要尝试在循环中多次调用 train() 或在自己的代码中管理 alpha,除非您是专家。

无论什么在线示例都建议使用像您这样的代码块......

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 速率,如果您想更改 epoch 的数量,它非常脆弱,它实际上最终会运行 500 epoch(100 * model.iter),它的代码远远多于所需的代码。

相反,不要更改默认的 alpha 选项,并在创建模型时指定所需的纪元数。因此,模型将缓存一个有意义的 epochs 值,供稍后的 infer_vector() 使用。

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

model = Doc2Vec(size=vec_size,
                min_count=1,  # not good idea w/ real corpuses but OK
                dm=1,  # not necessary to specify since it's the default but OK  
                epochs=max_epochs)
model.build_vocab(tagged_data)
model.train(tagged_data, 
            total_examples=model.corpus_count, 
            epochs=model.epochs)

关于python - Doc2Vec infer_vector 未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59032757/

相关文章:

python - 如何从gensim中的文档中删除停用词?

python - doc2vec的余弦相似度不准确

python - 在多级索引的一个级别上过滤 Pandas 数据框

python - processing.py 中串行库的文档

python - 如何在当前的词袋分类中添加另一个文本特征?在 Scikit-learn 中

machine-learning - 文本分类 - 如何找到对决策影响最大的特征

python - 无法恢复类 TextVectorization 的图层 - 文本分类

python - 如何使用 Gensim doc2vec 执行高效查询?

Python - 装饰器应用的正确顺序

python - 在Python中的嵌套字典中存储目录结构