【MeCab辞書】left-idとright-idに独自の品詞を追加する方法
あれこれ日本語解析していて独自の品詞が欲しくなったので追加してみました。
どういう事かと言うと解析する文章に都道府県名が入っているかを知る必要が出てきて
文章を分解した後に名詞だけを抜き出してその中から47都道府県名があるか
ぐるぐるとループを回していましたが効率が悪いので新たに品詞IDを振って
その品詞が入っていたら「都道府県名が有る」と判断できるな、と。
たとえば
「今日、北海道で海鮮丼を食べたけどやっぱり本場は違うな」
という文章を解析し、ここに都道府県名が入っているかを判定したくなったということです。
やり方
left-id.defとright-id.defに独自の品詞を追加します。
どちらのファイルも終わりはこうなっています。
1314 名詞,副詞可能,*,*,*,*,*
1315 連体詞,*,*,*,*,*,*
この下に
1316 名詞,都道府県,*,*,*,*,*,*
を追加します。(left-id.defとright-id.def両方)
追加後、Igo用の辞書ファイルを生成し実行したら例外が発生しました。
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1733182 at net.reduls.igo.dictionary.Matrix.linkCost(Unknown Source) at net.reduls.igo.Tagger.setMincostNode(Unknown Source) at net.reduls.igo.Tagger.access$000(Unknown Source) at net.reduls.igo.Tagger$MakeLattice.call(Unknown Source) at net.reduls.igo.dictionary.WordDic$WordDicCallbackCaller.call(Unknown Source) at net.reduls.igo.trie.Searcher.eachCommonPrefix(Unknown Source) at net.reduls.igo.dictionary.WordDic.search(Unknown Source) at net.reduls.igo.Tagger.parseImpl(Unknown Source) at net.reduls.igo.Tagger.parse(Unknown Source) at net.reduls.igo.Tagger.parse(Unknown Source) at igo.test.IgoTest.main(IgoTest.java:11)
アチャー・・・なので調べてみると、かなりデカイ配列の1733182番目がないから落ちたっぽいのでいろいろファイルを見ているとmatrix.defが173万行近くあったのでこいつが関係しそうです。
マトリクスというだけあってすべての品詞の組み合わせに対する何かを書いているみたいです。
matrix.defの中身
1316 1316 0 0 -434 0 1 1 0 2 -1630 ・ ・ 0 100 105 ・ 1 10 -209 ・ ・
例えば
品詞IDが0と100のパターンだとコストが105、1と10だと-209のようになっていて
ここに新たに追加した品詞ID:1316との組み合わせを追加しなければならないようです。
0と1316、1と1316、2と1316、3と1316、4と1316・・・全部追加していくと日が暮れます。
そこで秀丸マクロで一発解決させました。
マクロはこんな感じ
#a = 0; while( #a > 0 ) { searchdown "^"+str(#a)+" 1315" , regular, nocasesense, hilight; golineend; insertreturn; insert str(#a)+" 1316 100"; #a = #a + 1; if(#a == 1315)break; }
あとは1316と0〜1316の組み合わせがないので1315をコピーして一番したにペーストして1315を1316に変更すればOK
1315 0 1793
1315 1 13
↓
1316 0 1793
1316 1 13
わかりづらいかな?
最後に重要なのが
先頭にある1316 1316の部分を1317 1317にする必要があります。
変更後のイメージ
1317 1317 ←変更部分 0 0 -434 ・ 0 1315 -1907 0 1316 100 ←追加部分 ・ ・ 1315 1315 -129 1315 1316 100 ←追加部分 1316 0 1793 ←追加部分 ・ ←追加部分 1316 1316 100 ←追加部分
あとは前回の要領でIgo用の辞書ファイルを生成して
「今日、北海道で海鮮丼を食べたけどやっぱり本場は違うな」を解析するだけ。
しかしここで問題が!
Igoで解析する場合こんなソースになるけど
Tagger tagger = new Tagger("ipadic"); List<Morpheme> list = tagger.parse("今日、北海道で海鮮丼を食べたけどやっぱり本場は違うな"); for (Morpheme morpheme : list) { String str = morpheme.surface + "\t"+ morpheme.feature; System.out.println(str); }
Morphemeから品詞IDが取れないためmorpheme.featureで取得した値に「名詞,都道府県」が含まれるか?
と言う文字列判定が必要になってくる。
できればこれを品詞IDで判定したいところ。
次回はIgoを改造しMorphemeから品詞IDを取得できるようにする方法を紹介します。