読者です 読者をやめる 読者になる 読者になる

MeCabのipadic辞書への単語追加(ドメイン適応)

NLP

mecab-ipadicのCRF学習モデルが追加されたことにより、辞書に単語を追加しやすくなったようだ。

http://sourceforge.jp/projects/mecab/lists/archive/users/2012-June/000456.html

以前のMeCabの場合、単語追加をする場合は、追加したい単語と似ている単語のコスト値からなんとなく予測して追加する必要があって、結構やりにくかった。なので、どのぐらいやりやすくなったかを早速試してみた。

まず、自分のローカルにMeCabをインストールした。
また、ipadicのモデルファイルしかないようなので、ipadic辞書を入手する。

http://code.google.com/p/mecab/downloads/detail?name=mecab-0.994.tar.gz&can=2&q=
http://code.google.com/p/mecab/downloads/detail?name=mecab-ipadic-2.7.0-20070801.tar.gz&can=2&q=

いろんな用途で辞書に単語を追加したいと思いますが、今回は、固有名詞を追加してみようと思います。
例えば、文字種による未知語推定を行っているMeCabが苦手とする文字種が複合している固有名詞を追加してみます。
よくあるケースとして「~の~」という場合でやってみます。

$ echo "災禍の鎧を装着する。" | mecab
災禍    名詞,一般,*,*,*,*,災禍,サイカ,サイカ
の      助詞,連体化,*,*,*,*,の,ノ,ノ
鎧      名詞,一般,*,*,*,*,鎧,ヨロイ,ヨロイ
を      助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
装着    名詞,サ変接続,*,*,*,*,装着,ソウチャク,ソーチャク
する    動詞,自立,*,*,サ変・スル,基本形,する,スル,スル
。      記号,句点,*,*,*,*,。,。,。
EOS

ここでは、「災禍の鎧」を固有名詞としたいので、ipadicの品詞体系を参照して、適当な品詞を持ってきます。

http://www.unixuser.org/~euske/doc/postag/index.html#chasen

「固有名詞」の「一般」ぐらいが妥当でしょうか。*1

さて、ここからipadicに追加するための作業をしていきます。
いろいろやることが多そうに感じますが、ぶっちゃけ新規辞書作成者がやることは、「学習データの作成」と「追加する語彙ファイルの作成」の2つだけです。
後はMeCabがやってくれます。

学習データ(trainファイル)の作成

「trainファイル」を作成します。
このファイルは、MeCabの出力データと同じように作る必要があるので、先ほどの解析結果をちょっと改造して作ります。

災禍    名詞,一般,*,*,*,*,災禍,サイカ,サイカ
の      助詞,連体化,*,*,*,*,の,ノ,ノ
鎧      名詞,一般,*,*,*,*,鎧,ヨロイ,ヨロイ
を      助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
装着    名詞,サ変接続,*,*,*,*,装着,ソウチャク,ソーチャク
する    動詞,自立,*,*,サ変・スル,基本形,する,スル,スル
。      記号,句点,*,*,*,*,。,。,。
EOS

この解析結果の「災禍の鎧」を部分を変更します。
記述フォーマットの参考にするために、既存のipadic辞書から「名詞,固有名詞,一般」を探します。
以下のようなコマンドで探せます。

$ cd mecab-ipadic-2.7.0-20070801
$ cat Noun.*.csv | grep "名詞,固有名詞,一般" | head

こうやって、作成したtrainファイル(EUC)は以下のようになります。

災禍の鎧        名詞,固有名詞,一般,*,*,*,災禍の鎧,サイカノヨロイ,サイカノヨロイ
を      助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
装着    名詞,サ変接続,*,*,*,*,装着,ソウチャク,ソーチャク
する    動詞,自立,*,*,サ変・スル,基本形,する,スル,スル
。      記号,句点,*,*,*,*,。,。,。
EOS

追加する語彙ファイル(add_word.csv)の作成

既存の辞書と同じフォーマットにします。
ipadic辞書データ内のNoun.csvファイルなどを参考にすれば良いと思います。

以下のようなadd_word.csvファイル(EUC)を作りました。

