学生エンジニアのMoriです。
今回は 形態素解析ツールの一つMecabのIPADICにユーザー辞書を追加する方法について書きたいと思います。

目次

Mecabの形態素解析の仕組みの簡単な説明

Mecabは辞書ファイルに設定されたコストから、累積コストが最も低くなる形態素の組み合わせを探し、その組み合わせを形態素の解析結果として出力しています.

例として、東京京都のコストをそれぞれ見てみましょう

$ echo "東京" | mecab -F"%m,%c\n"
東京,3003
EOS
$ echo "京都" | mecab -F"%m,%c\n"
京都,2135
EOS
$ echo "東" | mecab -F"%m,%c\n"
東,6245
EOS
# 接尾辞の「都」はコストが高いため
$ echo "都" | mecab -F"%m,%c\n" -N6 | tail -n2
都,9428
EOS

カンマで区切られた左から2番目の値がコストになります.
コストを単純に足し合わせると、

  • 「東京」+「都」の合計コストが12431
  • 「東」+「京都」の合計コストが8380

になり、「東京都」を形態素解析した結果は「東」+「京都」になりそうですね.
では実際に東京都という文を形態素解析してみましょう.

$ echo "東京都" | mecab -F"%m,%c,%pc\n" -N2
東京,3003,2693
都,9428,2504
EOS
東,6245,5962
京都,2135,7729
EOS

(N2オプションをつけることにより累計コストが低い順で2つ表示、 フォーマットは左から順に表層形・その単語単体のコスト・前の単語と合わせた累計コストとなっています)
形態素解析の結果は予想と反して、「東」と「京都」ではなく、「東京」と「都」になりました.

なぜこのような結果になったのでしょうか?それは、「連接コスト」という概念が関係しています.
私たちが普段文章を読むとき、文脈を考慮して、文章の意味を理解し、適切な文の区切りを見つけています.(例えば、「苗字の後には名前が来やすい」というルールがありますね)
Mecabでも同じようなことをするために「コストの合計」でなく「コストと連接コストの合計」を比較することで適切な区切りを推測しています. 実際にMecab内で「連接コスト」を導出する方法は

  • 前の単語の右文脈IDと当該単語の左文脈IDを取得
  • 二つのIDからMatrix.def内を検索し、連接コストを取得

の流れとなっています.

$ echo "東京" | mecab -F"%m,%phl,%phr\n"
東京,1293,1293
EOS
$ echo "京都" | mecab -F"%m,%phl,%phr\n"
京都,1293,1293
EOS
$ echo "東" | mecab -F"%m,%phl,%phr\n"
東,1285,1285
EOS
$ echo "都" | mecab -F"%m,%phl,%phr\n" -N6 | tail -n2
都,1303,1303
EOS

上のコマンドはそれぞれの単語の左文脈IDと右文脈IDを出力しています.
これらの文脈IDをmatrix.def内で検索して見ると

...
#東京の右文脈ID 都の左文脈ID 連接コスト
1293 1303 -9617
...
#東の右文脈ID 京都の左文脈ID 連接コスト
1285 1293 -368
...

のような行が見つかりました.この検索結果によって、「東京」+「都」と連接すると累積コストが大きく下がっていることがわかります.これにより「東」+「京都」ではなく、「東京」+「都」という解析結果になっていたのです.

CSVの作成

適当なディレクトリ(今回は/home/foo/bar)に移動してから、以下のようなフォーマットのCSVを作成し、UTF-8で保存します

表層形,左文脈ID,右文脈ID,コスト,品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用型,活用形,原形,読み,発音

例えば、

メロンパン,1285,1285,4000,名詞,一般,*,*,*,*,メロンパン,メロンパン,メロンパン

です。
ここで左文脈ID・右文脈IDは、同じ品詞分類の似たような意味の単語 (例:「イチゴ」なら「メロン」など)の左文脈ID・右文脈IDをそのまま持ってくれば良いです.
また、コストに関しては、

$ echo 登録したい語 | mecab -F"%c,%pC,%pn\n"

とすることで、

  • %c : その単語の生起コスト
  • %pC : 1つ前の形態素との連接コスト
  • %pn : 連接コスト + 単語生起コスト

を適宜確認しながら、調整していくといいです.

辞書ファイルの作成

先ほどCSVを作成したディレクトリ(今回は/home/foo/bar/)に移動してから、以下のコマンドを実行することにより、CSVファイルfoo.csvから、辞書ファイルfoo.dicを作成します.

Linuxの場合

$ cd /home/foo/bar
$ /usr/local/libexec/mecab/mecab-dict-index \
-d/usr/local/lib/mecab/dic/ipadic \
-u foo.dic \
-f utf-8 \
-t utf-8 foo.csv

Mac(Homebrewで入れた)の場合

$ cd /home/foo/bar
$ /usr/local/Cellar/mecab/0.996/libexec/mecab/mecab-dict-index \
-d /usr/local/lib/mecab/dic/ipadic \
-u foo.dic \
-f utf-8 \
-t utf-8 foo.csv

オプションの意味は以下の通りです.

  • d : システム辞書のディレクトリ
  • u : 作成するユーザー辞書ファイルの名前
  • f : CSVの文字コード
  • t : 辞書ファイルの文字コード

使用するユーザー辞書を設定

/home/foo/bar/foo.dicが作成できていることを確認してから、/usr/local/etc/mecabrcに以下の文言を追加

userdic = /home/foo/bar/foo.dic 

なお、以下のように複数指定することも可能

userdic = /home/foo/bar/human.dic,/home/foo/bar/manga.dic

実際に使って見る

ユーザー辞書を指定しない場合

$ echo "メロンパン" | mecab
メロン 名詞,一般,*,*,*,*,メロン,メロン,メロン
パン  名詞,一般,*,*,*,*,パン,パン,パン
EOS

ユーザー辞書を指定した場合

$ echo "メロンパン" | mecab
メロンパン   名詞,一般,*,*,*,*,メロンパン,メロンパン,メロンパン
EOS

最後に

手作業でコストを付与するのは難しそうということが、一層わかりました(^_^;)
自動推定についても、勉強していきたいです。 後、ビタビのアルゴリズムがMecabの解析時に使われているのがちょっと感動しました

参考文献・Webページ