如何用python的gensim的word2vec模型来计算句子的相似度

根据Gensim的Word2Vec ,我可以使用gensim包中的word2vec模型来计算2个单词之间的相似度。

例如

trained_model.similarity('woman', 'man') 0.73723527 

然而,2vec这个单词不能预测句子的相似性。 我发现在gensim中有句子相似的LSI模型,但似乎并不能和word2vec模型结合使用。 我每句话的语料库篇幅都不是很长(不超过10个字)。 那么,有没有简单的方法来实现这个目标?

这实际上是一个相当具有挑战性的问题,你问。 计算句子相似性需要build立句子的语法模型,理解等同结构(例如,“他昨天走到商店”和“昨天,他走到商店”),发现不仅在代词和动词的相似性,而且在专有名词,在许多真实的文本例子中find统计上的同现/关系等等。

最简单的事情,你可以尝试 – 虽然我不知道这样做会有多好,它肯定不会给你最好的结果 – 将首先删除所有“停止”的话(像“”,“一个“等等,对句子没有太多的意义),然后对这两个句子中的单词运行word2vec,对这一个句子中的向量进行总结,对另一个句子中的向量进行总结,然后找出总和。 通过总结他们,而不是做一个单词的差异,你至less不会受到语序。 这就是说,这将会以很多方式失败,并不是一个好办法(尽pipe这个问题的好办法几乎总是涉及一些NLP,机器学习和其他的聪明)。

所以,简短的回答是,不,没有简单的方法来做到这一点(至less不这样做)。

既然你使用的是gensim,你应该使用它的doc2vec实现。 doc2vec是word2vec到词组,句子和文档级别的扩展。 这是一个非常简单的扩展,在这里描述

~quocle/paragraph_vector.pdf

Gensim很好,因为它直观,快速和灵活。 最棒的是,你可以从官方的word2vec页面抓取预训练词embedded,并且gensim的Doc2Vec模型的syn0层被暴露出来,这样你就可以用这些高质量的向量为embedded词种子!

了Googlenews向量-negative300.bin.gz

我认为gensim绝对是最容易的(到目前为止,对我来说,最好的)在向量空间中embedded句子的工具。

除了上面的Le&Mikolov的论文中,还有其他的句子 – vector技术。 斯坦福大学的Socher和Manning肯定是这个领域最着名的研究人员之一。 他们的工作是基于句子构成语义的原则而来的:

 1. semantics of the words 2. rules for how these words interact and combine into phrases 

他们已经提出了一些这样的模型(越来越复杂)如何使用组合性来构build句子级别的表示。

2011 – 展开recursionautoencoder(非常相对简单,如果感兴趣就从这里开始)

2012 – matrix向量neural network

2013(?) – 神经张量networking

2015年 – 树LSTM

他的论文都可以在socher.org上find。 其中一些模型是可用的,但我仍然推荐gensim的doc2vec。 首先,2011年的URAE并不是特别强大。 此外,它预先训练重量适合解释新闻数据。 他提供的代码不允许您重新训练networking。 你也不能交换不同的单词向量,所以你坚持使用来自Turian的2011 pre-word2vecembedded。 这些载体当然不在word2vec或GloVe的水平上。

还没有与树LSTM工作,但它似乎非常有前途!

tl;博士是的,使用gensim的doc2vec。 但其他方法确实存在!

如果使用word2vec,则需要计算每个句子/文档中所有单词的平均向量,并使用向量之间的余弦相似度。

 def avg_feature_vector(words, model, num_features, index2word_set): #function to average all words vectors in a given paragraph featureVec = np.zeros((num_features,), dtype="float32") nwords = 0 #list containing names of words in the vocabulary #index2word_set = set(model.index2word) this is moved as input param for performance reasons for word in words: if word in index2word_set: nwords = nwords+1 featureVec = np.add(featureVec, model[word]) if(nwords>0): featureVec = np.divide(featureVec, nwords) return featureVec 

计算相似度

 #get average vector for sentence 1 sentence_1 = "this is sentence number one" sentence_1_avg_vector = avg_feature_vector(sentence_1.split(), model=word2vec_model, num_features=300) #get average vector for sentence 2 sentence_2 = "this is sentence number two" sentence_2_avg_vector = avg_feature_vector(sentence_2.split(), model=word2vec_model, num_features=300) sen1_sen2_similarity = 1 - spatial.distance.cosine(sentence_1_avg_vector,sentence_2_avg_vector) 

一旦计算出两组字向量之和,就应该在向量之间取余弦,而不是差分。 余弦可以通过对两个向量的点积进行归一化来计算。 因此,字数不是一个因素。

我正在使用下面的方法,它运作良好。 你首先需要运行一个POSTagger,然后过滤你的句子,去除停用词(决定因素,连词,…)。 我推荐TextBlob APTagger 。 然后,通过对句子中每个单词向量的平均值来build立一个单词2vec。 Gemsim word2vec中的n_similarity方法正是通过允许传递两组单词来进行比较。

有Word2Vec的扩展旨在解决比较较长的文本,如短语或句子的问题。 其中之一是paragraph2vec或doc2vec。

“分布式句子和文档表示法” ~quocle/paragraph_vector.pdf

http://rare-technologies.com/doc2vec-tutorial/

我想更新现有的解决scheme,以帮助计算句子语义相似度的人。

步骤1:

使用gensim加载合适的模型,并计算句子中单词的单词向量并将它们存储为单词列表

步骤2:计算句子向量

语义相似度之间的语义相似度计算是很困难的,但是最近提出了一个名为“ 一个简单但是TOUGH-TO-BEAT基线对于embedded句的嵌套 ”的文章,提出了一个简单的方法,通过计算句子中的单词向量的加权平均,平均向量在它们的第一主分量上的投影。这里,词w的权重是a /(a + p(w)),其中a是参数并且p(w)被称为平滑逆频率这种方法performance明显更好。

这里给出了一个简单的代码来计算句子vector使用SIF(平滑逆频率)在本文提出的方法

步骤3:使用sklearn余弦相似度为句子加载两个向量并计算相似度。

这是计算句子相似度的最简单有效的方法。

您可以使用Word Mover的距离algorithm。 这里是关于WMD的简单描述 。

 #load word2vec model, here GoogleNews is used model = gensim.models.KeyedVectors.load_word2vec_format('../GoogleNews-vectors-negative300.bin', binary=True) #two sample sentences s1 = 'the first sentence' s2 = 'the second text' #calculate distance between two sentences using WMD algorithm distance = model.wmdistance(s1, s2) print ('distance = %.3f' % distance) 

Ps:如果您遇到关于导入pyemd库的错误,可以使用以下命令安装它:

 pip install pyemd 

我已经尝试了以前的答案提供的方法。 它的工作原理是,它的主要缺点是,相似度较大的句子越长(用两个句子的两个平均embedded的余弦得分来计算相似度),因为词越多,正面的语义效应将被添加到句子中。

我认为我应该改变主意,用本文和本文所研究的语句embedded。