Profile   Research   Publications   Tutorials            

LIBLINEARを用いた機械学習入門(単語分割)

このページでは機械学習のツール(LIBLINEAR)を利用して、実際に分類問題を解くにはどういう手順を経るかということについて解説します。つまり、Kytea(京都テキスト解析ツールキット)における簡易版の単語分割モデルを作ってみようということです。 なお今回はプログラミング言語としてRubyを用いますが、Rubyの知識がなくても実装ができるように解説するよう心がけます。また、必要以上に細かく書いてあるかもしれませんが、不要な方は適宜読み飛ばして下さい。
解き方へ

機械学習って?

朱鷺の杜Wiki 「機械学習」がわかりやすいかと思います。 ひとことで言うと、「訓練データを与えてそこから機械に問題の解き方を学んでもらい、別の問題を解いてもらうこと」です。

教師あり学習・教師なし学習

機械学習は大きく「教師あり」と「教師なし」に分かれます。 「教師あり学習」とは、「機械にこう分類してもらいたい」という意図があるとき、その意図に沿ったラベルがついた訓練データを与え学習してもらうことです。 「教師なし学習」とは、「どのように分類するか」という示唆を人間が与えることなく機械に分類をお願いすることです。 今回は「教師あり学習」を用いて、こちらが与えるラベルのように事例を分類してもらうということをします。

機械学習の分類器

一言に機械に分類してもらうといっても、どういう風に分類してもらうかということは様々な研究がなされています。 今回はLIBLINEARという実装を用いて、SVM(Support Vector Machine)による分類を行います。 SVMがどのようなものかということは、森 信介先生のパターン認識特論の講義及びスライドが詳しいので、学内の方はそちらを参照するか授業を受けられるとよいと思います。

分類器を用いた単語分割

今回解くような単語分割においてどのように分類を行うかについては、本家であるところのKyteaの単語分割・品詞推定で非常にわかりやすく書いてあります。 今回はこれを愚直に実装します。

LIBLINEARで実際に単語分割をしてみる

うだうだと能書きがありましたが、それでは実際にLIBLINEARを使って単語分割をしてみましょう。

LIBLINEARを使う準備をする

Rubyをインストールする

スキップ

日本語単語分割のデータを眺めてみる

今回は森先生の研究ページで公開されているMPTコーパスから、MPT.sent(未分割テキスト)、MPT.word(分割済みテキスト)を利用します(文字コードはすべてSJISに統一します)。なお、MPTコーパスは研究用途以外への利用は一切禁止されています。中身を見てみると、

MPT.sent
日本語や中国語のように、明示的な単語境界がない言語においては、自動単語分割は自然言語処理の最初のタスクである。
ほとんどの自然言語処理システムは、単語単位に依存しており、自動単語分割器はこれらの言語に対して非常に重要である。

MPT.word
日本 語 や 中国 語 の よう に 、 明示 的 な 単語 境界 が な い 言語 に お い て は 、 自動 単語 分割 は 自然 言語 処理 の 最初 の タスク で あ る 。
ほとんど の 自然 言語 処理 システム は 、 単語 単位 に 依存 し て お り 、 自動 単語 分割 器 は これ ら の 言語 に 対 し て 非常 に 重要 で あ る 。

のようになっています。
Kyteaの単語分割・品詞推定にも書いてあるように、べた書きのテキストをこのように分割することを学習したい場合は、各文字列の間を判定点として、そこにスペースが入るか入らないかの二値分類問題に落とし込みます。つまり、

MPT.lkytea
日-本|語|や|中-国|語|の|よ-う|に|、|明-示|的|な|単-語|境-界|が|な|い|言-語|に|お |い|て|は|、|自-動|単-語|分-割|は|自-然|言-語|処-理|の|最-初|の|タ-ス-ク|で|あ| る|。
ほ-と-ん-ど|の|自-然|言-語|処-理|シ-ス-テ-ム|は|、|単-語|単-位|に|依-存|し|て|お |り|、|自-動|単-語|分-割|器|は|こ-れ|ら|の|言-語|に|対|し|て|非-常|に|重-要|で| あ|る|。

のように、文字と文字の間には-が入るか、|が入るかを考える問題になるわけです。
データと以下のスクリプトを同じ場所に置き、以下のコマンドで実行すると上記のようなファイルが生成されます。
word2lkytea.rb

cd [ファイルがある場所のフルパス]
ruby word2lkytea.rb < MPT.word > MPT.lkytea

[ファイルがある場所のフルパス]=エクスプローラの上のバーをクリックすれば出る場所名

何を利用して分類するか

それではこのような問題を機械に分類をしてもらうには何をすればよいのでしょうか。今回利用する教師あり学習と呼ばれる手法では、機械に対して「どういう特徴を見ればその分類問題が解けるのか」という示唆を与えてやることになります。例を見てみましょう。

例1
日-本|語|や|中-国|語|の|よ-う|に

この例においては、前後が切れやすい語、つながりやすい語というのがあるのがわかります。例えば「語」は2回出ている両方とも前後が切れています。つまり、前後の語は非常に重要なヒントになる、ということがわかります。さらに次の例を見てみます。