災禍の鎧,0,0,0,名詞,固有名詞,一般,*,*,*,災禍の鎧,サイカノヨロイ,サイカノヨロイ

ポイントとしては、第二~第四カラムの値をすべて0にすることです。
第二カラムは、左文脈IDで、0にしておくと、MeCabが自動でIDを付与してくれます。
第三カラムは、右文脈IDで、左文脈IDと同様に、0にしておくと、MeCabが自動でIDを付与してくれます。
問題は、第四カラムであり、ここにコスト値(値が小さいほどその単語が出現しやすい)を入力する必要があるのですが、人手で副作用が少ないように値を決定するのはかなり大変です。
ただし、今回の記事の中心であるCRF学習モデルとMeCabを利用することで、このコスト値を推定してくれます。
なので、MeCabに任せるという意味で、0としておきましょう。

追加する語彙ファイル(add_word.csv)を使ってコンパイル

作成したadd_word.csvファイルをipadic辞書のディレクトリにコピーします。

$ cp add_word.csv ./mecab-ipadic-2.7.0-20070801

そして、以下のようにして辞書をコンパイルします。

$ mecab-dict-index -f euc-jp -t euc-jp -d mecab-ipadic-2.7.0-20070801 -o mecab-ipadic-2.7.0-20070801
reading mecab-ipadic-2.7.0-20070801/unk.def ... 40
emitting double-array: 100% |###########################################|
mecab-ipadic-2.7.0-20070801/model.def is not found. skipped.
reading mecab-ipadic-2.7.0-20070801/Noun.demonst.csv ... 120
reading mecab-ipadic-2.7.0-20070801/Symbol.csv ... 208
reading mecab-ipadic-2.7.0-20070801/Adj.csv ... 27210
reading mecab-ipadic-2.7.0-20070801/Adverb.csv ... 3032
reading mecab-ipadic-2.7.0-20070801/Postp.csv ... 146
reading mecab-ipadic-2.7.0-20070801/Noun.org.csv ... 16668
reading mecab-ipadic-2.7.0-20070801/Postp-col.csv ... 91
reading mecab-ipadic-2.7.0-20070801/Prefix.csv ... 221
reading mecab-ipadic-2.7.0-20070801/Noun.others.csv ... 151
reading mecab-ipadic-2.7.0-20070801/add_word.csv ... 1
reading mecab-ipadic-2.7.0-20070801/Filler.csv ... 19
reading mecab-ipadic-2.7.0-20070801/Noun.adverbal.csv ... 795
reading mecab-ipadic-2.7.0-20070801/Suffix.csv ... 1393
reading mecab-ipadic-2.7.0-20070801/Noun.adjv.csv ... 3328
reading mecab-ipadic-2.7.0-20070801/Noun.verbal.csv ... 12146
reading mecab-ipadic-2.7.0-20070801/Noun.name.csv ... 34202
reading mecab-ipadic-2.7.0-20070801/Conjunction.csv ... 171
reading mecab-ipadic-2.7.0-20070801/Noun.proper.csv ... 27327
reading mecab-ipadic-2.7.0-20070801/Others.csv ... 2
reading mecab-ipadic-2.7.0-20070801/Noun.csv ... 60477
reading mecab-ipadic-2.7.0-20070801/Adnominal.csv ... 135
reading mecab-ipadic-2.7.0-20070801/Noun.nai.csv ... 42
reading mecab-ipadic-2.7.0-20070801/Auxil.csv ... 199
reading mecab-ipadic-2.7.0-20070801/Interjection.csv ... 252
reading mecab-ipadic-2.7.0-20070801/Noun.place.csv ... 72999
reading mecab-ipadic-2.7.0-20070801/Verb.csv ... 130750
reading mecab-ipadic-2.7.0-20070801/Noun.number.csv ... 42
emitting double-array: 100% |###########################################|
reading mecab-ipadic-2.7.0-20070801/matrix.def ... 1316x1316
emitting matrix      : 100% |###########################################|

done!

上記の結果に、以下の行があれば成功です。

reading mecab-ipadic-2.7.0-20070801/add_word.csv ... 1

