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

いくつかバージョンがありますが、どうも動作が芳しくありません。

ICTCLAS.png

日本語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

できているようです。