2016-03-01 13 views
7

gensimを使ってつぶやきにword2vec表現を練習する必要があります。 gensimで見たほとんどのチュートリアルやコードとは異なり、私のデータは生データではなく、すでに前処理されています。私は65k単語( "未知の"トークンとEOLトークンを含む)を含むテキスト文書の辞書を持っていて、つぶやきはこの辞書に指数をつけた数の少ない行列として保存されています。データフォーマットの簡単な例を以下に見ることができる。あらかじめ定義された辞書と単語インデックスデータのGensim word2vec

dict.txt

you 
love 
this 
code 

ツイート(5が未知であり、6はEOL)私は

[[0, 1, 2, 3, 6], 
[3, 5, 5, 1, 6], 
[0, 1, 3, 6, 6]] 

私はどのようにインデックス表現を処理する必要がありますかわかりません。簡単な方法は、インデックスのリストを文字列のリストに変換することです(つまり、[0,1,2,3,6] - > ['0'、 '1'、 '2'、 '3'、 '6 '])私はword2vecモデルにそれを読んでいる。しかしながら、これはgensimが次に使用される内部インデックスをルックアップしようとするので、非効率的でなければならない。 '2'。

gensimを使用して効率的にこのデータをロードし、word2vec表現を作成するにはどうすればよいですか?

答えて

7

gensimWord2Vecモデルを初期化する通常の方法は、[1]

model = Word2Vec(sentences, size=100, window=5, min_count=5, workers=4) 

質問は、sentences何ですか? sentencesは、単語/トークンの繰り返し可能性のイテレータであるはずです。これはちょうどあなたが持っているnumpy行列のようですが、各行は異なる長さにすることができます。

gensim.models.word2vec.LineSentenceのドキュメントを参照すると、テキストファイルを直接文として読み込む方法が提供されます。ドキュメントによると、ヒントとして、それはかかります

1つの文= 1行;既に処理され、空白で区切られた単語。

words already preprocessedと書かれているのは、下部ケーシング、ステミング、ストップワードフィルタリング、その他すべてのテキストクレンジングプロセスを指しています。あなたの場合、56があなたの文のリストに含まれないようにするため、それらをフィルタリングする必要があります。

numpyの行列があると仮定して、各行が文であると仮定すると、それを2次元配列にキャストし、すべて56を除外する方が良いです。結果の2次元配列は、sentences引数として直接使用して、モデルを初期化することができます。唯一の捉え方は、トレーニング後にモデルにクエリを実行するときに、トークンの代わりにインデックスを入力する必要があるということです。

ここで、モデルが整数を直接取るかどうかという質問が1つあります。 Pythonバージョンでは、タイプをチェックせず、一意のトークンを渡します。その場合のユニークなインデックスは正常に動作します。しかし、ほとんどの場合、モデルをトレーニングするためにC-Extendedルーチンを使用したいと考えています。これは、70倍のパフォーマンスを実現できるため大したことです。 [2]その場合、Cコードは文字列型をチェックすることができます。つまり、文字列とインデックスのマッピングが格納されています。

これは効率的ではありませんか?あなたが持っている文字列は数値であり、一般的に表現する実際のトークンよりもはるかに短い(0のコンパクトなインデックスであると仮定すると)そうではないと思います。したがって、モデルはサイズが小さくなり、最後にモデルの直列化と逆シリアル化にいくらかの労力を節約します。基本的に、入力トークンを短い文字列形式でエンコードし、word2vecトレーニングから分離しました。word2vecモデルは、トレーニング前にこのエンコーディングが発生したことを知らず、必要もありません。

私の哲学はtry the simplest way firstです。私はちょうどモデルの整数のサンプルテスト入力をスローし、何がうまくいかないかを見てみましょう。それが役に立てば幸い。

[1] https://radimrehurek.com/gensim/models/word2vec.html

を[2] http://rare-technologies.com/word2vec-in-python-part-two-optimizing/

+0

単純に整数をモデルに入力できないことが確認できます。元の投稿に書かれているように(おそらくはっきりしていないかもしれませんが)、単純に整数を文字列にマッピングするだけで動作します。 – pir

+0

好奇心の乏しさから、2Dのnumpy配列から '5'と' 6'をどのように除外しますか?各行は常に同じサイズにする必要があります。それはword2vecにそれを提供するために行列を反復するときに実行できますが、それは非常に非効率的です。 – pir

1

を私は同じ問題がありました。 Word2Vecを実行している場合でも

>>> arr_str = np.char.mod('%d', arr) 

を経由して文字列の配列に変換する例外を発生させた:

>>> model = Word2Vec(arr_str) 
ValueError: The truth value of an array with more than one element is ambiguous. 
Use a.any() or a.all() 

私のソリューションは、テキストとして整数の配列を作成し、その後、LineSentenceでword2vec使用することでした。

import numpy as np 
from gensim.models import Word2Vec 
from gensim.models.word2vec import LineSentence 

np.savetxt('train_data.txt', arr, delimiter=" ", fmt="%s") 
sentences = LineSentence('train_data.txt') 
model = Word2Vec(sentences) 
関連する問題