人工知能してみる

人工知能の中の人が機械学習とか統計とかAI的なことを書き連ねます

Facebook社の自然言語処理ライブラリfastTextを使ってみる

こんには、Grahamianです。
今日は Facebook が公開している自然言語処理ライブラリである fastText を使ってみます。

fastText はこちら!
github.com

インストールは readme に書いてあるとおりなので省略するとして。fastText は何ができるかというとCPUでも高速に自然言語処理を行うことができるのが特徴です。 実際かなり早くて既存のものにくらべると「コレ本当に大丈夫?」と心配になるほど早いです。なぜなのかは実装見ないと分からないのでちょいと不明ですがテストしてみた感じでは使えそうです。

さて、fastText の使い方ですが、大きく分けて2つのことができます。
1つ目は単語のベクトル表現の獲得、2つ目は文書の分類です。

単語のベクトル表現の獲得

自然言語処理をするときは単語の Bag-of-Words(BoW) を使うのが古典的に一般でした。BoW は one hot vector で何かの単語が出現するとその要素が1つ増える、みたいなベクトルのことです。詳しくはググってください。 で、fastText は BoW よりも表現力が豊かな C-BoW と skip-gram を採用しています。Word2Vec でも採用されているアルゴリズムですね。それぞれの詳細はここでは書きませんが現代では一般的な手法で、単語周辺の文脈を盛り込むことができるので単純な BoW に比べるとかなり強力です。
似たようなライブラリとして Word2Vec があります。実はアルゴリズムが少し違い、fastText は subword分割 という手法を採用しているので同じテキストを学習させても結果が異なります。詳しくは検証してくださっている方がいるのでそちらを参照してください。

catindog.hatenablog.com

実際の使い方ですが、readme にあるように簡単で、学習用データを用意してそれをインプットするだけです。学習データは事前に単語を半角スペースで分かち書きしておいてください。

./fasttext skipgram -input data.txt -output model

分かち書きMeCab や JUMAN を使えばよいです。追記: 分かち書きのやり方を簡単にまとめました

grahamian.hatenablog.com

  • skipgram は学習アルゴリズムを指定します。cbow で C-BoW に切り替えられます。
  • -input は学習データのパスを与えます。
  • -output は学習したモデルの出力先を指定します。

文書の分類

自然言語処理をするときは一般にこっちが目的だと思います。文書を自然言語処理してラベリングする、というタスクです。
古典的な手法としては BoW を作って SVM で分けたりトピックモデルを使ったり、最近だと文字列を RNN や LSTM にインプットする方法が一般的です。fastTextは skipgram で得た単語のベクトル表現を使ってニューラルネットワークで処理します。ニューラルネットワークは1層です。シンプルですね。速さの源泉はここかな?
学習のさせ方は簡単で事前に用意した訓練データ train.txt をインプットするだけです。

./fasttext supervised -input train.txt -output model

このとき、訓練データの形式は下記のようになっている必要があります。

# __label__番号, 分かち書き した 文字列
__label__0, hoge hoge hoge
__label__1, huge huge huge
__label__2, hege hege hege

ラベル番号を指定するときに __label__◯ と書く必要があるので注意です。ちなみに header はあってもなくても大丈夫そうです。多分 __label__ が無い行は無視されるんだと思います。 学習結果で得られた model.bin に文書を与えることで文書分類が可能になります。

./fasttext predict-prob model.bin test.txt

このとき k を末尾に指定することで文書から複数のラベルを得られます。デフォルトは k=1 です。predict と predict-prob がありますが predict-prob は確率も表示してくれるだけなので内容に差はないはずです。
ちなみに精度を評価したいときは引数に test を使うことで precision と recall を表示してくれます。

./fasttext test model.bin test.txt

学習するときはいくつか引数からパラメータを設定することができます。詳細はreadmeの最後の載っていますが、ここでは使いそうなものだけ抜粋します。

  • -wordngram: N-gram の長さ
  • -dim: ベクトルの次元
  • -lr: 学習率
  • -epoch: epoch数

とりあえず学習するときは epoch を増やしたいと思うので epoch だけ覚えておけばいいんじゃないですかね?学習データサイズにもよりますが epoch=500 くらいなら数分で終わります。

まとめ

fastText は CPU でも軽快に動作する良い自然言語処理ライブラリです。中身のアルゴリズムも skipgram や C-BoW のように今っぽいものを使っているためかなり精度よく文書分類もできます。
今回は書きませんでしたが Python のラッパーも公式に用意されているので使い勝手良いです。 下手に自然言語処理で文書分類するくらいなら fastText を使ったほうが良いのではないでしょうか?あんまり使われている例が無いですが非常に便利なライブラリだと思います。皆さんも是非使ってみては?