如何提高doc2vec模型中两个文档(句子)的余弦相似度?

2024-06-01 09:21:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用gensim库通过doc2vec模型在Python中构建NLP聊天应用程序。我已经对文档进行了硬编码,并给出了一组培训示例,在测试模型时,首先抛出一个用户问题,然后找到最相似的文档。在本例中,我的测试问题是来自培训示例的文档的精确副本。在

import gensim
from gensim import models
sentence = models.doc2vec.LabeledSentence(words=[u'sampling',u'what',u'is',u'tell',u'me',u'about'],tags=["SENT_0"])
sentence1 = models.doc2vec.LabeledSentence(words=[u'eligibility',u'what',u'is',u'my',u'limit',u'how',u'much',u'can',u'I',u'claim'],tags=["SENT_1"])
sentence2 = models.doc2vec.LabeledSentence(words=[u'eligibility',u'I',u'am',u'retiring',u'how',u'much',u'can',u'claim',u'have', u'resigned'],tags=["SENT_2"])
sentence3 = models.doc2vec.LabeledSentence(words=[u'what',u'is',u'my',u'eligibility',u'post',u'my',u'promotion'],tags=["SENT_3"])
sentence4 = models.doc2vec.LabeledSentence(words=[u'what',u'is', u'my',u'eligibility' u'post',u'my',u'promotion'], tags=["SENT_4"])
sentences = [sentence, sentence1, sentence2, sentence3, sentence4]
class LabeledLineSentence(object):
    def __init__(self, filename):
        self.filename = filename
    def __iter__(self):
        for uid, line in enumerate(open(filename)):
            yield LabeledSentence(words=line.split(), labels=['SENT_%s' % uid])
model = models.Doc2Vec(alpha=0.03, min_alpha=.025, min_count=2)
model.build_vocab(sentences)
for epoch in range(30):
    model.train(sentences, total_examples=model.corpus_count, epochs = model.iter)
    model.alpha -= 0.002  # decrease the learning rate`
    model.min_alpha = model.alpha  # fix the learning rate, no decay
model.save("my_model.doc2vec")
model_loaded = models.Doc2Vec.load('my_model.doc2vec')
print (model_loaded.docvecs.most_similar(["SENT_4"]))

结果:

^{pr2}$

SENT_4和{}的相似性仅为-0.08253869414329529,因为它们完全相同。我应该如何提高这种准确性?是否有一种特定的培训文件的方式,而我却遗漏了一些东西?在


Tags: 文档alphamodelismodelsmytagsfilename
1条回答
网友
1楼 · 发布于 2024-06-01 09:21:56

Word2Vec/Doc2Vec不能很好地处理玩具大小的示例(例如很少的文本、简短的文本和很少的总单词)。许多理想的属性只有通过数百万字或数万个文档的训练集才能可靠地实现。在

特别是,在只有5个例子,只有十几个或两个单词,但是有100个维度的建模向量时,训练并不强制去做使词向量/doc向量有用的主要事情:将表示压缩成密集的嵌入,其中相似的项需要在向量空间中逐渐靠近彼此,因为在一个巨大的查找表中没有办法保留所有的原始变体。与语料库变化相比,维度更多,相同的标记SENT_3和{}可以采用非常不同的doc向量,而且模型仍然足够大,可以在其训练任务上做得很好(本质上是“过度拟合”),而不必强迫具有相似向量的相似文本的期望结束状态。在

有时,您可以通过更多的训练迭代和更小的模型(就向量size)从小数据集中挤出更多的含义,但实际上:这些向量需要大的、变化的数据集才能变得有意义。在

这是主要问题。示例代码中的其他一些低效或错误:

  • 您的代码不使用LabeledLineSentence类,因此不需要在这里包含它–这是不相关的样板。(另外,TaggedDocument是近期gensim版本中words+tags文档类的首选名称,而不是LabeledSentence。)

  • 您对alphamin_alpha的自定义管理不太可能做任何有用的事情。除非你已经有了一些工作,很好地理解了算法,然后想尝试细微的优化,否则最好还是保留它们的默认值。

  • train()将执行自己的迭代,因此不需要在外循环中多次调用它。(这段代码在它的第一个循环5 model.iter迭代中,在alpha值处逐渐从0.03下降到0.025,然后在0.028的固定alpha处进行5次迭代,然后在0.026处再进行5次迭代,最后在第30个循环中以-0.028的固定alpha结束。这是一个无稽之谈的结束值-学习率永远不应该是负的-在一个无意义的进程的结尾。即使有一个大的数据集,这150次迭代(大约一半发生在负的alpha值下)也可能产生奇怪的结果。)

相关问题 更多 >