studylog/北の雲

chainer/python/nlp

fastTextのsubword(部分語)の弊害

札幌は1桁まで最低気温が下がってきました。寒いです。

Facebookが開発したfastTextを使ってみました。word2vecっぽくword embeddingをCPU環境で高速に生成してくれます。
github.com

pythonラッパーもありますが生成時に進行状況が表示されないので、生成時は元を使ってそれ以降のembedding利用時にpythonラッパーを使うといいと思います。
日本語で使う場合は分かち書きして半角スペース区切りしておけば大丈夫。

fastTextの一番の特徴としてはsubword(部分語)情報を使っている点でしょうか。

「札幌公園」という単語があったとして、これを「札幌」「幌公」「公園」「札幌公」「幌公園」に分けて、それぞれのベクトルの和を元々の「札幌公園」のベクトルとする、という概念らしい。
未知語や低頻度でもそこそこの精度が出せそう。

元論文
[1607.04606] Enriching Word Vectors with Subword Information
日本語解説
Enriching Word Vectors with Subword Information

低〜中頻度カタカナ語があんまりイケてない

ただ、これだと日本語の場合は主にカタカナ語で問題が生じるっぽい。

■の単語にコサイン類似度で近い意味ベクトルを持つ単語を並べてみました。右側の数字は比較対象の単語との距離(小さい方が近い=意味が似ている)。処理対象はwikipedia日本語版の全記事ページ(2.5GBくらい)、形態素解析mecabデフォルトのmecab-ipadicです。

■ラーニア
グラーニア 0.110071759251
ラーウィーニア 0.199205000797
イオーニア 0.202326828422
マムーニア 0.206659963828
チコーニア 0.207524586709
ゲレーニア 0.208745609686
ポローニア 0.213838900663
ラコーニア 0.217503489063
ラウィーニア 0.217740708759

■オートハイトコントロール
ハイトコントロール 0.0286428025034
アダプティブシフトコントロール 0.0788315688305
クライメートコントロール 0.0833289249448
オートスピードコントロール 0.0900023123386
シンクロレブコントロール 0.0981465376821
レーダークルーズコントロール 0.10443453429
パークディスタンスコントロール 0.107318457674
アクティブスタビリティコントロール 0.108806201904
オーディオリモートコントロールスイッチ 0.109451593292

■ムアンパンガー
ムアンパッタルン 0.109422108154
ムアンラノーン 0.109676683584
ムアンコーンケン 0.111267026516
ムアンサラブリー 0.115317254754
ムアンラムプーン 0.116075613423
ムアンクラビー 0.124810032323
パンガー 0.128222390266
ムアンサムットサーコーン 0.13747850807
ムアンサトゥーン 0.137808885017

なんとなく語感が似ている単語がリストアップされているだけに見える…。
もっとわかりやすい例はティッシュ

ティッシュ
ブリ 0.257772973497
ブリティッシュロック 0.308858462262
ブリティッシュヒルズ 0.312396743261
ブリティッシュ・アンセムズ 0.331879744703
ブリティッシュ・アンビション 0.346499619236
ブリティッシュ・トラッド 0.347967017107
ブリティッシュ・サウンズ 0.348785485835
ブリティッシュビート 0.350252572815
ストーン 0.352235959714

ティッシュとブリティッシュがカタカナだと似すぎているので意味も近くなっちゃってる。
これが英単語だとtissueとBritishだから全然似てない。
でもカタカナにしちゃうとそっくりになるせいで、subword情報を使ったfastTextだと意味ベクトルが近くなる。

これもそう。「〜メモリ」シリーズ。仮面ライダーとITが混在してる。

■ギジメモリ 仮面ライダー
ルナメモリ 仮面ライダー
オンメモリ IT
ファングメモリ 仮面ライダー
メモリバリア IT
バッファメモリ IT
ナスカメモリ 仮面ライダー
メモリ IT
デジメモリ ゲーム?
レジスタードメモリ IT

いずれもそんなに頻繁に登場しない単語だから精度が出ないだけでもっと高頻度単語なら問題は出ないのかもしれないし、wikipediaよりも遥かに大規模なコーパスなら大丈夫なのかもしれません。

手軽に使える

ちなみに500MBコーパスで5年前の4コア8スレッドCPUでも10分かかりません。メモリは1.5GBぐらい確保。
2.5GBコーパスで25分程度で処理終了します。メモリは2~3GBぐらいだったかな。
活用語を落とすなどの前処理をすればもっと高速に終わるはず。
もしメモリが足らなくなる場合は、

  • dim size of word vectors [100]

オプションでdim(意味ベクトルの次元数)を下げてみてください。デフォルトは100です。

おわり。