Mecab をもっと手軽に Ruby で扱える Gem

  • 35
    Like
  • 0
    Comment
More than 1 year has passed since last update.

問題

mecab-ruby を本格的に使う必要が出てきたので mecab-ruby を触っていました.
mecab-ruby は SWIG という一度書いたものをより高級な言語で使いまわせるようにするツールで実装されているので, インターフェイスが Ruby っぽくないです.
あと各言語向けバインディングの DocMeCab::Node の振舞い で触れられているように MeCab::Node の振る舞いはすこし癖があります.

書いてみた

というわけで, 不満があるならラッパーを書けばいいじゃない!ということで gem を書いてみました.

どこが便利なったのか・使い方

まずは Node インスタンスを作ります.

nodes = Mecab::Ext::Parser.parse("テスト文章")
nodes.class #=> Mecab::Ext::Node

このmecab-ruby の Node がいくつか入った Mecab::Ext::Node をいろいろこねくれるようにしました.

# Enumerable です
nodes.each {|node| p node }
nodes.map {|node| node.surface }
nodes.select {|node| node.surface == "テスト" }
nodes.map {|n| n.surface }.join

# surface だけほしい場合
nodes.each_surface {|surface| p surface }

# 元の Node の各メソッドの返り値をイテレートする
# こっちのが Enumerable のメソッド使えて便利なはず
nodes.surfaces.each {|surface| p surface }
nodes.surfaces.select {|surface| surface == "テスト" }

%w(surfaces features lengths ids char_types isbests wcosts costs).each do |name|
  nodes.respond_to? name #=> true
end

で, これは実は良くなかったりするのかもしれないのですが, 文頭・文末の形態素をカットしています. 不要な場合が多いかな…と思いまして. 必要ならオプションで指定できるようにしたいです.

nodes.count #=> 2

mecab-ruby の Node の上書き問題を解決するために MeCab::Tagger のインスタンス生成を遅らせて, イテレーション毎に生成するようにしました.
なのでなんどもイテレートできますし, 別の文章を解析しても上書きされません.

n1 = Mecab::Ext::Parser.parse "今日の天気"
n2 = Mecab::Ext::Parser.parse "赤い花"
n1.each_surface(&:display)
n2.each_surface(&:display)

というわけで mecab 愛用している方々いかがでしょうか. 今のところ自分向けには 100% 仕様を満たしたので改善点などあればぜひ伺って取り込みたいです.