web-dev-qa-db-ja.com

gensimのWord2vecモデルとpythonを使用して文の類似性を計算する方法

Gensim Word2Vec によれば、gensimパッケージのWord2vecモデルを使用して、2つの単語間の類似性を計算できます。

例えば.

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

ただし、Word2vecモデルは文の類似性を予測できません。 gensimで文の類似性を持つLSIモデルを見つけましたが、Word2vecモデルと組み合わせることができないようです。私が持っている各文のコーパスの長さはそれほど長くありません(10単語よりも短い)。では、目標を達成する簡単な方法はありますか?

107
zhfkt

これは実際にあなたが求めているかなり挑戦的な問題です。文の類似性を計算するには、文の文法モデルを構築し、同等の構造を理解する必要があります(たとえば、「昨日店に歩いた」と「昨日、店に歩いた」)、代名詞や動詞だけでなく、固有名詞、多くの実際のテキスト例での統計的共起/関係の発見など。

あなたが試すことができる最も簡単なことは-これがどれだけうまく機能するかわかりませんが、最適な結果が得られないことは確かです-最初にすべての「ストップ」ワード(「the」、「an "など、文にあまり意味を加えない)、両方の文の単語に対してWord2vecを実行し、1つの文のベクトルを合計し、他の文のベクトルを合計してから、合計。単語ごとの違いを行うのではなく、それらを合計することにより、少なくとも単語の順序に従うことはありません。そうは言っても、これは多くの点で失敗し、決して良い解決策ではありません(この問題に対する優れた解決策は、ほとんどの場合、ある程度のNLP、機械学習、およびその他の賢さを伴います)。

だから、短い答えは、いや、これを行う簡単な方法はありません(少なくともうまくやらない)。

79

Gensimを使用しているので、おそらくdoc2vec実装を使用する必要があります。 doc2vecは、Word2vecをフレーズレベル、センテンスレベル、およびドキュメントレベルに拡張したものです。ここで説明する非常に単純な拡張機能です

http://cs.stanford.edu/~quocle/paragraph_vector.pdf

Gensimは、直感的で、高速で、柔軟性があるため、素晴らしいです。素晴らしいのは、公式のWord2vecページから事前トレーニング済みのWord埋め込みを取得でき、gensimのDoc2Vecモデルのsyn0レイヤーが公開されているため、これらの高品質のベクトルでWord埋め込みをシードできることです!

GoogleNews-vectors-negative300.bin.gz

Gensimは、ベクトル空間に文を埋め込むための間違いなく最も簡単な(そして今のところ、最高の)ツールだと思います。

上記のLe&Mikolovの論文で提案されているもの以外の、文からベクトルへのテクニックは他にもあります。スタンフォードのソッチャーとマニングは、この分野で働いている最も有名な研究者の2人です。彼らの作品は、作曲の原理に基づいています-文の意味論は、

1. semantics of the words

2. rules for how these words interact and combine into phrases

彼らは、文章レベルの表現を構築するために構成性を使用する方法のために、いくつかのそのようなモデル(ますます複雑になる)を提案しました。

2011- 再帰オートエンコーダーの展開 (非常に比較的簡単。興味があればここから始めてください)

2012- 行列ベクトルニューラルネットワーク

2013- 神経テンソルネットワーク

2015- ツリーLSTM

彼の論文はすべてsocher.orgで入手できます。これらのモデルのいくつかは利用可能ですが、私はまだgensimのdoc2vecをお勧めします。たとえば、2011 URAEは特に強力ではありません。さらに、news-yデータの言い換えに適した重みで事前トレーニングされています。彼が提供するコードでは、ネットワークを再訓練することはできません。また、異なるWordベクトルにスワップすることもできないため、Turianの2011年のWord2vecより前の埋め込みに固執しています。これらのベクトルは確かにWord2vecやGloVeのレベルではありません。

Tree LSTMをまだ使用していませんが、非常に有望です!

tl; drええ、gensimのdoc2vecを使用してください。しかし、他の方法も存在します!

66
Willie

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

類似度を計算する:

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
30
tbmihailov

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)

P.s .: import pyemd libraryに関するエラーが発生した場合は、次のコマンドを使用してインストールできます。

pip install pyemd
24
Ehsan

