fastText : Tutorials : 単語表現 (翻訳)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 07/09/2018 (0.1.0)
FAIR の fastText は単語表現とセンテンス分類の効率的な学習のためのライブラリです。
0.1.0 でドキュメントが整備されましたので、再翻訳しています。
* 本ページは、github 上の facebookresearch/fastText の website の Tutorials : Word representations を
動作確認・翻訳した上で適宜、補足説明したものです:
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
現代的な機械学習において人気のあるアイデアは単語をベクトルで表現することです。これらのベクトルは単語の類推や意味のような、言語についての隠れた情報を捕捉します。テキスト分類器のパフォーマンスを改善するためにも使用されます。
このチュートリアルでは、fastText ツールでこれらの単語ベクトルをどのように構築するかを示します。
データを取得する
単語ベクトルを計算するためには、巨大なテキスト・コーパスが必要です。コーパスに依拠して、単語ベクトルは異なる情報を捕捉します。このチュートリアルでは、Wikipedia の記事に注目しますが、news や Webcrawl (更なる例は ここ です) のような他のソースも考えられます。Wikipedia の生ダンプをダウンロードするためには、次のコマンドを実行します :
wget https://dumps.wikimedia.org/enwiki/latest/enwiki-latest-pages-articles.xml.bz2
Wikipedia コーパスのダウンロードにはある程度時間がかかります。代わりに、英語 Wikipedia の最初の 10 億バイトに私達の研究を限定しましょう。それらは Matt Mahoney の Web サイトで見つけられます :
$ mkdir data $ wget -c http://mattmahoney.net/dc/enwik9.zip -P data $ unzip data/enwik9.zip -d data
生 Wikipedia ダンプは多くの HTML / XML データを含みます。それを fastText にバンドルされている wikifil.pl スクリプトで前処理します (このスクリプトは元々は Matt Mahoney により開発されて、彼の Web サイトで見つかります)。
$ perl wikifil.pl data/enwik9 > data/fil9
次のコマンドを実行することによりファイルをチェックできます :
$ head -c 80 data/fil9 anarchism originated as a term of abuse first used against early working class
テキストは上手く前処理されて単語ベクトルを学習するために利用できます。
単語ベクトルを訓練します
このデータ上の単語ベクトルの学習はシングル・コマンドで達成されます :
$ mkdir result $ ./fasttext skipgram -input data/fil9 -output result/fil9
このコマンドラインを分解すると: ./fastext はバイナリ fastText 実行ファイルを ‘skipgram’ モデル (それは ‘cbow’ もあり得ます) で呼び出します。それから必要なオプション (データ位置のための) ‘-input’ と (単語表現がセーブされる位置のための) ‘-output’ を指定します。
fastText が動作している間、進捗と完了までの予定時間が画面上に示されます。プログラムが終了すれば、結果ディレクトリには 2 つのファイルがあるはずです :
$ ls -l result -rw-r-r-- 1 bojanowski 1876110778 978480850 Dec 20 11:01 fil9.bin -rw-r-r-- 1 bojanowski 1876110778 190004182 Dec 20 11:01 fil9.vec
fil9.bin ファイルは fastText モデル全体をストアするバイナリファイルで後でロード可能です。fil9.vec ファイルは、語彙の各単語のために 1 行に 1 つ、単語ベクトルを含むテキストファイルです :
$ head -n 4 result/fil9.vec 218316 100 the -0.10363 -0.063669 0.032436 -0.040798 0.53749 0.00097867 0.10083 0.24829 ... of -0.0083724 0.0059414 -0.046618 -0.072735 0.83007 0.038895 -0.13634 0.60063 ... one 0.32731 0.044409 -0.46484 0.14716 0.7431 0.24684 -0.11301 0.51721 0.73262 ...
最初の行は単語数とベクトル次元を含むヘッダです。続く行は語彙の総ての単語のための単語ベクトルで、頻度の低下によりソートされています。
上級読者のために: skipgram v.s. cbow
fastText は単語表現を計算するために 2 つのモデルを提供します : skipgram と cbow (‘continuous-bag-of-words’) です。
skipgram モデルは近傍の単語からターゲット単語を予測することを学習します。一方、cbow モデルはそのコンテキストからターゲット単語を予測します。コンテキストはターゲット単語の回りの固定サイズのウィンドウに含まれる bag of words として表現されます。
この違いを例で示しましょう : センテンス ‘Poets have been mysteriously silent on the subject of cheese’ とターゲット単語 ‘silent’ が与えられたとき、skipgram モデルは ‘subject’ や ‘mysteriously’ のような、無作為なすぐ近くの単語を使用してターゲットを予測しようとします。cbow モデルは {been, mysteriously, on, the} のような取り囲むウィンドウの総ての単語を取り、ターゲットを予測するためにそれらのベクトルの総計を使用します。下の図は他の例でこの違いを要約しています :
fastText で cbow モデルを訓練するには、次のコマンドを実行してください :
./fasttext cbow -input data/fil9 -output result/fil9
実際には、部分語 (= subword) 情報を伴う skipgram モデルが cbow よりもより良く動作することを観察します。
上級読者のために: パラメータで遊ぶ
ここまで、fastText をデフォルト・パラメータで実行しましたが、データに依拠して、これらのパラメータは最適ではないかもしれません。単語ベクトルのための主要なパラメータの幾つかを紹介しましょう。
モデルのもっとも重要なパラメータはその次元と部分語のためのサイズの範囲です。次元 (dim) はベクトルのサイズを制御し、それらがより大きくなればより多くの情報を捕捉できますが、学習すべきより多くのデータも必要になります。しかしそれらが巨大過ぎれば、訓練するのがより困難により遅くなります。デフォルトでは、100 次元を使用しますが、100-300 の範囲のどのような値でも一般的です。部分語は単語に含まれる最小サイズ (minn) と最大サイズ (maxn) の間の総ての部分文字列です。デフォルトでは、3 と 6 文字の間の部分語総てを取りますが、異なる言語には他の範囲がより適切かもかもしれません :
$ ./fasttext skipgram -input data/fil9 -output result/fil9 -minn 2 -maxn 5 -dim 300
所持するデータ量に依拠して、訓練パラメータを変更することを望むかもしれません。epoch パラメータはデータに渡り何回ループするかを制御します。デフォルトでは、データセットに渡り 5 回ループします。データセットが極めて大きい場合には、より低い頻度でそれに渡りループすることを望むかもしれません。他の重要なパラメータは学習率 -lr です。学習率がより高くなれば、モデルは解により速く収束しますが、データセットへの overfitting のリスクはあります。デフォルト値は 0.05 でこれは良い妥協です。それで遊ぶことを望むのであれば、[0.01, 1] の範囲に留めることを提案します :
$ ./fasttext skipgram -input data/fil9 -output result/fil9 -epoch 1 -lr 0.5
最後に、fastText はマルチ・スレッド化されていてデフォルトでは 12 スレッドを使用します。より少ない CPU コア (例えば 4) を持つ場合には、thread フラグを使用してスレッド数を簡単に設定することができます :
$ ./fasttext skipgram -input data/fil9 -output result/fil9 -thread 4
単語ベクトルをプリントする
fil9.vec ファイルから単語ベクトルを直接的に検索してプリントすることはやっかいです。幸い、fastText には print-word-vectors 機能があります。
例えば、次のコマンドで単語 asparagus, pidgey そして yellow の単語ベクトルをプリントできます :
$ echo "asparagus pidgey yellow" | ./fasttext print-word-vectors result/fil9.bin asparagus 0.46826 -0.20187 -0.29122 -0.17918 0.31289 -0.31679 0.17828 -0.04418 ... pidgey -0.16065 -0.45867 0.10565 0.036952 -0.11482 0.030053 0.12115 0.39725 ... yellow -0.39965 -0.41068 0.067086 -0.034611 0.15246 -0.12208 -0.040719 -0.30155 ...
素晴らしい特徴は貴方のデータに現れない単語を query することもできます!実際に単語はその部分文字列の総和により表現されます。未知の単語が既知の部分文字列からなる限りは、その表現があります!
例としてスペリングを誤った単語で試してみましょう :
$ echo "enviroment" | ./fasttext print-word-vectors result/fil9.bin
依然としてそれに対する単語を得ます!しかしそれはどの程度良いのでしょう?次のセクションで調べてみましょう!
最近傍 query
単語ベクトルの品質をチェックする単純な方法はその最近傍を見ることです。これはベクトルが捕捉できる意味的情報のタイプの直感を与えてくれます。
これは nn 機能により成されます。例えば、次のコマンドを実行することで単語の 10 近傍を query できます :
$ ./fasttext nn result/fil9.bin Pre-computing word vectors... done.
すると query 単語をタイプするように促されますので、asparagus を試してみましょう :
Query word? asparagus beetroot 0.812384 tomato 0.806688 horseradish 0.805928 spinach 0.801483 licorice 0.791697 lingonberries 0.781507 asparagales 0.780756 lingonberry 0.778534 celery 0.774529 beets 0.773984
Nice! 野菜のベクトルが類似しているようです。最近傍は単語 asparagus 自身であることに注意してください、これはこの単語がデータセットに出現したことを意味します。pokemons についてはどうでしょう?
Query word? pidgey pidgeot 0.891801 pidgeotto 0.885109 pidge 0.884739 pidgeon 0.787351 pok 0.781068 pikachu 0.758688 charizard 0.749403 squirtle 0.742582 beedrill 0.741579 charmeleon 0.733625
同じポケモンの異なる進化はすぐ近くのベクトルを持ちます!
ミススペルされた単語についてはどうでしょう、そのベクトルは妥当なものに近いでしょうか? 調べてみましょう :
Query word? enviroment enviromental 0.907951 environ 0.87146 enviro 0.855381 environs 0.803349 environnement 0.772682 enviromission 0.761168 realclimate 0.716746 environment 0.702706 acclimatation 0.697196 ecotourism 0.697081
単語内に含まれる情報のおかげで、ミススペルされた単語のベクトルは妥当な単語に適合します!それは完全ではありませんが主要な情報は捕捉されています。
上級読者のために: 類似性の測定
最近傍を見つけるためには、単語間の類似性スコアを計算する必要があります。私達の単語は連続的な単語ベクトルで表わされますので、それらに単純な類似性を適用することができます。特に 2 つのベクトル間の角度のコサインを使用します。この類似性は語彙の総ての単語のために計算されて、10 の最も類似性のある単語が示されます。もちろん、単語が語彙に出現すれば、それは 類似性 1 を持ちトップに現れます。
単語の類推
同様の意図で、単語の類推で遊ぶことができます。例えば、Berlin が Germany に対応するものとして、何が France に対応するかを私達のモデルは推測できます。
これは analogies 機能によって成されます。それは (Germany Berlin France のような) 単語 3 項を取り類推を出力します :
$ ./fasttext analogies result/fil9.bin Pre-computing word vectors... done. Query triplet (A - B + C)? berlin germany france paris 0.896462 bourges 0.768954 louveciennes 0.765569 toulouse 0.761916 valenciennes 0.760251 montpellier 0.752747 strasbourg 0.744487 meudon 0.74143 bordeaux 0.740635 pigneaux 0.736122
モデルにより提供される答えは Paris で、これは正解です。
もう少し明確ではない例を見てみましょう :
Query triplet (A - B + C)? psx sony nintendo gamecube 0.803352 nintendogs 0.792646 playstation 0.77344 sega 0.772165 gameboy 0.767959 arcade 0.754774 playstationjapan 0.753473 gba 0.752909 dreamcast 0.74907 famicom 0.745298
モデルは psx の nintendo の類推は gamecube であると考え、これは妥当でしょう。もちろん類推の品質はモデルを訓練するために使用されたデータセット依拠し、データセットにある限りの分野をカバーすることだけを望むことができます。
文字 n-grams の重要性
部分語レベルの情報の使用は未知の単語のためのベクトルを構築するために特に興味深いです。例えば、単語 gearshift は Wikipedia に存在しませんが依然としてそれの最も近い既存の単語を query することはできます :
Query word? gearshift gearing 0.790762 flywheels 0.779804 flywheel 0.777859 gears 0.776133 driveshafts 0.756345 driveshaft 0.755679 daisywheel 0.749998 wheelsets 0.748578 epicycles 0.744268 gearboxes 0.73986
取得された単語の殆どは実在する部分語を共有しますが実際には幾つかは非常に異なります、cogwheel のようにです。sunbathe や grandnieces のような他の単語も試すことができます。
未知の単語に対する関心ある部分語の情報を見ましたので、部分語情報を使用しないモデルとどのように比較するかを確認してみましょう。部分語なしでモデルを訓練するためには、次のコマンドを実行するだけです :
$ ./fasttext skipgram -input data/fil9 -output result/fil9-none -maxn 0
結果は result/fil9-non.vec と result/fil9-non.bin にセーブされます。
違いを示すために、(accommodation のミススペリングである) accomodation のような、Wikipedia の一般的ではない単語を取りましょう。ここに部分語なしで得られた最近傍があります :
$ ./fasttext nn result/fil9-none.bin Query word? accomodation sunnhordland 0.775057 accomodations 0.769206 administrational 0.753011 laponian 0.752274 ammenities 0.750805 dachas 0.75026 vuosaari 0.74172 hostelling 0.739995 greenbelts 0.733975 asserbo 0.732465
結果は殆ど意味がなく、それらの単語の多くは無関係です。一方、部分語情報の使用は最近傍の次のリストを与えます :
Query word? accomodation accomodations 0.96342 accommodation 0.942124 accommodations 0.915427 accommodative 0.847751 accommodating 0.794353 accomodated 0.740381 amenities 0.729746 catering 0.725975 accomodate 0.703177 hospitality 0.701426
最近傍は単語 accommodation 回りの異なるバリエーションを捕捉します。amenities や lodging のような意味的に関連する単語もまた得ます。
結論
このチュートリアルでは、Wikipedia からどのように単語ベクトルを得るかを示しました。これは任意の言語に対して遂行され、私達はそれらの 294 のためにデフォルト設定で 事前訓練されたモデル を提供します。
以上