2017年10月更新
同じ話題について書きました:「MeCabの中国語分割辞書を作る話」
形態素解析(分かち書き)とは
形態素解析というのは「我是英國人」という文章を入れたときに「我/是/英國/人」という形態素(意味を持つ最小の単位)に分割するものです。ここでは必ずしも形態素に分割することを求めていないので「分かち書き」という言葉を使います。
このエントリを作ろうと思ったのは情報がほとんどなくて自分が非常に苦労したからです。このエントリがあることで多くの人にとって役に立つことを願います。
中国語の形態素解析器はほとんどない
「関口宏司のLuceneブログ」によると
「中国語には(商用のものを除き)形態素解析器が(あまり)ない」という話を聞いたことがあります
とのことです。他にも「(2004年度修士論文)JPドメインにおける茶筌を用いた中国語ページの抽出(PDF注意)」を見ると
3.2.1 中国国内の研究
「形態素解析」は中国語では「詞素解析」と言い、中国国内での研究は少ない。茶筌のように誰でもフリーにダウンロードできるツールは、まず公開されていない。検索エンジンに搭載される事が少なく、機械語翻訳もかなり精度が低い。メジャーな検索エンジンでサーチしても、ヒット数が少ない上に、「海外・日本では形態素解析はどのような研究をされているか」・「日本国立情報学研究所NIIではどのような結果を出しているか」といった情報ばかりである。それほど注目度が低いのだ。
そうだ。ところでこの修士論文、あちこち未完成のままだけど彼はちゃんと卒業できたのだろうか。
また「(2007年度修士論文)シーケンシャルパターンマイニングを利用した中国語感情表現抽出手法(PDF注意)」によると、中国語の形態素解析システムは次のようなものがあるそうです。
「形態素解析」は中国語では「詞素解析」と言い,中国国内での研究では,個人が開発した中国語形態素解析ツール捜捜捜中文分詞や,海量信息技術有限会社が開発した中国語形態素解析ツール中文智能分詞や,中科院の張華平氏が開発した中国語形態素解析ツールICTCLAS(Institute of Computing Technology, Chinese Lexical Analysis System)などがある.その中で,もっとも中国国内に認められている形態素解析ツールはICTCLASである.ICTCLASは中国国内メディアや,海外メディアなどに広く報道され,2007年9月までに,中国,日本,シンガポール,韓国,アメリカと他国・地域からの30000人を超える研究員に利用されている.また,ICTCLASはダイナミックリンクライブラリICTCLAS.dll,COMコンポーネントと対応する中国語辞書を提供されている,
だそうです。この修士論文の著者は(おそらく)中国人なので中国における研究を調べるには有利です。
日本国内でも中国語の形態素解析にはICTCLASを使うのが普通のようです。「NAIST Chinese Dictionary」には次のような記述があります。
我々が開発していない他の中国語形態素解析システムとして ICTCLASがあります。研究用途にはそちらのご利用をお勧めします。
また「ChaSen — 形態素解析器」には「中国語語辞書(奈良先端大より公開予定)」とありますが、未だに公開されていないようです。この記事は2007年なので、3年経っても動きがありません。
ICTCLAS
いくつかバージョンがありますが、どうも動作が芳しくありません。