Wordベクトルの2つのセットの合計を計算したら、diffではなくベクトル間のコサインを取る必要があります。余弦は、正規化された2つのベクトルのドット積を取ることで計算できます。したがって、ワード数は要因ではありません。

18
Rani Nelken

文章の意味的類似性を計算する人々を支援するために、既存のソリューションを更新したいと思います。

ステップ1:

Gensimを使用して適切なモデルを読み込み、文内の単語のWordベクトルを計算し、それらをWordリストとして保存します

ステップ2:文ベクトルの計算

文間の意味的類似性の計算は以前は困難でしたが、最近、「 文の埋め込みのためのシンプルでタフなビートのベースライン 」という名前の論文が提案されました。文中のベクトルを計算し、最初の主成分の平均ベクトルの射影を削除します。ここで、単語wの重みはa /(a + p(w))であり、パラメータはp(w)滑らかな逆周波数と呼ばれる(推定される)単語の周波数。

論文で提案されている方法であるSIF(スムーズ逆周波数)を使用して文ベクトルを計算する簡単なコードが与えられました here

ステップ3:sklearn cosine_similarityを使用して、文の2つのベクトルをロードし、類似度を計算します。

これは、文の類似性を計算するための最も簡単で効率的な方法です。

9
Poorna Prudhvi

documentation から機能があり、単語のリストを取得し、それらの類似性を比較します。

s1 = 'This room is dirty'
s2 = 'dirty and disgusting room' #corrected variable name

distance = model.wv.n_similarity(s1.lower().split(), s2.lower().split())
8
Astariul

私は次の方法を使用していますが、うまく機能します。最初にPOSTaggerを実行してから、センテンスをフィルター処理してストップワード(行列式、接続詞など)を削除する必要があります。 TextBlob APTagger をお勧めします。次に、文の各Wordベクトルの平均を取ることにより、Word2vecを構築します。 Gemsim Word2vecのn_similarityメソッド は、2組の単語を渡して比較できるようにすることで、まさにそれを行います。

8
lechatpito

Word2Vecには、フレーズや文章などの長いテキストを比較する問題を解決するための拡張機能があります。それらの1つは、paragraph2vecまたはdoc2vecです。

「文章と文書の分散表現」 http://cs.stanford.edu/~quocle/paragraph_vector.pdf

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

6
Max

Gensimは、Doc2Vecfor というモデルを実装します段落埋め込み

IPythonノートブックとして提示されるさまざまなチュートリアルがあります。

別の方法は、Word2VecおよびWord Mover's Distance(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)

最後に、Tensorflowを実行できる場合は、次を試してください: https://tfhub.dev/google/universal-sentence-encoder/2

4
Wok

以前の回答で提供された方法を試しました。それは機能しますが、主な欠点は、文が長いほど類似性が大きくなることです(類似性を計算するには、2つの文の2つの平均埋め込みのコサインスコアを使用します)文に追加されます。

this paper および this で学習したように、考えを変えて、代わりに文の埋め込みを使用する必要があると考えました。

3
Lerner Zhang

Facebook ResearchグループはInferSent Resultsと呼ばれる新しいソリューションをリリースし、コードはGithubで公開されています。レポを確認してください。とても素晴らしいです。私はそれを使用する予定です。 https://github.com/facebookresearch/InferSent

彼らの論文 https://arxiv.org/abs/1705.02364 要約:多くの最新のNLPシステムは、Wordの埋め込みに依存しています。Wordの埋め込みは、以前は大きなコーパスで教師なしで訓練され、基本機能として使用されていました。しかし、文章などの大きなテキストの部分の埋め込みを取得する努力はそれほど成功していません。教師なしの文の表現を学習しようとするいくつかの試みは、広く採用されるのに十分なパフォーマンスに達していない。この論文では、Stanford Natural Language Inferenceデータセットの教師ありデータを使用してトレーニングされた普遍的な文表現が、幅広い転送タスクでSkipThoughtベクトルのような教師なし方法を一貫して上回る方法を示します。コンピュータービジョンがImageNetを使用して機能を取得し、それを他のタスクに転送できるように、私たちの仕事は、学習を他のNLPタスクに転送するための自然言語推論の適合性を示す傾向があります。エンコーダは一般公開されています。

2
Ayman Salama