MeCab 用の辞書を学習するときに、.def 中の左右の概念がファイルごとにこんがらがるので実行しながらまとめ。
こんがらがる原因はここら辺を参照。
左文脈素性(その形態素を左側から見た時の素性), 右文脈素性(その形態素を左側から見た時の素性)の3つが使われます.
準備
リソースは、UniDic(unidic-cwj-3.1.1-full.zip)のものを再利用する。
コーパスとトークンリスト
まず、UniDic の lex.csv から適当に2文程度のミニコーパスを作る。
1列目の表層形と以降のCSVフィールドの間にあるのはタブ1個。
Chakiでいうところの.mecab形式。
UniDicのフィールドには1カラムに"動詞%F1,形容詞%F2@-1"みたいなカンマが入る列もあるのでガチのCSV。ちゃんとエスケープするためにダブルクォーテーションでくくってあるので、不用意にナイーブなカンマsplitはしてはいけない。
EOSの直後はすぐ改行。EOS行にはタブは入れちゃダメ。EOS\nしかダメ。
くるま 名詞,普通名詞,一般,*,*,*,クルマ,車,くるま,クルマ,くるま,クルマ,和,ク濁,基本形,*,*,*,*,体,クルマ,クルマ,クルマ,クルマ,0,C2,*,2895297718133248,10533
で 助詞,接続助詞,*,*,*,*,テ,て,で,デ,で,デ,和,*,*,*,*,*,*,接助,デ,デ,デ,デ,*,"動詞%F1,形容詞%F2@-1",*,6837330270888448,24874
待つ 動詞,一般,*,*,五段-タ行,終止形-一般,マツ,待つ,待つ,マツ,待つ,マツ,和,*,*,*,*,*,*,用,マツ,マツ,マツ,マツ,1,C1,*,9848884062986923,35830
EOS
車 名詞,普通名詞,一般,*,*,*,クルマ,車,車,クルマ,車,クルマ,和,ク濁,基本形,*,*,*,*,体,クルマ,クルマ,クルマ,クルマ,0,C2,*,2895297651024384,10533
で 助詞,接続助詞,*,*,*,*,テ,て,で,デ,で,デ,和,*,*,*,*,*,*,接助,デ,デ,デ,デ,*,"動詞%F1,形容詞%F2@-1",*,6837330270888448,24874
待つ 動詞,一般,*,*,五段-タ行,終止形-一般,マツ,待つ,待つ,マツ,待つ,マツ,和,*,*,*,*,*,*,用,マツ,マツ,マツ,マツ,1,C1,*,9848884062986923,35830
EOS
つぎに、上のmini_corpus.mecab に入ってるエントリだけの mini_lex.csv を作る。
コピペで学習済みの.csvから持ってくると、right-id, left-id, 生起costの値(2~4列目)がすでに埋まっているので0,0,0,に全置換しておく。
くるま,0,0,0,名詞,普通名詞,一般,*,*,*,クルマ,車,くるま,クルマ,くるま,クルマ,和,ク濁,基本形,*,*,*,*,体,クルマ,クルマ,クルマ,クルマ,0,C2,*,2895297718133248,10533
車,0,0,0,名詞,普通名詞,一般,*,*,*,クルマ,車,車,クルマ,車,クルマ,和,ク濁,基本形,*,*,*,*,体,クルマ,クルマ,クルマ,クルマ,0,C2,*,2895297651024384,10533
くる,0,0,0,動詞,非自立可能,*,*,カ行変格,終止形-一般,クル,来る,くる,クル,くる,クル,和,*,*,*,*,*,*,用,クル,クル,クル,クル,1,C1,*,2891174448865963,10518
まで,0,0,0,助詞,副助詞,*,*,*,*,マデ,まで,まで,マデ,まで,マデ,和,*,*,*,*,*,*,副助,マデ,マデ,マデ,マデ,*,"名詞%F2@1,形容詞%F2@1,動詞%F2@1",*,9865651581755904,35891
で,0,0,0,助詞,接続助詞,*,*,*,*,テ,て,で,デ,で,デ,和,*,*,*,*,*,*,接助,デ,デ,デ,デ,*,"動詞%F1,形容詞%F2@-1",*,6837330270888448,24874
待つ,0,0,0,動詞,一般,*,*,五段-タ行,終止形-一般,マツ,待つ,待つ,マツ,待つ,マツ,和,*,*,*,*,*,*,用,マツ,マツ,マツ,マツ,1,C1,*,9848884062986923,35830
.def ファイル
基本的には UniDic の .def ファイルをそのまま使用。
書き換えるのは、以下の rewrite.def, feature.def。上と同じ理由で unk.def も 0,0,0, 置換しておく。
# node:
# $1: pos1
# $2: pos2
# $3: pos3
# $4: pos4
# $5: cType
# $6: cForm
# $7: lForm
# $8: lemma
# $9: orth
# $10: pron
# $11: orthBase
# $12: pronBase
# $13: goshu
# $14: iType
# $15: iForm
# $16: fType
# $17: fForm
# $18: iConType
# $19: fConType
# $20: type
# $21: kana
# $22: kanaBase
# $23: form
# $24: formBase
# $25: aType
# $26: aConType
# $27: aModType
# unk:
# $1: pos1
# $2: pos2
# $3: pos3
# $4: pos4
# $5: cType
# $6: cForm
[unigram rewrite]
BOS/EOS,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,* $1,*,*,*,*,*,*,BOS/EOS,BOS/EOS,BOS/EOS,*,*,BOS/EOS,*,*,*
*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,* $1,$2,$3,$4,$5,$6,$7,$8,$9,$11,$10,$12,$13,$25,$26,$27
*,*,*,*,*,* $1,$2,$3,$4,$5,$6,*,*,*,*,*,*,*
[left rewrite]
BOS/EOS,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,* X$1,*,*,*,*,*,XBOS/EOS,XBOS/EOS,XBOS/EOS,*,*,*,*,*,*
*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,* X$1,X$2,X$3,X$4,X$5,X$6,X$9,X$8,X$13,X$16,X$17,X$18,X$25,X$26,X$27
*,*,*,*,*,* OX$1,$2,$3,$4,$5,$6,*,*,*,*,*,*
[right rewrite]
BOS/EOS,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,* Y$1,*,*,*,*,*,YBOS/EOS,YBOS/EOS,YBOS/EOS,*,*,*,*,*,*
*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,* Y$1,Y$2,Y$3,Y$4,Y$5,Y$6,*,Y$8,Y$13,Y$14,Y$15,Y$19,Y$25,Y$26,Y$27
*,*,*,*,*,* OY$1,$2,$3,$4,$5,$6,*,*,*,*,*,*
語彙化のrewrite行は消して、
left rewrite したら素性値の頭にXが付いて、right rewrite したら素性値の頭にYが付くように書き換え。
元のファイルでは書字形等はアスタリスク「*」につぶされる設定だったのを
,X$9,X$8,
,Y*,Y$8,
であえて語彙化しつつ左右非対称になる設定に修正。
EOS/BOS 行が dicrc と長さ違ったので同じになるよう調整。
未知語の rewrite の場合はXYの前に O がつくようにしている。
# [0]: pos1
# [1]: pos2
# [2]: pos3
# [3]: pos4
# [4]: cType
# [5]: cForm
# [6]: lForm
# [7]: lemma
# [8]: orth
# [9]: orthBase
# [10]: pron
# [11]: pronBase
# [12]: goshu
UNIGRAM G01:%F[0]
UNIGRAM C01:%F?[4]
UNIGRAM C03:%F?[4],%F?[5]
UNIGRAM O01:%F?[8]
UNIGRAM O02:%F?[9]
UNIGRAM P01:%F?[10]
UNIGRAM P02:%F?[11]
UNIGRAM W01:%F?[12]
UNIGRAM T01:%t
BIGRAM G_G01:%L[0]/%R[0]
BIGRAM O_O01:%L?[6]/%R?[6]
BIGRAM O_O02:%L?[6]/%R?[7]
BIGRAM O_O03:%L?[7]/%R?[7]
素性テンプレートはこんな感じに簡素化。
BIGRAM素性は、L/Rのカタチになっている。
これで準備完了。
学習実行
> mecab-dict-index
> mecab-cost-train -c 1.0 mini_corpus.mecab model
学習実行結果
eta: 5e-05
freq: 1
C: 1
eval-size: 10
unk-eval-size: 4
charset: UTF-8
-0.0742225309004440 C01:カ行変格
-0.0000000000000000 C01:五段-タ行
-0.0742225309004440 C03:カ行変格,終止形-一般
-0.0000000000000000 C03:五段-タ行,終止形-一般
0.0000000000000000 G01:BOS/EOS
-0.0000000000000000 G01:助詞
-0.0742225309004440 G01:動詞
0.0742225309004438 G01:名詞
-0.0742225309004440 G_G01:YBOS/EOS/X動詞
0.0742225309004438 G_G01:YBOS/EOS/X名詞
-0.0000000000000000 G_G01:Y助詞/X動詞
0.0000000000000000 G_G01:Y動詞/XBOS/EOS
-0.0742225309004440 G_G01:Y動詞/X助詞
0.0742225309004440 G_G01:Y名詞/X助詞
-0.0742225309004440 O01:くる
0.0742225309004438 O01:くるま
0.0742225309004440 O01:で
-0.0742225309004440 O01:まで
-0.0000000000000000 O01:待つ
0.0000000000000000 O01:車
-0.0742225309004440 O02:くる
0.0742225309004438 O02:くるま
0.0742225309004440 O02:で
-0.0742225309004440 O02:まで
-0.0000000000000000 O02:待つ
0.0000000000000000 O02:車
-0.0742225309004440 O_O01:YBOS/EOS/Xくる
0.0742225309004438 O_O01:YBOS/EOS/Xくるま
0.0000000000000000 O_O01:YBOS/EOS/X車
-0.0742225309004440 O_O02:YBOS/EOS/X来る
0.0742225309004438 O_O02:YBOS/EOS/X車
-0.0742225309004440 O_O03:YBOS/EOS/X来る
0.0742225309004438 O_O03:YBOS/EOS/X車
0.0742225309004440 O_O03:Yて/X待つ
-0.0742225309004440 O_O03:Yまで/X待つ
0.0000000000000000 O_O03:Y待つ/XBOS/EOS
-0.0742225309004440 O_O03:Y来る/Xまで
0.0742225309004440 O_O03:Y車/Xて
-0.0742225309004440 P01:クル
0.0742225309004438 P01:クルマ
0.0742225309004440 P01:デ
-0.0000000000000000 P01:マツ
-0.0742225309004440 P01:マデ
-0.0742225309004440 P02:クル
0.0742225309004438 P02:クルマ
0.0742225309004440 P02:デ
-0.0000000000000000 P02:マツ
-0.0742225309004440 P02:マデ
0.0000000000000000 T01:0
0.0000000000000000 T01:2
-0.0000000000000002 T01:6
0.0000000000000000 W01:和
BIGRAM 素性を見たらわかるけれど、
- L[]にYが入っているので rewrite.def の [right rewrite] が feature.def の L に対応
- R[]にXが入っているので rewrite.def の [left rewrite] が feature.def の R に対応
-
O_O03:Y来る/Xまで
という素性ができているので、feature.def の L はトークン連接の左トークンに対応、Rは右トークンに対応。ここは直感的。
matrix 作成
> mecab-dict-gen -o ../final -m model
15 16
1 1 0
1 2 0
1 3 0
1 4 0
1 5 0
1 6 0
1 7 0
1 8 0
1 9 0
1 0 0
1 10 0
1 11 0
1 12 0
1 13 0
1 14 0
1 15 0
2 1 0
(略)
0 1 0
0 2 0
0 3 0
0 4 0
0 5 0
0 6 0
0 7 0
0 8 0
0 9 0
0 0 0
(略)
14 12 0
14 13 0
14 14 0
14 15 0
id 0 がファイルの頭でなくて途中にいるせいでわかりづらいけれど、1行目に書いてある通り 15x16 サイズの matrix が完成している。
左右非対称のサイズになっているのは、rewrite.def でそうなるように設定したから。
1 OY名詞,固有名詞,一般,*,*,*,*,*,*,*,*,*
2 OY名詞,固有名詞,人名,一般,*,*,*,*,*,*,*,*
3 OY名詞,固有名詞,地名,一般,*,*,*,*,*,*,*,*
4 OY名詞,数詞,*,*,*,*,*,*,*,*,*,*
5 OY名詞,普通名詞,サ変可能,*,*,*,*,*,*,*,*,*
6 OY名詞,普通名詞,一般,*,*,*,*,*,*,*,*,*
7 OY感動詞,一般,*,*,*,*,*,*,*,*,*,*
8 OY空白,*,*,*,*,*,*,*,*,*,*,*
9 OY補助記号,一般,*,*,*,*,*,*,*,*,*,*
0 YBOS/EOS,*,*,*,*,*,YBOS/EOS,YBOS/EOS,YBOS/EOS,*,*,*,*,*,*
10 Y助詞,Y副助詞,Y*,Y*,Y*,Y*,*,Yまで,Y和,Y*,Y*,Y*,Y*,"Y名詞%F2@1,形容詞%F2@1,動詞%F2@1",Y*
11 Y助詞,Y接続助詞,Y*,Y*,Y*,Y*,*,Yて,Y和,Y*,Y*,Y*,Y*,"Y動詞%F1,形容詞%F2@-1",Y*
12 Y動詞,Y一般,Y*,Y*,Y五段-タ行,Y終止形-一般,*,Y待つ,Y和,Y*,Y*,Y*,Y1,YC1,Y*
13 Y動詞,Y非自立可能,Y*,Y*,Yカ行変格,Y終止形-一般,*,Y来る,Y和,Y*,Y*,Y*,Y1,YC1,Y*
14 Y名詞,Y普通名詞,Y一般,Y*,Y*,Y*,*,Y車,Y和,Yク濁,Y基本形,Y*,Y0,YC2,Y*
1 OX名詞,固有名詞,一般,*,*,*,*,*,*,*,*,*
2 OX名詞,固有名詞,人名,一般,*,*,*,*,*,*,*,*
3 OX名詞,固有名詞,地名,一般,*,*,*,*,*,*,*,*
4 OX名詞,数詞,*,*,*,*,*,*,*,*,*,*
5 OX名詞,普通名詞,サ変可能,*,*,*,*,*,*,*,*,*
6 OX名詞,普通名詞,一般,*,*,*,*,*,*,*,*,*
7 OX感動詞,一般,*,*,*,*,*,*,*,*,*,*
8 OX空白,*,*,*,*,*,*,*,*,*,*,*
9 OX補助記号,一般,*,*,*,*,*,*,*,*,*,*
0 XBOS/EOS,*,*,*,*,*,XBOS/EOS,XBOS/EOS,XBOS/EOS,*,*,*,*,*,*
10 X助詞,X副助詞,X*,X*,X*,X*,Xまで,Xまで,X和,X*,X*,X*,X*,"X名詞%F2@1,形容詞%F2@1,動詞%F2@1",X*
11 X助詞,X接続助詞,X*,X*,X*,X*,Xで,Xて,X和,X*,X*,X*,X*,"X動詞%F1,形容詞%F2@-1",X*
12 X動詞,X一般,X*,X*,X五段-タ行,X終止形-一般,X待つ,X待つ,X和,X*,X*,X*,X1,XC1,X*
13 X動詞,X非自立可能,X*,X*,Xカ行変格,X終止形-一般,Xくる,X来る,X和,X*,X*,X*,X1,XC1,X*
14 X名詞,X普通名詞,X一般,X*,X*,X*,Xくるま,X車,X和,X*,X*,X*,X0,XC2,X*
15 X名詞,X普通名詞,X一般,X*,X*,X*,X車,X車,X和,X*,X*,X*,X0,XC2,X*
matrix.def の最終行が 14 15 0
なので、*-id.def の最終行と見比べて、
matrix.def の 1列目が right-id, 2列目が left-id に対応。
また right-id.def に Y に rewrite された素性、left-idに X にrewrite された素性が入っているので、
- right-id.def が feature.def の L 、rewrite.def の [right rewrite] に対応
- left-id.def が feature.def の R 、rewrite.def の [left rewrite] に対応
くるま,14,14,-259,名詞,普通名詞,一般,*,*,*,クルマ,車,くるま,クルマ,くるま,クルマ,和,ク濁,基本形,*,*,*,*,体,クルマ,クルマ,クルマ,クルマ,0,C2,*,2895297718133248,10533
車,15,14,-155,名詞,普通名詞,一般,*,*,*,クルマ,車,車,クルマ,車,クルマ,和,ク濁,基本形,*,*,*,*,体,クルマ,クルマ,クルマ,クルマ,0,C2,*,2895297651024384,10533
くる,13,13,363,動詞,非自立可能,*,*,カ行変格,終止形-一般,クル,来る,くる,クル,くる,クル,和,*,*,*,*,*,*,用,クル,クル,クル,クル,1,C1,*,2891174448865963,10518
まで,10,10,207,助詞,副助詞,*,*,*,*,マデ,まで,まで,マデ,まで,マデ,和,*,*,*,*,*,*,副助,マデ,マデ,マデ,マデ,*,"名詞%F2@1,形容詞%F2@1,動詞%F2@1",*,9865651581755904,35891
で,11,11,-207,助詞,接続助詞,*,*,*,*,テ,て,で,デ,で,デ,和,*,*,*,*,*,*,接助,デ,デ,デ,デ,*,"動詞%F1,形容詞%F2@-1",*,6837330270888448,24874
待つ,12,12,51,動詞,一般,*,*,五段-タ行,終止形-一般,マツ,待つ,待つ,マツ,待つ,マツ,和,*,*,*,*,*,*,用,マツ,マツ,マツ,マツ,1,C1,*,9848884062986923,35830
これは学習後、0,0,0 に id と生起コストが振り直された mini_lex.csv 。
車,15,14,-155,名詞,普通名詞,一般,,,*,クルマ,車,車,クルマ
というのがいるので、*-id.def の最終行と見比べて、
.csv の 2列目が left-id, 3列目が right-id に対応。
matrix.def と逆なので注意。
図にまとめるとこう。
さらにこう。
ややこしいったらない。
今回使用したファイル、ここに置きました。
追記
今回、matrix.def と left- right-id.def が0始まりでないのは、dicrcで定義したBOS/EOS素性列が、rewrite.def の書き換えルールにマッチしていないからです。