既存のCRF学習モデルを使った新しいCRF学習モデルの作成

配布されているipadicのCRF学習モデルを使って、学習データから新しいCRF学習モデル(new_modelファイル)を構築します。
以下のリンクからipadicのCRF学習モデルをあらかじめ入手しておいてください。

http://code.google.com/p/mecab/downloads/detail?name=mecab-ipadic-2.7.0-20070801.model.bz2&can=2&q=

$ mecab-cost-train -M mecab-ipadic-2.7.0-20070801.model -d mecab-ipadic-2.7.0-20070801 train new_model
Using previous model: mecab-ipadic-2.7.0-20070801.model
--cost --freq and --eta options are overwritten.
reading corpus ...
Number of sentences: 1
Number of features:  1029148
eta:                 0.00005
freq:                1
eval-size:           8
unk-eval-size:       4
threads:             1
charset:             euc-jp
C(sigma^2):          1.00000

iter=0 err=1.00000 F=-nan target=1.07188 diff=1.00000
iter=1 err=0.00000 F=1.00000 target=0.50022 diff=0.53333
iter=2 err=0.00000 F=1.00000 target=0.37289 diff=0.25454
iter=3 err=1.00000 F=-nan target=0.91234 diff=1.44666
iter=4 err=0.00000 F=1.00000 target=0.14861 diff=0.83711
iter=5 err=0.00000 F=1.00000 target=0.22105 diff=0.48744
iter=6 err=0.00000 F=1.00000 target=0.12184 diff=0.44878
iter=7 err=0.00000 F=1.00000 target=0.12146 diff=0.00318
iter=8 err=0.00000 F=1.00000 target=0.12135 diff=0.00087
iter=9 err=0.00000 F=1.00000 target=0.12135 diff=0.00000
iter=10 err=0.00000 F=1.00000 target=0.12135 diff=0.00000
iter=11 err=0.00000 F=1.00000 target=0.12135 diff=0.00000

Done! writing model file ...

上記のような結果が出力され、new_modelファイルが作成されていれば成功です。

新しいCRF学習モデルからの新しいMeCab辞書の作成

先ほど作成した新しいCRF学習モデル(追加したい語彙を反映済み)から新しいMeCab辞書を「new_dicディレクトリ」に作成します。
ただし、「new_dicディレクトリ」は、空のディレクトリとしてあらかじめ作成しておく必要があります。
以下のように実行します。

