fastText : Tutorials: 単語表現

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 のためにデフォルト設定で 事前訓練されたモデル を提供します。

 

以上