zhf*_*fkt 113 python gensim word2vec
根据Gensim Word2Vec,我可以使用gensim包中的word2vec模型来计算2个单词之间的相似度.
例如
trained_model.similarity('woman', 'man')
0.73723527
Run Code Online (Sandbox Code Playgroud)
但是,word2vec模型无法预测句子相似性.我发现在gensim中具有句子相似性的LSI模型,但是,似乎不能与word2vec模型结合.我所拥有的每个句子的语料库长度不是很长(短于10个单词).那么,有没有简单的方法来实现目标?
Mic*_*yan 81
这实际上是一个非常具有挑战性的问题.计算句子相似度需要建立句子的语法模型,理解等效结构(例如"他昨天走到商店"和"昨天,他走到商店"),不仅在代词和动词中找到相似性,而且在专有名词,在许多真实文本例子中找到统计共现/关系等.
你可以尝试的最简单的事情 - 虽然我不知道这会有多好,而且肯定不会给你最好的结果 - 首先要删除所有"停止"字样(像"the"," "等等,对句子没有多大意义),然后对两个句子中的单词运行word2vec,总结一个句子中的向量,总结另一个句子中的向量,然后找出它们之间的差异总和.通过总结它们而不是做一个单词差异,你至少不会受到单词顺序的影响.话虽如此,这将在很多方面失败,并且无论如何都不是一个好的解决方案(尽管这个问题的好解决方案几乎总是涉及一些NLP,机器学习和其他聪明).
所以,简短的回答是,不,没有简单的方法可以做到这一点(至少不要做得好).
小智 70
既然你正在使用gensim,你应该使用它的doc2vec实现.doc2vec是word2vec对短语,句子和文档级别的扩展.这是一个非常简单的扩展,在这里描述
http://cs.stanford.edu/~quocle/paragraph_vector.pdf
Gensim很好,因为它直观,快速,灵活.最棒的是你可以从官方的word2vec页面中获取预训练的单词嵌入,并且暴露了gensim的Doc2Vec模型的syn0层,这样你就可以使用这些高质量的向量来嵌入单词嵌入!
了Googlenews向量-negative300.bin.gz
我认为gensim绝对是将一个句子嵌入向量空间中最简单的(也是迄今为止我最好的)工具.
除了上面Le&Mikolov的论文中提出的技术之外,还存在其他的句子到矢量技术.斯坦福大学的Socher和Manning肯定是这一领域最着名的研究人员之一.他们的工作基于组合原则 - 句子的语义来自:
1. semantics of the words
2. rules for how these words interact and combine into phrases
Run Code Online (Sandbox Code Playgroud)
他们提出了一些这样的模型(变得越来越复杂),以便如何使用组合来构建句子级表示.
2011 - 展开递归自动编码器(非常简单.如果感兴趣,请从这里开始)
2012年 - 矩阵向量神经网络
2013年 - 神经张量网络
2015年 - 树LSTM
他的论文都可以在socher.org上找到.其中一些模型可用,但我仍然推荐gensim的doc2vec.首先,2011 URAE并不是特别强大.此外,它还预先配备了适用于解释新闻数据的权重.他提供的代码不允许您重新训练网络.你也不能交换不同的单词向量,所以你会遇到来自Turian的2011年pre-word2vec嵌入.这些向量肯定不在word2vec或GloVe的级别上.
尚未使用Tree LSTM,但它看起来很有前途!
tl;博士是的,使用gensim的doc2vec.但其他方法确实存在!
小智 34
如果您使用的是word2vec,则需要计算每个句子/文档中所有单词的平均向量,并使用向量之间的余弦相似度:
import numpy as np
from scipy import spatial
index2word_set = set(model.wv.index2word)
def avg_feature_vector(sentence, model, num_features, index2word_set):
words = sentence.split()
feature_vec = np.zeros((num_features, ), dtype='float32')
n_words = 0
for word in words:
if word in index2word_set:
n_words += 1
feature_vec = np.add(feature_vec, model[word])
if (n_words > 0):
feature_vec = np.divide(feature_vec, n_words)
return feature_vec
Run Code Online (Sandbox Code Playgroud)
计算相似度:
s1_afv = avg_feature_vector('this is a sentence', model=model, num_features=300, index2word_set=index2word_set)
s2_afv = avg_feature_vector('this is also sentence', model=model, num_features=300, index2word_set=index2word_set)
sim = 1 - spatial.distance.cosine(s1_afv, s2_afv)
print(sim)
> 0.915479828613
Run Code Online (Sandbox Code Playgroud)
小智 25
您可以使用Word Mover的距离算法.这里有一个关于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)
Run Code Online (Sandbox Code Playgroud)
Ps:如果您遇到有关import pyemd库的错误,可以使用以下命令安装它:
pip install pyemd
Run Code Online (Sandbox Code Playgroud)
Poo*_*hvi 10
我想更新现有的解决方案,以帮助那些计算句子语义相似性的人.
步骤1:
使用gensim加载合适的模型,并计算句子中单词的单词向量,并将它们存储为单词列表
第2步:计算句子向量
句子之间的语义相似度的计算是困难的,但是最近提出了一篇名为" 简单但是针对句子嵌入的强烈基础的基础 "的论文,它提出了一种简单的方法,通过计算句子中单词向量的加权平均值然后删除平均向量在它们的第一主成分上的投影.这里w的权重是a /(a + p(w)),其中a是参数,p(w)是(估计的)单词频率,称为平滑反频率这种方法表现得更好.
步骤3:使用sklearn cosine_similarity为句子加载两个向量并计算相似度.
这是计算句子相似性的最简单有效的方法.
Ast*_*iul 10
文档中有一项功能,可获取单词列表并比较它们的相似性。
s1 = 'This room is dirty'
s2 = 'dirty and disgusting room' #corrected variable name
distance = model.wv.n_similarity(s1.lower().split(), s2.lower().split())
Run Code Online (Sandbox Code Playgroud)
我使用以下方法,它运作良好.你首先需要运行一个POSTagger然后过滤你的句子来摆脱停用词(决定因素,连词,......).我推荐TextBlob APTagger.然后通过取句子中每个单词向量的平均值来构建word2vec.Gemsim word2vec中的n_similarity方法正好通过允许传递两组单词进行比较.
小智 6
Word2Vec的扩展旨在解决比较较长文本(如短语或句子)的问题.其中一个是paragraph2vec或doc2vec.
"句子和文件的分布式表示" http://cs.stanford.edu/~quocle/paragraph_vector.pdf
http://rare-technologies.com/doc2vec-tutorial/
Gensim为段落嵌入实现了一个称为Doc2Vec的模型。
IPython笔记本提供了不同的教程:
另一种方法将依赖Word2Vec和Word Mover的距离(WMD),如本教程所示:
另一种解决方案是依靠平均向量:
from gensim.models import KeyedVectors
from gensim.utils import simple_preprocess
def tidy_sentence(sentence, vocabulary):
return [word for word in simple_preprocess(sentence) if word in vocabulary]
def compute_sentence_similarity(sentence_1, sentence_2, model_wv):
vocabulary = set(model_wv.index2word)
tokens_1 = tidy_sentence(sentence_1, vocabulary)
tokens_2 = tidy_sentence(sentence_2, vocabulary)
return model_wv.n_similarity(tokens_1, tokens_2)
wv = KeyedVectors.load('model.wv', mmap='r')
sim = compute_sentence_similarity('this is a sentence', 'this is also a sentence', wv)
print(sim)
Run Code Online (Sandbox Code Playgroud)
最后,如果您可以运行Tensorflow,则可以尝试:https ://tfhub.dev/google/universal-sentence-encoder/2