はじめに
Pure Rubyな形態素解析器Suikaを作成した。開発中でバッリバリにα版だが、思い切ってリリースすることにした。
suika | RubyGems.org | your community gem host
最も有名な形態素解析器であるMeCabもそうだが、形態素解析器は食べ物の名前がつくことが多い。「Rubyなので赤い食べ物が良いかな」と考えて、文字数とかわいらしさからSuika(スイカ)とした。
使い方
SuikaはPure Rubyで作られているため、MeCabをはじめ特別なライブラリを別途インストールする必要はない。
gem install suika
バッリバリにα版なので、機能はないに等しく、オプションなしのMeCabコマンドと同様となる。
$ irb irb(main):001:0> require 'suika' => true irb(main):002:0> tagger = Suika::Tagger.new irb(main):003:0> puts tagger.parse('すもももももももものうち') すもも 名詞, 一般, *, *, *, *, すもも, スモモ, スモモ も 助詞, 係助詞, *, *, *, *, も, モ, モ もも 名詞, 一般, *, *, *, *, もも, モモ, モモ も 助詞, 係助詞, *, *, *, *, も, モ, モ もも 名詞, 一般, *, *, *, *, もも, モモ, モモ の 助詞, 連体化, *, *, *, *, の, ノ, ノ うち 名詞, 非自立, 副詞可能, *, *, *, うち, ウチ, ウチ => nil
Taggerのparseメソッドは、形態素解析した結果を、StringのArrayで返す。
irb(main):004:0> tagger.parse('すもももももももものうち') => ["すもも\t名詞, 一般, *, *, *, *, すもも, スモモ, スモモ", "も\t助詞, 係助詞, *, *, *, *, も, モ, モ", "もも\t名詞, 一般, *, *, *, *, もも, モモ, モモ", "も\t助詞, 係助詞, *, *, *, *, も, モ, モ", "もも\t名詞, 一般, *, *, *, *, もも, モモ, モモ", "の\t助詞, 連体化, *, *, *, *, の, ノ, ノ", "うち\t名詞, 非自立, 副詞可能, *, *, *, うち, ウチ, ウチ"]
実装のはなし
MeCabの作者であるTaku Kudoさんが書かれた、形態素解析器に関する本を読んで、勉強のために実装した。 ホントにわかりやすい本で、ホントすごい(語彙)。
形態素解析器の実装では、候補となる単語の検索のための、トライ木の実装が重要になるのだが、Rubyでトライ木を実装したGemがすでにあり(自作してた拙いモノはスッパリ捨てて)これを使うことにした。動作も早く、ホントすごい。
さらに、単語の品詞推定などには辞書が必要になる。これについては、Pure Pythonで書かれたJanomeという形態素解析器を参考にした (Pure Pythonで動作も軽いJanomeの存在はSuikaを開発する気合を与えてくれた)。
JanomeはIPAdicによるバイナリ辞書を同梱している。Suikaでも、IPAdicをパースしてRuby Hashにしたりしたモノを持たせることにした。Suika::Tagger.newすると、この同梱したバイナリ辞書を読み込むのだが、ここがとっても遅いので、なんとか改善したい。
おわりに
最初はRumaleの応用も兼ねて、点推定による形態素解析器(単語分割などを機械学習で行う)を遊びで作っていた。作っていると、段々とそれなりに動くものが欲しくなって、ここまで来てしまった。Rubyで形態素解析する場合は、FFIでMeCabを叩くNattoというGemが有名で、これをオススメする。Suikaは、まだ、遊んでみるには良いけど、使ってはいけない。
Rubyには、PythonのNLTKやSpaCyのような包括的な自然言語処理ライブラリで、コレだ!!というのはまだない。RSpecなどがそうだが、自然言語的にかけることを意識するRubyの文化と、自然言語処理は相性が良いと思っている。Rubyな自然言語処理ライブラリを夢見て、Suikaの開発は、少しずつでも続けていきたいと思っている。