RakutenMAによる形態素解析入門

概要

 本稿はRakutenMAというJavaScriptだけで動く学習器付きの形態素解析器を利用する入門記事です。本記事を読了すると、形態素解析の実行と形態素解析のモデルを作成・更新出来るようになります。
 また、本稿ははてな×PC工房との連動企画の補足をするべく書きました。
「あんちべさんと一緒に Rakuten MA で形態素解析」はてなニュース連動企画 第二弾! : パソコン工房

パソコン工房のPCで遊ぼう第2弾! あんちべさんと一緒に Rakuten MA で形態素解析 - はてなニュース

RakutenMAを利用したエディタ判定器デモ
エディタ判定器 :パソコン工房
【やじうまWatch】Emacs派とVim派の対立を煽る「エディタ判定器」が面白いと評判 -INTERNET Watch

はじめに

 近年、twitterFacebookなどのSNSAmazonのレビューなどから得られる様々なテキスト情報を解析して有効活用しようという取り組みが活発になってきています。例えばインフルくん(http://mednlp.jp/influ/)はtwitterから「インフルエンザ」に関するツイートを収集して解析することによりインフルエンザの流行地域を可視化します。テキスト情報を解析する際は、文章そのものではなく、単語ベースでテキストを扱うというアプローチがよく取られます。しかし、日本語は英語と違って単語と単語の間に空白を開けるなどの区切りがないため、一体どこからどこまでが単語なのかを機械で処理することは困難です。そこで、自然言語処理というテキスト情報を解析する分野で用いられる「形態素解析」という技術が役立ちます。形態素解析とは、モデルに基づいて文章を形態素(※厳密には違いますが、ここでは単語のようなものだとお考えください)に切り分け(※これを「分かち書き」と言います)、品詞を付与し、原型に復元するという処理のことです。ここで言う形態素解析におけるモデルとは、「与えられた文字列のどこからどこまでを形態素として切出すか」、更に「その単語に最もふさわしい品詞は何か」を推定して割り当てるための情報だとお考え下さい。この形態素解析を用いることによって様々な分析が可能になります。
 形態素解析を実現するツール形態素解析器といいます。有名な形態素解析器としてMeCab(http://mecab.googlecode.com/svn/trunk/mecab/doc/index.html)やKyTea(http://www.phontron.com/kytea/index-ja.html)などがあります。但し、これらはユーザにインストール作業をして頂く必要があります。例えば社内でテキストを解析するツールを公開する際、沢山の(プログラマではない)一般ユーザに形態素解析器のインストール作業や後述する辞書やモデルの更新作業を行って頂くよう周知するのは中々大変です。そこで、出来ればブラウザでアクセスするだけで形態素解析が出来るとそれらの問題が解決し大変便利です。また、ブラウザだけで形態素解析が実行できるようになれば、PCではなくスマホタブレットでもそのページにアクセスするだけでテキスト解析が可能になります。その要望を実現出来るJavaScript製の(広義の)形態素解析器が幾つかあります。例えばTinySegmenter(http://chasen.org/~taku/software/TinySegmenter/)は良く知られたツールですが、これは分かち書き機能だけを提供するモノなので、「名詞だけを取得したい」、「形容詞と形容動詞の出現数の比を知りたい」などといった品詞情報まで含めた解析が出来ません。JavaScript製の形態素解析器として最近注目を集めているkuromoji.js(https://github.com/takuyaa/kuromoji.js)は形態素解析の全機能を実現しますが、大変残念ながら学習器が付いていません。
 学習器とは、形態素解析器に望ましい形態素解析を行わせるよう学習させるためのツールです。形態素解析器は必ずしも思うように形態素解析をしてくれるわけではありません。例えば大日本帝国陸軍が建造・運用した揚陸艦である我らが「あきつ丸」を含む次のような例文をMeCab形態素解析してみると、「あきつ丸」という一単語(名詞)として切出してくれるのではなく「あ/きつ/丸」と切り分けられてしまっているのがわかります。
f:id:AntiBayesian:20150108074700j:plain

このように形態素解析器の出力結果が望ましくない状態になってしまう事は頻繁に起こります。これを正しく「あきつ丸」で一単語の名詞であると形態素解析器に解釈して貰えるようにするのが学習器の役割です。どれだけ望ましい、言い換えると、人間が見て不自然ではない形態素解析が出来るかはどれだけ正しい学習を行うかに掛かってきます。Webで公開されている形態素解析の標準的なモデルは、新聞のような校正され整った文章に対しては高い精度で形態素解析を行ってくれます(なぜならそれを元にモデルを作ったため)が、ネットでよく見られるようなくだけた文章では誤まった解析をしがちです。また、解析しようとする対象分野特有の単語がある場合も正しく解析出来ないことが多くなります。そのため、実務で形態素解析を行う場合は解析対象分野に合わせた学習をすることが必須となります。
 本稿で紹介するRakutenMAは形態素解析器(※原型復元機能を持たないため、厳密には形態素解析器ではありません)としての機能だけではなく、学習器としての機能も持っています。そしてJavaScript製のツールで学習器までついている形態素解析器は他にありません。また、機能を提供しているというだけではなく、ツールそのものの使いやすさと整備されたドキュメントの存在が使い勝手を良くしています。本稿ではRakutenMAを簡単に説明し、形態素解析と学習を実践するための手順について紹介します。

RakutenMA

RakutenMAの技術的な中身や特徴はこの論文を読むのが一番確かです。
http://anthology.aclweb.org/C/C14/C14-2009.pdf
ざっくり説明すると、形態素解析部分は文字単位の系列ラベリングモデルを用い、学習の部分はSCWを利用しています。
使い方やライセンスなどの情報はこちらに日本語でまとめられています。
https://github.com/rakuten-nlp/rakutenma/blob/master/README-ja.md
また、簡単に形態素解析を試せるデモも用意されています。
http://rakuten-nlp.github.io/rakutenma/

形態素解析の実践

ブラウザで実行しても良いのですが、ここでは色々操作するためにnode.js上で実行します。
まずはnode.jsをインストールして下さい。
http://nodejs.org/

次にRakutenMA本体をインストールして下さい。
https://github.com/rakuten-nlp/rakutenma

インストールが完了したら、nodeのREPLを起動し、以下のコードを実行して下さい。

// RakutenMAの読み込みと諸々の初期設定
var RakutenMA = require('./rakutenma');
var fs = require('fs');
var model = JSON.parse(fs.readFileSync('model_ja.json'));
rma = new RakutenMA(model, 1024, 0.007812);
rma.featset = RakutenMA.default_featset_ja;
rma.hash_func = RakutenMA.create_hash_func(15);

// 形態素解析実行
rma.tokenize("あきつ丸改二で大発動艇もっと欲しい");
rma.tokenize("将校殿…いや、提督殿。このあきつ丸に御用でしょうか");

これを実行すると次のような結果が出力されます。
f:id:AntiBayesian:20150108074742j:plain


結果を見て分かるように、「あきつ丸」や「大発動艇」、「御用」などが意図したような単語として取り出されていません。学習を行うことによって意図通りの解析を実現しましょう。


学習の実践

学習には学習用のデータが必要です。下記のデータをコピペしてakitumaru.jsと名前を付けて保存して下さい。

[
  [
    ["あきつ丸","N-pn"],
    ["改二","N-pn"],
    ["で","P-k"],
    ["大発動艇","N-pn"],
    ["もっと","F"],
    ["欲しい","A-c"]
  ],
  [
    ["自分","N-nc"],
    ["あきつ丸","N-pn"],
    ["で","P-k"],
    ["あり","X"],
    ["ます","X"]
  ],
  [
    ["この","R"],
    ["あきつ丸","N-pn"],
    ["に","P-k"],
    ["御用","N-nc"],
    ["で","X"],
    ["しょう","X"],
    ["か","X"]
  ],
  [
    ["陸軍","N-nc"],
    ["あきつ丸","N-pn"],
    ["ここ","D"],
    ["に","P-k"],
    ["あり","V-c"]
  ]

RakutenMAの学習用のデータは

[
  [学習データ],
  [学習データ],
  [学習データ], 
  ...,
  [学習データ]
]

という構造で、各学習データは["形態素", "品詞"]という形式で与えます。品詞は下記のページの「日本語品詞リストと対応する BCCWJ の品詞名」の節を参照して下さい。
https://github.com/rakuten-nlp/rakutenma/blob/master/README-ja.md

上記の学習データが用意出来たら次のコードをnode.jsで実行して下さい。

var RakutenMA = require('./rakutenma');
var fs = require('fs');
var model = JSON.parse(fs.readFileSync('model_ja.json'));
rma = new RakutenMA(model);
rma.featset = RakutenMA.default_featset_ja;
rma.hash_func = RakutenMA.create_hash_func(15);
var rcorpus = JSON.parse(fs.readFileSync("akitumaru.js")); // 今回学習させるデータ
for (var i in rcorpus) {
    rma.train_one(rcorpus[i]);
}
fs.writeFile('akitumaru-model.json', JSON.stringify(rma.model));

これでakitumaru-model.jsonという学習済みの形態素解析用モデルが出来ました。これを利用することで意図通りの形態素解析を実現します。実際に意図通りの挙動をするか確認してみましょう。

var RakutenMA = require('./rakutenma');
var fs = require('fs');
var model = JSON.parse(fs.readFileSync('akitumaru-model.json'));
rma = new RakutenMA(model, 1024, 0.007812);
rma.featset = RakutenMA.default_featset_ja;
rma.hash_func = RakutenMA.create_hash_func(15);

rma.tokenize("あきつ丸改二で大発動艇もっと欲しい");
rma.tokenize("将校殿…いや、提督殿。このあきつ丸に御用でしょうか");

f:id:AntiBayesian:20150108074803j:plain

ということで、意図通りの形態素解析結果になりました。

終わりに

 ご覧頂いたように、RakutenMAでは形態素解析も学習もとても簡単に実行できます。特に、学習が大変簡単なのが大変素晴らしいと思います。実務で形態素解析を行う場合はモデルを解析対象の分野に適合するよう学習する必要があり、これを分野適応と言います。RakutenMAの学習器はオンライン学習という、既存のモデルを逐次で追加・補正出来る性質になっています。この特性により、日々登場する新語・未知語へ継続的に対応出来ます。今回は学習データが小規模だったので大したことは無かったのですが、実務で利用する学習データは遥かに大規模で、学習に大変時間が掛かります。バッチ学習という学習の度に1から再学習をする方式では非常に学習に掛かるコストが高く、そのために日々のモデル更新がままならないことすらあります。形態素解析の精度は学習によって大幅に変わるため、テキスト解析をする人間にとってはこの学習をいかにうまく行うかが腕の見せ所になっています。ぜひ皆さんもRakutenMAで学習にチャレンジして下さい!

お詫びとかなんか色々なアレ

 本来であればkuromoji.jsとの形態素解析部分の比較や学習データの作り方について解説したかったのですが、今回ちょっと時間が足りませんでした…。多分この記事を読んでも「で、結局どうやって学習データ作るの?」って感じになると思います、すみません…。ざっくり言うと、twitterwikipediaから取ってきたデータをMeCabに掛けて半教師有学習でちょっとずつ精度上げていき、目標水準達成したところでRakutenMA用のモデルに変換しました。今回そうした理由は、RakutenMAの学習の速度がMeCabに比べると流石に遅いのと私がMeCabに慣れていたからです。詳細はまた別の機会にご紹介できればと思います。特にkuromoji.jsはこの企画の記事を書き終わって、さぁ公開するかという直前にその存在を知り、「JavaScript製で品詞付与まで出来るのはRakutenMAしかない(断言)」などという感じの解説を書いていたので、色々大変更することになり泣きながら修正しました。kuromoji.jsはJavaScript製だとは信じられない速度と軽さを実現しており、正直度胆を抜かれました。このデモを見ればその驚きを分かち合えるのではないかと思われます。
kuromoji.js demo
 kuromoji.jsを開発なさった @takuya_a 様には今後是非ともkuromoji.jsの学習器も作って欲しいなと思いました、いや、きっと作って下さると私は信じています。
 私は普段python/MeCabclojure/kuromoji(JavaScript版ではなくJava版)を使っているのですが、今回様々な形態素解析器を試した結果、各々かなり挙動が違うことを体感出来て楽しかったです。特にRakutenMAの学習部分の挙動はMeCabと全然違っていたので新鮮でした。MeCabに慣れている方はちょっと試して見て下さい。
 最後になりましたが、はてなの皆さん、PC工房の皆さん、楽天研究所NYの@mhagiwaraさんには大変お世話になりました。ありがとうございました。



2015/01/10 追記
エディタ判定器で結構遊んで頂けたようで嬉しい限りです!
皆さんも下記URLから試してみて下さい!
エディタ判定器 :パソコン工房