例2
最-初|の|タ-ス-ク|で|あ|る|。

この例では、漢字同士、カタカナ同士はつながっており、文字種が変化する場合は切れているということがわかるでしょう。今回はこの『前後に出てくる文字』『前後に出てくる文字種』の2種類を利用します。ちなみにこうした機械に与えるヒントのことを「素性(そせい:feature)」といいます。

LIBLINIEARにわかる形で教師データを与える

ここで先程出てきたLIBLINEARを利用します。つまり、今述べた文字境界の『前後に出てくる文字』『前後に出てくる文字種』という示唆を、LIBLINEARが解釈できる形にフォーマットします。
LIBLINEARは次のようなデータフォーマットを要求します。

LIBLINEARが要求するデータフォーマット
[クラス番号] [素性番号1]:[その頻度] [素性番号2]:[その頻度]...

これも先程の例で見てみましょう。

MPT.feat(単語分割における学習データ)
1 Lc1=日:1 Rc1=本:1 Lt1=C:1 Rt1=C:1
2 Lc1=本:1 Rc1=語:1 Lt1=C:1 Rt1=C:1
2 Lc1=語:1 Rc1=や:1 Lt1=C:1 Rt1=H:1
2 Lc1=や:1 Rc1=中:1 Lt1=H:1 Rt1=C:1
1 Lc1=中:1 Rc1=国:1 Lt1=C:1 Rt1=C:1
2 Lc1=国:1 Rc1=語:1 Lt1=C:1 Rt1=C:1
2 Lc1=語:1 Rc1=の:1 Lt1=C:1 Rt1=H:1
2 Lc1=の:1 Rc1=よ:1 Lt1=H:1 Rt1=H:1
1 Lc1=よ:1 Rc1=う:1 Lt1=H:1 Rt1=H:1
2 Lc1=う:1 Rc1=に:1 Lt1=H:1 Rt1=H:1
2 Lc1=に:1 Rc1=、:1 Lt1=H:1 Rt1=S:1

このデータは
lkytea2feature.rb

ruby lkytea2feature.rb < MPT.lkytea > MPT.feat

のようにして出力できます。
それぞれの素性が分割境界1つについてどのように登場したか、その場合分割境界はクラス1(分割しない)か、クラス2(分割する)か、ということを記述します。ただ、このままでLIBLINEARを利用することはできません。素性番号にあたる場所をIDに変換する必要があります。そこで、次のようにデータを変換します。

MPT.liblin(実際にLIBLINEARに食わせるデータ)
1 1:1 2:1 3:1 4:1
2 3:1 4:1 5:1 6:1
2 3:1 7:1 8:1 9:1
2 4:1 10:1 11:1 12:1
1 3:1 4:1 13:1 14:1
2 3:1 4:1 6:1 15:1
2 3:1 7:1 9:1 16:1
2 9:1 12:1 17:1 18:1
1 9:1 12:1 19:1 20:1
2 9:1 12:1 21:1 22:1
2 12:1 23:1 24:1 25:1
2 4:1 26:1 27:1 28:1
1 3:1 4:1 29:1 30:1
2 3:1 4:1 31:1 32:1
2 3:1 9:1 33:1 34:1
2 4:1 12:1 35:1 36:1
1 3:1 4:1 6:1 37:1
...

lkytea2liblin.rb

ruby lkytea2liblin.rb < MPT.lkytea > MPT.liblin

これで、LIBLINEARを利用する準備が整いました。 LIBLINEARで学習を行うためのデータを作る注意点としては、

といった制約があります。

LIBLINEARで学習をする

ここまでくればもう一息です。 それでは用意したデータを使って、LIBLINEARのモデルを作ってみます。学習データのあるディレクトリで

train [学習データ]

とすると学習が行われ、[学習データ].modelという拡張子のファイルが生成されます。これがLIBLINEARが学習したモデルファイルです。今回は

train MPT.liblin

なので生成されるモデルファイルはMPT.liblin.modelとなります。

LIBLINEARで分類をする(クローズド)

さて、作成したモデルを用いて、分類を行ってみましょう。上と同じディレクトリで、

predict [テストデータ] [モデルファイル] [出力結果]

とすると分類が行われます。ここまででテストデータという単語は初めて出てきました。これは実際作ったモデルがどれくらいうまく問題を分類できるかチェックするためのもので、通常は学習データを20%程度学習に使わず分類を行ってみます(オープンテストと言います。テストデータのフォーマットは先に紹介した学習データのフォーマットと同じです。)
今回はテストセットを用意していないので、学習に使ったのと同じデータを分類してみましょう(クローズドテストといいます)。

predict MPT.liblin MPT.liblin.model MPT.closed
> Accuracy = 97.7778% (12232/12510)

学習データと同じデータを分類しているはずなのに100%分類できませんね。これは、さきほど選んだ素性が単語境界の完全な特徴を表しているわけではなく、100%を分類することが難しいからです。今回は簡単な素性だけを用いたので、こんなものだと思います。


KAWAHARA Lab. Top Page
KAWAHARA Lab. Members Page


yoshino [at] ar.media.kyoto-u.ac.jp
Kyoto University, Media Archiving Research Laboratory, Koichiro Yoshino.