web-dev-qa-db-ja.com

gensim Word2Vecモデルでの単語とベクトルの一致

gensimWord2Vec 実装でWordの埋め込みを計算してもらいました。私が知る限り、すべてが非常に素晴らしいものでした。今、私はいくつかのセマンティックグループを取得することを期待して、作成されたWordベクトルをクラスタリングしています。

次のステップとして、各クラスターに含まれる単語(ベクトルではなく)を調べます。つまり埋め込みのベクトル_[x, y, z]_がある場合、このベクトルが表す実際のWordを見つけたいと思います。 _model.vocab_とWordベクトルを_model.syn0_を介して呼び出すことにより、words/Vocabアイテムを取得できます。しかし、これらが明示的に一致する場所は見つかりませんでした。

これは予想よりも複雑であり、それを行うための明らかな方法を見逃しているのではないかと感じています。どんな助けも大歓迎です!

問題:

Word2Vec ()で作成された埋め込みベクトルに単語を一致させます-どうすればよいですか?

私のアプローチ:

モデル(以下のコード*)を作成した後、各Wordに割り当てられたインデックス(build_vocab()フェーズ中)を_model.syn0_として出力されるベクトル行列に一致させたいと思います。かくして

_for i in range (0, newmod.syn0.shape[0]): #iterate over all words in model
    print i
    Word= [k for k in newmod.vocab if newmod.vocab[k].__dict__['index']==i] #get the Word out of the internal dicationary by its index
    wordvector= newmod.syn0[i] #get the vector with the corresponding index
    print wordvector == newmod[Word] #testing: compare result of looking up the Word in the model -- this prints True
_
  • これを行うより良い方法はありますか?単語に一致するようにモデルにベクトルを供給することにより?

  • これで正しい結果が得られますか?

* Wordベクトルを作成するための私のコード:

_model = Word2Vec(size=1000, min_count=5, workers=4, sg=1)

model.build_vocab(sentencefeeder(folderlist)) #sentencefeeder puts out sentences as lists of strings

model.save("newmodel")
_

この質問 が見つかりましたが、これは似ていますが、実際には回答されていません。

18
patrick

そこで、nmodelがモデルの名前である簡単な方法を見つけました。

#Zip the two lists containing vectors and words
zipped = Zip(nmodel.wv.index2Word, nmodel.wv.syn0)

#the resulting list contains `(Word, wordvector)` tuples. We can extract the entry for any `Word` or `vector` (replace with the Word/vector you're looking for) using a list comprehension:
wordresult = [i for i in zipped if i[0] == Word]
vecresult = [i for i in zipped if i[1] == vector]

これは gensimコード に基づいています。 gensimの古いバージョンでは、モデルの後にwvを削除する必要がある場合があります。

5
patrick

私は長い間、syn0マトリックスと語彙の間のマッピングを見つけるために探していました...ここに答えがあります:use model.index2Wordこれは単純に正しい順序の単語のリストです!

これは公式ドキュメントにはありません(理由は?)が、ソースコード内で直接見つけることができます: /models/Word2vec.py#L441

10
Arcyno

Wordvectorにマッピングするだけなら、単に[]演算子を使用できます。たとえばmodel["hello"]は、helloに対応するベクトルを提供します。

ベクトルからWordを回復する必要がある場合は、提案どおりにベクトルのリストをループし、一致をチェックできます。ただし、これは非効率的でPythonicではありません。便利な解決策は、次のようにWord2vecモデルのsimilar_by_vectorメソッドを使用することです。

import gensim

documents = [['human', 'interface', 'computer'],
 ['survey', 'user', 'computer', 'system', 'response', 'time'],
 ['eps', 'user', 'interface', 'system'],
 ['system', 'human', 'system', 'eps'],
 ['user', 'response', 'time'],
 ['trees'],
 ['graph', 'trees'],
 ['graph', 'minors', 'trees'],
 ['graph', 'minors', 'survey']]

model = gensim.models.Word2Vec(documents, min_count=1)
print model.similar_by_vector(model["survey"], topn=1)

どの出力:

[('survey', 1.0000001192092896)]

ここで、数字は類似性を表します。

ただし、この方法は、すべてのWordベクトルをスキャンして最も類似したものを検索する必要があるため、依然として非効率的です。あなたの問題に対する最善の解決策は、クラスタリングプロセス中にベクトルを追跡する方法を見つけるであるため、高価な逆マッピングに頼る必要がありません。

5
bpachev

@bpachevが述べたように、gensimにはベクトル、つまりsimilar_by_vector

ただし、ブルートフォース線形検索を実装します。つまり、指定されたベクトルと語彙内のすべての単語のベクトル間のコサイン類似度を計算し、上位の隣人を生成します。他の answer で説明した代替オプションは、FLANNなどの近似最近傍検索アルゴリズムを使用することです。

同じことを示す要点の共有: https://Gist.github.com/kampta/139f710ca91ed5fabaf9e6616d2c762b

0
kampta