Java製形態素解析エンジン「Igo」を試してみる

概要
IgoはJavaで作られた形態素解析エンジンです。

JavaはJVMという閉じた空間で動作する分、Cなどのネイティブアプリと連携する際の安定性や性能がイマイチ。

そのため形態素解析をしたい場合もMeCabを使わずにJava製のものを利用するケースが目立ちます。IgoはJavaで形態素解析をする場合に選択肢の1つとして挙げられます。

@Date 2010/12/18
@Env Igo0.4.2/Fedora14
Igoの特徴
IgoはMeCabの辞書を利用することができ、ほぼMeCabと同じ解析結果を返すことを意識して作られているそうです(詳細は公式サイト参照)。

Igo - Java形態素解析器
http://igo.sourceforge.jp/

下記ページによると、実行速度もMeCabと比べてそれほど大きく劣ることはないようです。

Igo : MeCabと形態素解析速度比較
http://d.hatena.ne.jp/sile/20100318/1268870637

また、まだ試してませんがダウンロードページを見るとLucene用のAnalyzerも用意されているようです。

Igo Um projeto página de topo portuguesa - SourceForge.JP
http://pt.sourceforge.jp/projects/igo/


※2010/12/23追記 Lucene用Analyzer、試しました。
http://www.mwsoft.jp/programming/munou/igo_lucene.html
SenやGoSenとの違い
Javaの形態素解析エンジンと言うと真っ先に思いつくのが、MeCabのポーティングであるSenGoSen

この2つはMeCabのコードをJavaに変換したものなので、MeCabとほぼ同等の機能を持っています。対するIgoはMeCabと同様の結果を求めてはいるもののソースはオリジナル。そのため、実行結果や持っている機能には多少の差があります。特にMeCabのように多彩な引数を指定したり、ユーザ辞書を指定することなどはできないっぽいです。

ということで機能面ではSenやGoSenに軍配が上がります。でも導入の簡易さメンテナンスという面ではIgoの方が良いです。

Senの最終リリース日は2005年2月、GoSenもかれこれ3年間更新がない。かなり放置系です。対するIgoは2010年5月が最終リリースと割と最近(2010年12月18日確認)。

また、Igoは機能が絞られている分コードの量はそれほど多くないので、自力でソースを読んでメンテナンスをするのもやりやすいです。

インストール手順もSenのように環境変数を設定するなどの手順は必要なく、Jarをクラスパスに追加して辞書を生成するだけで実行することができます。

結論として「IPA辞書をそのまま使ってさくっとJavaで形態素解析したい」という用途であればIgoは向いていると思います。
インストール手順
IgoはJar1個で動くというとてもシンプルな構成。なのでダウンロードするのもJarを1個だけ。

まずは下記URLからigo-0.4.2.jarをダウンロード。
http://sourceforge.jp/projects/igo/releases/

次に下記URLからmecab-ipadicをダウンロード。
http://sourceforge.net/projects/mecab/files/

ダウンロードした辞書データから、Igo用の辞書バイナリファイルを生成する。

// 解凍
$ tar xzvf mecab-ipadic-2.7.0-20070801.tar.gz

// 辞書生成
$ java -cp igo-0.4.2.jar net.reduls.igo.bin.BuildDic ipadic mecab-ipadic-2.7.0-20070801 EUC-JP

これを実行すると、ipadicというディレクトリの中にIgo用の辞書が生成されます。

引数に出てくる文字コードの指定は、MeCabのconfigureで使うような「生成される辞書の文字コード」ではなく、生成元の辞書が用意している「csvファイルなどの文字コード」です。IPA辞書はEUC-JPでファイルを用意しているので、ここでの指定はEUC-JP一択です。

あとは引数にこの辞書のパスを指定してIgoを実行すれば形態素解析できます。

// 実行
$ java -cp igo-0.4.2.jar net.reduls.igo.bin.Igo ipadic
テスト
テスト 名詞,サ変接続,*,*,*,*,テスト,テスト,テスト
EOS

これでインストール作業は終了です。Senと比べるとかなり楽ですね。
Javaからの実行
Igoの用途はコマンドラインじゃなくJavaから呼び出すのがメイン。というわけでJavaでのIgoの実行方法。

とりあえず分かち書きしてみる。分かち書きはTagger.wakatiを実行する。
 
import java.util.List;
import net.reduls.igo.Tagger;
public class IgoTest {
    public static void main(String[] args) throws Exception {
        // 辞書ディレクトリを引数で指定
        Tagger tagger = new Tagger( "ipadic" );
        // 分かち書きの実行
        List<String> wakati = tagger.wakati("この文字列を分かち書きしてみる");
        System.out.println(wakati);
    }
}

これを実行すると、こんな結果が出力される。

[この, 文字, 列, を, 分かち書き, し, て, みる]

次に品詞などもちゃんと出力する形で解析をしてみる。Tagger.parseというメソッドを実行すると、List<Morpheme>という形式で結果が返ってくる。Morphemeはsurface、feature、startという値が格納されている。
 
import java.util.List;
import net.reduls.igo.Morpheme;
import net.reduls.igo.Tagger;
public class IgoTest {
    public static void main(String[] args) throws Exception {
        Tagger tagger = new Tagger( "ipadic" );
        // parseの実行
        List<Morpheme> list = tagger.parse("この文字列を解析してみる");
        for( Morpheme morph : list )
            System.out.println(morph.surface + ", " + morph.feature + ", " + morph.start);
    }
}