$ mkdir new_dic
$ mecab-dict-gen -d mecab-ipadic-2.7.0-20070801 -o new_dic -m new_model
new_model is not a binary model. reopen it as text mode...
reading mecab-ipadic-2.7.0-20070801/unk.def ... 40
reading mecab-ipadic-2.7.0-20070801/Noun.demonst.csv ... 120
reading mecab-ipadic-2.7.0-20070801/Symbol.csv ... 208
reading mecab-ipadic-2.7.0-20070801/Adj.csv ... 27210
reading mecab-ipadic-2.7.0-20070801/Adverb.csv ... 3032
reading mecab-ipadic-2.7.0-20070801/Postp.csv ... 146
reading mecab-ipadic-2.7.0-20070801/Noun.org.csv ... 16668
reading mecab-ipadic-2.7.0-20070801/Postp-col.csv ... 91
reading mecab-ipadic-2.7.0-20070801/Prefix.csv ... 221
reading mecab-ipadic-2.7.0-20070801/Noun.others.csv ... 151
reading mecab-ipadic-2.7.0-20070801/add_word.csv ... 1
reading mecab-ipadic-2.7.0-20070801/Filler.csv ... 19
reading mecab-ipadic-2.7.0-20070801/Noun.adverbal.csv ... 795
reading mecab-ipadic-2.7.0-20070801/Suffix.csv ... 1393
reading mecab-ipadic-2.7.0-20070801/Noun.adjv.csv ... 3328
reading mecab-ipadic-2.7.0-20070801/Noun.verbal.csv ... 12146
reading mecab-ipadic-2.7.0-20070801/Noun.name.csv ... 34202
reading mecab-ipadic-2.7.0-20070801/Conjunction.csv ... 171
reading mecab-ipadic-2.7.0-20070801/Noun.proper.csv ... 27327
reading mecab-ipadic-2.7.0-20070801/Others.csv ... 2
reading mecab-ipadic-2.7.0-20070801/Noun.csv ... 60477
reading mecab-ipadic-2.7.0-20070801/Adnominal.csv ... 135
reading mecab-ipadic-2.7.0-20070801/Noun.nai.csv ... 42
reading mecab-ipadic-2.7.0-20070801/Auxil.csv ... 199
reading mecab-ipadic-2.7.0-20070801/Interjection.csv ... 252
reading mecab-ipadic-2.7.0-20070801/Noun.place.csv ... 72999
reading mecab-ipadic-2.7.0-20070801/Verb.csv ... 130750
reading mecab-ipadic-2.7.0-20070801/Noun.number.csv ... 42
emitting new_dic/left-id.def/ new_dic/right-id.def
emitting new_dic/unk.def ... 40
emitting new_dic/Noun.demonst.csv ... 120
emitting new_dic/Symbol.csv ... 208
emitting new_dic/Adj.csv ... 27210
emitting new_dic/Adverb.csv ... 3032
emitting new_dic/Postp.csv ... 146
emitting new_dic/Noun.org.csv ... 16668
emitting new_dic/Postp-col.csv ... 91
emitting new_dic/Prefix.csv ... 221
emitting new_dic/Noun.others.csv ... 151
emitting new_dic/add_word.csv ... 1
emitting new_dic/Filler.csv ... 19
emitting new_dic/Noun.adverbal.csv ... 795
emitting new_dic/Suffix.csv ... 1393
emitting new_dic/Noun.adjv.csv ... 3328
emitting new_dic/Noun.verbal.csv ... 12146
emitting new_dic/Noun.name.csv ... 34202
emitting new_dic/Conjunction.csv ... 171
emitting new_dic/Noun.proper.csv ... 27327
emitting new_dic/Others.csv ... 2
emitting new_dic/Noun.csv ... 60477
emitting new_dic/Adnominal.csv ... 135
emitting new_dic/Noun.nai.csv ... 42
emitting new_dic/Auxil.csv ... 199
emitting new_dic/Interjection.csv ... 252
emitting new_dic/Noun.place.csv ... 72999
emitting new_dic/Verb.csv ... 130750
emitting new_dic/Noun.number.csv ... 42
emitting matrix      : 100% |###########################################|
copying mecab-ipadic-2.7.0-20070801/char.def to new_dic/char.def
copying mecab-ipadic-2.7.0-20070801/rewrite.def to new_dic/rewrite.def
copying mecab-ipadic-2.7.0-20070801/dicrc to new_dic/dicrc
copying mecab-ipadic-2.7.0-20070801/feature.def to new_dic/feature.def
copying new_model to new_dic/model.def

done!

上記のような結果が出力され、「new_dicディレクトリ」が以下のようになっていれば成功です。

$ ls new_dic
Adj.csv
Auxil.csv
Interjection.csv
Noun.csv
Noun.name.csv
Noun.others.csv
Noun.verbal.csv
Postp.csv
Symbol.csv
char.def
left-id.def
rewrite.def
Adnominal.csv
Conjunction.csv
Noun.adjv.csv
Noun.demonst.csv
Noun.number.csv
Noun.place.csv
Others.csv
Prefix.csv
Verb.csv
dicrc
matrix.def
right-id.def
Adverb.csv
Filler.csv
Noun.adverbal.csv
Noun.nai.csv
Noun.org.csv
Noun.proper.csv
Postp-col.csv
Suffix.csv
add_word.csv
feature.def
model.def
unk.def

「add_word.csvファイル」が存在すれば成功です。

さて、「add_word.csvファイル」には、コスト値を付与していませんでした。
しかし、新しいモデルファイルを使って、辞書を作成したので、今度はコスト値が付与されています。
以下のような結果になります。

$ cat add_word.csv
災禍の鎧,1288,1288,7691,名詞,固有名詞,一般,*,*,*,災禍の鎧,サイカノヨロイ,サイカノヨロイ

