Edited at

[Ruby]mecabを使ってみた(形態素解析)


Macにmecabをインストール

Ruby: 2.3.3

os: OSX 10.12.3 (Sierra)

SentOSの場合はこの記事を参考にしてください。


mecabと辞書ファイルをmacにインストール

$ brew update

$ brew install mecab mecab-ipadic


gemをインストール

$ gem install mecab


使ってみる

>> require 'mecab'

=> true
>> tagger = MeCab::Tagger.new
=> #<MeCab::Tagger:0x007fb5ff0a2b40 @__swigtype__="_p_MeCab__Tagger">
>> puts tagger.parse('太郎はこの本を二郎を見た女性に渡した。')
太郎 名詞,固有名詞,人名,,*,*,太郎,タロウ,タロー
助詞,係助詞,*,*,*,*,,,
この 連体詞,*,*,*,*,*,この,コノ,コノ
名詞,一般,*,*,*,*,,ホン,ホン
助詞,格助詞,一般,*,*,*,,,
名詞,,*,*,*,*,,,
名詞,一般,*,*,*,*,,ロウ,ロー
助詞,格助詞,一般,*,*,*,,,
動詞,自立,*,*,一段,連用形,見る,,
助動詞,*,*,*,特殊・タ,基本形,,,
女性 名詞,一般,*,*,*,*,女性,ジョセイ,ジョセイ
助詞,格助詞,一般,*,*,*,,,
渡し 動詞,自立,*,*,五段・サ行,連用形,渡す,ワタシ,ワタシ
助動詞,*,*,*,特殊・タ,基本形,,,
記号,句点,*,*,*,*,,,
EOS
=> nil


natto(Gem)を使うと簡単に書ける

nattoはmecabを扱いやすくしてくれるGemです。


nattoをインストール

$ gem install natto


使ってみる

>> require 'natto'

=> true
>> nm = Natto::MeCab.new
=> #<Natto::MeCab:0x007fa61891a9e0 @model.........
>> puts nm.parse('太郎はこの本を二郎を見た女性に渡した。')
太郎 名詞,固有名詞,人名,,*,*,太郎,タロウ,タロー
助詞,係助詞,*,*,*,*,,,
この 連体詞,*,*,*,*,*,この,コノ,コノ
名詞,一般,*,*,*,*,,ホン,ホン
助詞,格助詞,一般,*,*,*,,,
名詞,,*,*,*,*,,,
名詞,一般,*,*,*,*,,ロウ,ロー
助詞,格助詞,一般,*,*,*,,,
動詞,自立,*,*,一段,連用形,見る,,
助動詞,*,*,*,特殊・タ,基本形,,,
女性 名詞,一般,*,*,*,*,女性,ジョセイ,ジョセイ
助詞,格助詞,一般,*,*,*,,,
渡し 動詞,自立,*,*,五段・サ行,連用形,渡す,ワタシ,ワタシ
助動詞,*,*,*,特殊・タ,基本形,,,
記号,句点,*,*,*,*,,,
EOS
=> nil

surface: 形態素の対象要素

posid: 辞書のid

is_eos?: EOS(End Of String)かどうかの判定

>> nm.parse('太郎はこの本を二郎を見た女性に渡した。') do |n|

?> puts "#{n.surface}\tpart-of-speech id: #{n.posid}" if !n.is_eos?
>> end
太郎 part-of-speech id: 44
は part-of-speech id: 16
この part-of-speech id: 68
本 part-of-speech id: 38
を part-of-speech id: 13
二 part-of-speech id: 48
郎 part-of-speech id: 38
を part-of-speech id: 13
見 part-of-speech id: 31
た part-of-speech id: 25
女性 part-of-speech id: 38
に part-of-speech id: 13
渡し part-of-speech id: 31
た part-of-speech id: 25
。 part-of-speech id: 7
=> nil

要素をループで回して処理する場合は、enum_parseメソッドを使うことで効率的に処理ができます。

下記のノードフォーマットオプションでループの際に使う属性をカスタマイズできます。

%m: 形態素の対象要素

%f[0]: 要素名

%f[7]: カナ

>> nm = Natto::MeCab.new('-F%m\t%f[0]\t%f[7]\n')

=> #<Natto::MeCab:0x007ff11a1bc318 @model=...........
>> enum = nm.enum_parse('太郎はこの本を二郎を見た女性に渡した。')
=> #<Enumerator: #<Enumerator::Generator:0x007ff11986f4e0>:each>
>> enum.next
=> #<Natto::MeCabNode:0x007ff11986d438 @pointer=#<FFI::Pointer address=0x007ff11a1e2c30>, stat=0, @surface="太郎", @feature="太郎 名詞 タロウ">
>> enum.peek
=> #<Natto::MeCabNode:0x007ff11909b610 @pointer=#<FFI::Pointer address=0x007ff11a1e2d80>, stat=0, @surface="は", @feature="は 助詞 ハ">
>> enum.rewind
=> #<Enumerator: #<Enumerator::Generator:0x007ff11986f4e0>:each>
>> enum.each {|n| puts n.feature unless n.is_eos? }
太郎 名詞 タロウ
助詞
この 連体詞 コノ
名詞 ホン
助詞
名詞
名詞 ロウ
助詞
動詞
助動詞
女性 名詞 ジョセイ
助詞
渡し 動詞 ワタシ
助動詞
記号
=> nil
>>


参考リンク

https://github.com/markburns/mecab

https://github.com/buruzaemon/natto

http://watarisein.hatenablog.com/entry/2016/01/31/163327