日本語Windowsで使うと化け化けです。他にLinux版もあるのですが、これも色々問題がありました。
他の形態素解析システム
「きまぐれ日記」に興味深い記事があります。『Mac OS X Leopard に「標準で」インストールされている MeCabを使ってみる』
Mac OS X Leopard の Spotlight に MeCab が使われているらしいという情報を聞いたので、実際に深追いしてみました。
いとも簡単に /usr/lib/libmecab* , /usr/include/mecab.h と /usr/lib/mecab/dic/apple/{ja,tc,sc} というディレクトリを発見しました。ts, sc は traditional/simplified Chinese (繁体字/簡体字) の略で、中国語の辞書だと推察されます
元記事では日本語の分かち書きについて書いてありますが、ここでは”/usr/lib/mecab/dic/apple/ja/LE”を”/usr/lib/mecab/dic/apple/tc/LE”にして実行します。
[neet@MBA ~/Documents/SugarSync/Source]# ./a.out 我是英國人 我 w 是 s 英國人 y
うひょー。分かち書きできます。元のソースだと品詞情報を出さないけど、すこしいじったらwやらsを出しました。これは何だろうと思ったらどうもピンインでの最初の1文字のようです。これだけしか情報がないのでは使い物になりません。
結局、中国語の処理を今後もやっていこうと思ったら自分で辞書を作るしかないという結論に達しました。
MeCab辞書作り
MeCabの辞書を作るには大雑把に
- 人間が手で分かち書きをした「お手本」データ
- 単語辞書
が必要です。
お手本データ
MeCabの出力と同じ形式でお手本データを作ります。
我 0,0,0,代名詞,ワレ,wǒ 姓 0,0,0,動詞,名前を名乗る,xìng 王 0,0,0,名詞,中国人名,Wáng , 0,0,0,句読点類,, 您 0,0,0,代名詞,あなた様,nín 貴姓 0,0,0,動詞,お名前をお尋ねします,gui xing ? 0,0,0,句読点類,, EOS
CCライセンスのWikipediaとか著作権問題が起きにくいコーパスをかっぱらってきて、地道にやります。あまり頭を使う要素はありません。ひたすら作業です。ファイル名は”corpus”としておきます。
単語辞書
教科書から片っ端から単語を拾っていきます。ひたすら作業。あまり頭を使う必要はありません。
白色,0,0,0,形容詞,白い,bái sè 白菜,0,0,0,名詞,白菜,báicài 百貨公司,0,0,0,名詞,デパート,bǎihuò gōngsī 白天,0,0,0,名詞,昼間,báitiān 白天,0,0,0,副詞,昼間,báitiān
ファイル名は拡張子.csvです。品詞ごとにわけても、1つのファイルでも構いません。
dicrc
cost-factor = 800 bos-feature = BOS/EOS,*,*,*,*,*,*,*,* eval-size = 6 unk-eval-size = 4 config-charset = UTF-8
適当にでっち上げました。エンコーディングをUTF-8にしてあるくらいです。
feature.def
UNIGRAM W0:%F[6] UNIGRAM W1:%F[0]/%F[6] UNIGRAM W2:%F[0],%F?[1]/%F[6] UNIGRAM W3:%F[0],%F[1],%F?[2]/%F[6] UNIGRAM W4:%F[0],%F[1],%F[2],%F?[3]/%F[6] UNIGRAM T0:%t UNIGRAM T1:%F[0]/%t UNIGRAM T2:%F[0],%F?[1]/%t UNIGRAM T3:%F[0],%F[1],%F?[2]/%t UNIGRAM T4:%F[0],%F[1],%F[2],%F?[3]/%t BIGRAM B00:%L[0]/%R[0] BIGRAM B01:%L[0],%L?[1]/%R[0] BIGRAM B02:%L[0]/%R[0],%R?[1] BIGRAM B03:%L[0]/%R[0],%R[1],%R?[2] BIGRAM B04:%L[0],%L?[1]/%R[0],%R[1],%R?[2] BIGRAM B05:%L[0]/%R[0],%R[1],%R[2],%R?[3] BIGRAM B06:%L[0],%L?[1]/%R[0],%R[1],%R[2],%R?[3]
日本語の辞書サンプルにあるのをそのまま利用しました。
rewrite.def
[unigram rewrite] # 読み,発音をとりのぞいて, 品詞1,2,3,4,活用形,活用型,原形,よみ を使う *,*,* $1,$2,$3 [left rewrite] *,*,* $1,$2,$3 [right rewrite] *,*,* $1,$2,$3
なんか書き換えるらしい。よくわからないので、辞書のパラメータ数にあわせて適当に。上手くやれば繁体字と簡体字を両方扱えるのかな。日本語で「ニートではない」と「ニートでは無い」を区別しないために使うらしいです。
char.def
DEFAULT 0 1 0 # DEFAULT is a mandatory category! SPACE 0 1 0 CJK 0 0 2 # SPACE 0x0020 SPACE # DO NOT REMOVE THIS LINE, 0x0020 is reserved for SPACE 0x00D0 SPACE 0x0009 SPACE 0x000B SPACE 0x000A SPACE #CJK 0x4E00..0x9FCB CJK
SPACEは削るなとあるので残して、あとDEFAULT。CJKに相当するUnicodeの値を指定しておわり。
unk.def
DEFAULT,0,0,0,記号,*,* SPACE,0,0,0,記号,*,* CJK,0,0,0,名詞,*,*
char.defで指定した3つの文字種について未知語のときの処理を指定。とりあえず名詞にしとこうということに。
mecab-dict-index
これらのファイルを1つのフォルダにおいて、mecab-dict-indexすると
iconv_open is not supported iconv_open is not supported ./pos-id.def is not found. minimum setting is used reading ./unk.def ... 3 emitting double-array: 33% |############## | emitting double-array: 66% |############################ | emitting double-array: 100% |###########################################| iconv_open is not supported iconv_open is not supported ./pos-id.def is not found. minimum setting is used reading ./ver7.csv ... empty word is found, discard this line empty word is found, discard this line 2356 emitting double-array: 0% | | emitting double-array: 1% | | emitting double-array: 2% | | emitting double-array: 3% |# | emitting double-array: 4% |# | emitting double-array: 5% |## | emitting double-array: 6% |## | (略) emitting double-array: 98% |########################################## | emitting double-array: 99% |########################################## | emitting double-array: 100% |###########################################| ./matrix.def is not found. minimum setting is used. reading ./matrix.def ... 1x1 done!
を生成するはずでしたが、なんか止まります。エラーが出るわけでもなく、ずっと処理が終わらない。CPUも別に使っていない様子。
仕方ないのでソースコードを落としてきて必要なコードだけ抜き出して野良ビルドを作り実行したところうまくいきました。これで学習用辞書ができます。
mecab-cost-train
続いてCRFによるパラメータ学習をします。
mecab-cost-train corpus model
すると
(略) adding virtual node: 0,0,0,動詞 adding virtual node: 0,0,0,動詞 adding virtual node: 0,0,0,代名詞 adding virtual node: 0,0,0,句読点類 Number of sentences: 771 Number of features: 26808 eta: 0.00100 freq: 1 threads: 1 C(sigma^2): 1.00000 iter=0 err=0.34890 F=0.88190 target=6675.95740 diff=1.00000 iter=1 err=0.00000 F=1.00000 target=158.18419 diff=0.97631 iter=2 err=0.00000 F=1.00000 target=134.59601 diff=0.14912 iter=3 err=0.00000 F=1.00000 target=57.31932 diff=0.57414 iter=4 err=0.00000 F=1.00000 target=32.57943 diff=0.43162 iter=5 err=0.00000 F=1.00000 target=17.06155 diff=0.47631 iter=6 err=0.00000 F=1.00000 target=9.82326 diff=0.42425 iter=7 err=0.00000 F=1.00000 target=6.19450 diff=0.36940 iter=8 err=0.00000 F=1.00000 target=4.55300 diff=0.26499 iter=9 err=0.00000 F=1.00000 target=3.88528 diff=0.14665 iter=10 err=0.00000 F=1.00000 target=3.67282 diff=0.05468 iter=11 err=0.00000 F=1.00000 target=3.62842 diff=0.01209 iter=12 err=0.00000 F=1.00000 target=3.62211 diff=0.00174 iter=13 err=0.00000 F=1.00000 target=3.61941 diff=0.00074 iter=14 err=0.00000 F=1.00000 target=3.61607 diff=0.00092 iter=15 err=0.00000 F=1.00000 target=3.61518 diff=0.00025 Done! writing model file ...
となります。これには時間がかかるようですが、手で作った辞書なので案外早く終わりました。
mecab-dict-gen
最終辞書を作ります。まずmkdir dicとしてdicフォルダを作ります。続いて
mecab-dict-gen -o dic --model=model
すると
reading ./unk.def ... 3 reading ./ver7.csv ... 2358 emitting dic/left-id.def/ dic/right-id.def emitting dic/unk.def ... 3 emitting dic/ver7.csv ... 2358 emitting matrix : 100% |###########################################| copying ./char.def to dic/char.def copying ./rewrite.def to dic/rewrite.def copying ./dicrc to dic/dicrc copying ./feature.def to dic/feature.def done!
これで辞書フォルダに辞書が入ります。
mecab-dict-index -f utf8 -t utf8
最後にコンパイルします。
cd dic /usr/local/libexec/mecab/mecab-dict-index -f utf8 -t utf8
すると
./pos-id.def is not found. minimum setting is used reading ./unk.def ... 3 emitting double-array: 100% |###########################################| ./pos-id.def is not found. minimum setting is used reading ./ver7.csv ... empty word is found, discard this line empty word is found, discard this line 2356 emitting double-array: 100% |###########################################| reading ./matrix.def ... 2283x2283 emitting matrix : 100% |###########################################| done!
となり辞書のコンパイルが終わります。
テスト
cd ..して親フォルダに移動します。
[neet@MBA ~/Documents/SugarSync/Source/C++/mecab-dict-index/mecab_dict_index2/build/Debug]# mecab -d dic 我是英國人 我 代名詞,ワレ,wǒ 是 動詞,なり,shì 英國人 名詞,イギリス人,ying guo ren EOS
できているようです。
最近のコメント