第四カラムがコスト値なので、7961というコスト値が付与されていることがわかります。

新規辞書の作成

先ほど作成した「new_dicディレクトリ」にある辞書ファイルをコンパイルして、MeCabが読み込める形式の新規辞書を作成します。
ここでは、UTF-8で辞書を構築します。
以下のようなコマンドで実行します。

$ mecab-dict-index -f euc-jp -t utf8 -d new_dic -o new_dic
new_dic/pos-id.def is not found. minimum setting is used
reading new_dic/unk.def ... 40
emitting double-array: 100% |###########################################|
new_dic/pos-id.def is not found. minimum setting is used
reading new_dic/Noun.demonst.csv ... 120
reading new_dic/Symbol.csv ... 208
reading new_dic/Adj.csv ... 27210
reading new_dic/Adverb.csv ... 3032
reading new_dic/Postp.csv ... 146
reading new_dic/Noun.org.csv ... 16668
reading new_dic/Postp-col.csv ... 91
reading new_dic/Prefix.csv ... 221
reading new_dic/Noun.others.csv ... 151
reading new_dic/add_word.csv ... 1
reading new_dic/Filler.csv ... 19
reading new_dic/Noun.adverbal.csv ... 795
reading new_dic/Suffix.csv ... 1393
reading new_dic/Noun.adjv.csv ... 3328
reading new_dic/Noun.verbal.csv ... 12146
reading new_dic/Noun.name.csv ... 34202
reading new_dic/Conjunction.csv ... 171
reading new_dic/Noun.proper.csv ... 27327
reading new_dic/Others.csv ... 2
reading new_dic/Noun.csv ... 60477
reading new_dic/Adnominal.csv ... 135
reading new_dic/Noun.nai.csv ... 42
reading new_dic/Auxil.csv ... 199
reading new_dic/Interjection.csv ... 252
reading new_dic/Noun.place.csv ... 72999
reading new_dic/Verb.csv ... 130750
reading new_dic/Noun.number.csv ... 42
emitting double-array: 100% |###########################################|
reading new_dic/matrix.def ... 1316x1316
emitting matrix      : 100% |###########################################|

done!

上記のような結果になれば成功です。
「add_word.csvファイル」もきちんとコンパイルされていますね。

新規辞書でMeCabを実行

新規辞書の解析を早速試してみましょう。

$ echo "災禍の鎧を装着する。" | mecab -d new_dic
災禍の鎧        名詞,固有名詞,一般,*,*,*,災禍の鎧,サイカノヨロイ,サイカノヨロイ
を      助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
装着    名詞,サ変接続,*,*,*,*,装着,ソウチャク,ソーチャク
する    動詞,自立,*,*,サ変・スル,基本形,する,スル,スル
。      記号,句点,*,*,*,*,。,。,。
EOS

素晴らしい。
ちゃんと固有名詞として判定していくれているようです。

ちなみに、オプションで辞書を指定して起動するのがめんどうな場合は、mecabrcを編集すると常に使う辞書をnew_dicにすることができます。
MeCabのインストールフォルダを「/usr/local」とすると、「/usr/local/etc」の直下に「mecabrcファイル」があります。
以下のパラメータを変更してください。

変更前:
dicdir =  /usr/local/lib/mecab/dic/ipadic

変更後:
dicdir =  <任意のディレクトリパス>/new_dic

まとめ

今までは、追加する単語のコスト値を考えるのがとても大変だったけど、かなり楽になった。
これだけでもかなりうれしい。
分野適応はKyTeaの方がやりやすいかと思っていたけど、このやり方ならMeCabでもそれほど工数をかけずにできるのではないかと思う。
KyTeaは実行速度がかなり遅いので、やはりまだまだMeCabの方がいいかなと思う。
あと、naist-jdicのモデルファイルも公開して欲しいなと強く思います。

*1:ipadicの詳細な品詞体系を知りたい場合は、ipadicのマニュアルを見ると良いです。「http://sourceforge.jp/projects/ipadic/」からipadic-2.7.0をダウンロードできます。ダウンロードした圧縮ファイルを解凍すると、その中にマニュアル(pdf)があります。