これを実行すると、こんな結果が出力される。

この, 連体詞,*,*,*,*,*,この,コノ,コノ, 0
文字, 名詞,一般,*,*,*,*,文字,モジ,モジ, 2
列, 名詞,一般,*,*,*,*,列,レツ,レツ, 4
を, 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ, 5
解析, 名詞,サ変接続,*,*,*,*,解析,カイセキ,カイセキ, 6
し, 動詞,自立,*,*,サ変・スル,連用形,する,シ,シ, 8
て, 助詞,接続助詞,*,*,*,*,て,テ,テ, 9
みる, 動詞,非自立,*,*,一段,基本形,みる,ミル,ミル, 10

実にシンプル。MeCabだと出力形式をいろいろ指定できるけど、Igoの場合は固定っぽいように見えます。
単語を追加する
Igoは辞書生成時に「*.csv」に合致するファイルを登録しているらしい。なので、mecab-ipadicディレクトリに追加したい単語の情報を書いたCSVファイルを入れて辞書を再作成すれば単語が追加されます。

まず、単語追加前の状態で「アーサー マーリン ランスロット」を解析すると、こんな結果になる。

アーサー, 名詞,固有名詞,人名,姓,*,*,アーサー,アーサー,アーサー, 0
マーリン, 名詞,一般,*,*,*,*,*, 5
ラン, 名詞,一般,*,*,*,*,ラン,ラン,ラン, 10
スロット, 名詞,一般,*,*,*,*,スロット,スロット,スロット, 12

ブリテンの偉大な王の名は登録されているようだけど、女好きの魔術師と、王妃と恋に落ちてしまった騎士の名前は登録されていないようです。

そこで以下のようなCSVを作成して、mecab-ipadic-2.7.0-20070801配下に置く。

ランスロット,1291,1291,500,名詞,固有名詞,人名,名,*,*,ランスロット,ランスロット,ランスロット
マーリン,1291,1291,500,名詞,固有名詞,人名,名,*,*,マーリン,マーリン,マーリン
※他のCSVファイルと合わせてEUC-JPで保存する必要があります

// 辞書を再作成
$ java -cp igo-0.4.2.jar net.reduls.igo.bin.BuildDic ipadic mecab-ipadic-2.7.0-20070801 EUC-JP

// 実行
$ java -cp igo-0.4.2.jar net.reduls.igo.bin.Igo ipadic
アーサー マーリン ランスロット

アーサー 名詞,固有名詞,人名,姓,*,*,アーサー,アーサー,アーサー
マーリン 名詞,固有名詞,人名,名,*,*,マーリン,マーリン,マーリン
ランスロット 名詞,固有名詞,人名,名,*,*,ランスロット,ランスロット,ランスロット
EOS

こんな感じでめでたく2人の名前が登録されました。覚えるコマンドは1個だけなので、MeCabで辞書を追加する時より簡単です。

CSVファイルの2〜4番目の値(1291, 1291, 500)はそれぞれ左文脈ID、右文脈ID、コストです。

IPA辞書では人名,名の文脈IDは1291になっています。この数字はmecab-ipadic-2.7.0-20070801配下のleft-id.defやright-id.defを見ればわかります。

コストは小さい数ほど優先して採用されます。詳細は以下のページとか見ていただければ。

【参考】はてなキーワードからMecCab辞書を生成する(Ruby版)
http://www.mwsoft.jp/programming/munou/mecab_hatena.html
コストの単純なつけ方については、ここの「コストについて」を参照。

【参考】日本テレビ東京で学ぶMeCabのコスト計算
http://localhost/programming/munou/mecab_nitteretou.html
コストって何かという話はここを参照。
naist-jdicで辞書作成する
IPA辞書の後継として知られるnaist-jdicを利用することもできます。

下記のURLからnaist-jdic(for MeCab)をダウンロードし、辞書を作成します
http://sourceforge.jp/projects/naist-jdic/

$ tar xzvf mecab-naist-jdic-0.6.3-20100801.tar.gz
$ java -cp igo-0.4.2.jar net.reduls.igo.bin.BuildDic naistdic mecab-naist-jdic-0.6.3-20100801 EUC-JP

するとこんなエラーが出ます。

[PARSE ERROR] Parse short integer failed. For input string: """ {file: mecab-naist-jdic-0.6.3-20100801/naist-jdic.csv, line: 247824}

IgoはCSVファイルを単純にカンマの位置だけ見てパースしているのですが、naist-jdicの中にはカンマ自身が単語として含まれていて、パースが狂うせいで起きています。

// 247824行目にジャンプして当該行を削除
$ vi mecab-naist-jdic-0.6.3-20100801/naist-jdic.csv
247824gg
dd

こんな感じで当該行を消してしまえば解決です。この解決方法が微妙と思う人は、WordDicクラスのcollectWordInfoメソッドでパースしているとこを、いい感じのCSVライブラリ使うように修正するのもアリだと思います。

// 作成した辞書で実行
$ java -cp igo-0.4.2.jar net.reduls.igo.bin.Igo naistdic
まとめ
以上、Igoさんを試してみた記録でした。

Igoさんは何かとわかりやすいですね。Javaであまり凝らずに形態素解析をしたい場合はけっこうイケてるんじゃないでしょうか。

安定性とかについてはまだ未検証です。一応、30MBくらいのファイルをJavaで1行ずつ解析にかけてみた感じでは、まったく問題なく動いてました。
戻る    ご意見、ご要望