我在Gensim的Doc2Vec模型中遇到了my_similar方法的问题。当我运行most_similar时,我只得到前10个标记文档的相似性(基于它们的标记 - 总是从0到9)。对于这段代码我有topn = 5,但是我使用了topn = len(文档),我仍然只得到前10个文档的相似性
标记文件:
tokenizer = RegexpTokenizer(r'\w+')
taggeddoc=[]
for index,wod in enumerate(model_data):
wordslist=[]
tagslist=[]
tokens = tokenizer.tokenize(wod)
td = TaggedDocument(gensim.utils.to_unicode(str.encode(' '.join(tokens))).split(), str(index))
taggeddoc.append(td)
documents=taggeddoc
实例化模型:
model=gensim.models.Doc2Vec(documents, dm=0, dbow_words=1, iter=1, alpha=0.025, min_alpha=0.025, min_count=10)
训练模型:
for epoch in range(100):
if epoch % 10 == 0:
print("Training epoch {}".format(epoch))
model.train(documents, total_examples=model.corpus_count, epochs=model.iter)
model.alpha -= 0.002
model.min_alpha = model.alpha
问题在这里(我认为):
new = model_data[100].split()
new_vector = model.infer_vector(new)
sims = model.docvecs.most_similar([new_vector], topn=5)
print(sims)
输出:
[('3', 0.3732905089855194), ('1', 0.36121609807014465), ('7', 0.35790640115737915), ('9', 0.3569292724132538), ('2', 0.3521473705768585)]
培训模型前后的文档长度相同。不确定为什么它只返回前10个文档的相似性。
附带问题:在任何人的经验中,如果输入文档非常短(约50个单词)并且有> 2,000个文档,那么使用Word2Vec或Doc2Vec会更好吗?谢谢你的帮助!
答案 0 :(得分:3)
TaggedDocument()
的第二个参数tags
应该是标记列表,不是单个字符串。
通过提供单个字符串的简单整数,如'109'
,这被解释为标记列表['1', '0', '9']
- 因此在整个语料库中只有10个唯一标记,数字0-9,将被遇到/训练。
将其设为单个标记列表,例如[str(index)]
,您可以获得更符合预期的结果。
关于您的附带问题,Word2Vec
和Doc2Vec
都可以在训练数据中包含数百万字的大型语料库中发挥最佳效果。仅有2,000个文档*每个最多50个单词,最多可提供100,000个训练单词,这些算法非常小。您可以通过使用更小的size
模型和更多培训iter
次传递来获得一些轻微的结果,但这不是那些数据集/问题算法效果很好。
另外,您的训练代码完全错误。
如果您向documents
初始化提供Doc2Vec
,它会自动执行所有必需的词汇表发现和iter
培训通行证 - 请勿拨打{ {1}}了。
如果由于某种原因您未在初始化时提供train()
,则通常应该同时调用documents
和build_vocab()
。
几乎没有人应该在显式循环中多次更改train()
或多次调用min_alpha
:您几乎肯定会做错了,就像在这里一样,你在哪里' ll在100个循环中将有效train()
从0.025减去0.002,结束时无意义的负学习率为-0.175。不要这样,如果你从似乎是一个可靠的在线资源中复制了这种方法,请让该来源知道他们的代码是混淆的。