毎日テキストマイニング

180日間、毎日テキストマイニングをするブログ

2018/7/10【18日目前半】MeCabに単語を登録する

ずっと気になっていたことに、MeCabが単語を区切りすぎているのではないか? ということがありました。例えば、「AKB48」とという言葉をMeCabに渡すと、下記のようにAKBと48という単語に区切られてします。

$ echo "AKB48” | mecab

AKB 名詞,一般,*,*,*,*,*
48  名詞,数,*,*,*,*,*
EOS

AKB48AKB48と認識して欲しいので、今日はMeCabに特定の単語を登録していきたいと思います。

Mecabに単語を登録をする

MeCabへ単語を登録する方法は2種類あるそうです。 - システム辞書への追加 - ユーザ辞書への追加

システム辞書の場合

辞書更新が頻繁でないときや, 解析速度を落としたくない時は, 直接 システム辞書を変更するのがよいでしょう.

ユーザー辞書の場合

システム辞書の更新は時間がかかります. 辞書の更新が頻繁な場合や, システム辞書を変更する権限が無い場合は, ユーザ辞書を作るのがいいでしょう.

今回はどのような影響が出るのかよくわかっていないので、手軽にできそうなユーザー辞書の方法にしてみます。

ユーザー辞書を登録する

ユーザー辞書に単語を登録するには任意のフォルダの中にcsvファイルを作って、そのファイルに単語を書いていって、コンパイルすればよさそうです。

ここでは、フォルダーをakb_dic、辞書csvをakb_dic.csvとします。 単語登録の記述は決まっており、次のようにする必要があるそうです。

工藤,1223,1223,6058,名詞,固有名詞,人名,名,*,*,くどう,クドウ,クドウ

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

この文脈IDとはいったいなんなんだ? という感じですが、公式ページに書いてありますね。

左文脈IDは, その単語を左から見たときの内部状態IDです. 通常システム 辞書と同一場所にある left-id.def から該当する ID を選択します. 空にしておくと mecab-dict-index が自動的に ID を付与します.

右文脈IDも同様ですね。とりあえず今回は空白でよさそうです。

右文脈IDは, その単語を右から見たときの内部状態IDです. 通常システム 辞書と同一場所にある right-id.def から該当する ID を選択します. 空にしておくと, mecab-dict-index が自動的に ID を付与します.

コストはこんな感じです。AKB48は一番小さい1がいいですね。

コストは,その単語がどれだけ出現しやすいかを示しています. 小さいほど, 出現しやすいという意味になります. 似たような単語と 同じスコアを割り振り, その単位で切り出せない場合は, 徐々に小さくしていけばいいと思います.

この形式にそって単語を登録していきたいと思います。

AKB48,,,1,名詞,固有名詞,一般,グループ名,*,*,えーけーびーふぉーてぃーえいと,エーケービーフォーティーエイト,エーケービーフォーティーエイト

akb_dic.csvに書いて保存します。 作業ディレクトリをakb_dicに移動します。

cd akb_dic

その後、下記のコマンドでコンパイルします。

$ /usr/local/libexec/mecab/mecab-dict-index -d/usr/local/lib/mecab/dic/ipadic \
-u akb_dic -f euc-jp -t euc-jp akb_dic.csv

と、思ったらできない。 このpath、Linuxのpathなんですね。macOSだとどこかなーって探してたのですが、下記にありました。

/usr/local/Cellar/mecab/0.996/libexec/mecab

こっちのpathで改めてコンパイル

$ /usr/local/Cellar/mecab/0.996/libexec/mecab/mecab-dict-index -d/usr/local/lib/mecab/dic/ipadic \
-u akb.dic -f euc-jp -t euc-jp akb_dic.csv

そしたら下記のエラーが出ました。

reading akb_dic.csv ... context_id.cpp(96) [it != left_.end()] cannot find LEFT-ID  for 名詞,固有名詞,グループ名,*,*,*,*

調べてみましたが、名詞の後は好き勝手に書いちゃダメで、IPA品詞体系の指定する形にしないいといけないんですね。

http://www.unixuser.org/~euske/doc/postag/

ChaSen 品詞体系 (IPA品詞体系)にそって、固有名詞の右側は「組織」に修正します。

AKB48,,,1,名詞,固有名詞,組織,*,*,えーけーびーふぉーてぃーえいと,エーケービーフォーティーエイト,エーケービーフォーティーエイト

改めてコンパイル

/usr/local/Cellar/mecab/0.996/libexec/mecab/mecab-dict-index -d/usr/local/lib/mecab/dic/ipadic \
-u akb.dic -f euc-jp -t euc-jp akb_dic.csv

これでもコンパイルエラーがおきますね。もうしばらく調べてみると、MeCabのバージョンが0.996では左文脈ID,右文脈IDを空白にしてはいけないとのこと(なんてことだ)。左文脈ID,右文脈IDを*にして再び実行してみます。

実行結果。

> -u akb.dic -f euc-jp -t euc-jp akb_dic.csv
reading akb_dic.csv ... 1
emitting double-array: 100% |###########################################| 

done!

コンパイルできました。これでakb.dicというファイルができました。このファイルを読み込めるように、MeCabにpathを記載します。vimでmecabrcを開きます。

vim /usr/local/etc/mecabrc

開いたら下記のようなpathを追加します。

userdic = /Users/user_name/akb_dic/akb.dic

vimを保存したら、MeCabを試してみます。

$ echo "AKB48" | mecab

実行結果。

viterbi.cpp(50) [tokenizer_->open(param)] tokenizer.cpp(130) [sysdic->isCompatible(*d)] incompatible dictionary:

というエラーが起きます。 うすうす気付いていましたが、どうやらコンパイル時に指定した文字コードが違うらしいですね。utf8を指定してコンパイルし直します。

/usr/local/Cellar/mecab/0.996/libexec/mecab/mecab-dict-index -d/usr/local/lib/mecab/dic/ipadic \
-u akb.dic -f utf8 -t utf8 akb_dic.csv

もう一度MeCabを実行します。

$ echo "AKB48" | mecab
AKB48   名詞,固有名詞,組織,*,*,えーけーびーふぉーてぃーえいと,エーケービーフォーティーエイト,エーケービーフォーティーエイト
EOS

できました!

長くなったので、後半に続きます。