MeCabとnattoを使ってみる

Last-modified: 2018-05-27 (日) 15:54:30

オープンソースの日本語用形態素解析エンジンであるMeCabとそれをRubyで使いやすくしてくれるというnattoを使ってみた。

 
 

文章から名詞だけを拾い出してみる。

文章を解析して、固有名詞、普通名詞、サ変接続名詞だけを抜き出そうとしたけど、なぜか代名詞も抜き出してしまった。
nattotest_1.rb

 require 'natto'
 require 'pp'
 str = '山本太陽はこう言った。「一般的に芸術は暴発だがこれは一発だ」と。'
 parsetest = Natto::MeCab.new
 parsetest.parse(str) do |line|
   puts "#{line.surface}  #{line.feature}"
 end
 parsetest.parse(str) do |line|
   if line.feature =~ /固有名詞/ || line.feature =~ /名詞,サ変接続/ || line.feature =~ /名詞,一般/
     puts "#{line.surface}  #{line.feature}"
   end
 end

なお、require は'natto'だけでよくて、require 'Mecab'は不要。

 

実行結果

 山本  名詞,固有名詞,人名,姓,*,*,山本,ヤマモト,ヤマモト
 太陽  名詞,一般,*,*,*,*,太陽,タイヨウ,タイヨー
 は  助詞,係助詞,*,*,*,*,は,ハ,ワ
 こう  副詞,助詞類接続,*,*,*,*,こう,コウ,コー
 言っ  動詞,自立,*,*,五段・ワ行促音便,連用タ接続,言う,イッ,イッ
 た  助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
 。  記号,句点,*,*,*,*,。,。,。
 「  記号,括弧開,*,*,*,*,「,「,「
 一般的  名詞,固有名詞,一般,*,*,*,一般的,イッパンテキ,イッパンテキ
 に  助詞,格助詞,一般,*,*,*,に,ニ,ニ
 芸術  名詞,一般,*,*,*,*,芸術,ゲイジュツ,ゲイジュツ
 は  助詞,係助詞,*,*,*,*,は,ハ,ワ
 暴発  名詞,サ変接続,*,*,*,*,暴発,ボウハツ,ボーハツ
 だ  助動詞,*,*,*,特殊・ダ,基本形,だ,ダ,ダ
 が  助詞,接続助詞,*,*,*,*,が,ガ,ガ
 これ  名詞,代名詞,一般,*,*,*,これ,コレ,コレ
 は  助詞,係助詞,*,*,*,*,は,ハ,ワ
 一  名詞,数,*,*,*,*,一,イチ,イチ
 発  名詞,接尾,助数詞,*,*,*,発,ハツ,ハツ
 だ  助動詞,*,*,*,特殊・ダ,基本形,だ,ダ,ダ
 」  記号,括弧閉,*,*,*,*,」,」,」
 と  助詞,格助詞,引用,*,*,*,と,ト,ト
 。  記号,句点,*,*,*,*,。,。,。
   BOS/EOS,*,*,*,*,*,*,*,*
 山本  名詞,固有名詞,人名,姓,*,*,山本,ヤマモト,ヤマモト
 太陽  名詞,一般,*,*,*,*,太陽,タイヨウ,タイヨー
 一般的  名詞,固有名詞,一般,*,*,*,一般的,イッパンテキ,イッパンテキ
 芸術  名詞,一般,*,*,*,*,芸術,ゲイジュツ,ゲイジュツ
 暴発  名詞,サ変接続,*,*,*,*,暴発,ボウハツ,ボーハツ
 これ  名詞,代名詞,一般,*,*,*,これ,コレ,コレ
 
 

繋がっている2つの単語に続く単語をハッシュにしてみた

将来的にマルコフ連鎖っぽいことをするのを想定して、繋がっている2つの言葉(例えば「私 は」)のあとに続く言葉をハッシュに格納するようにしてみた。
キーは、つながる2つの言葉による配列で、値も複数の値が入る場合があるので配列とした。
やってみたら、値の方に同じ言葉が何度も出てくる不具合が生じてしまった。
(moe_dic[keys] = [moe_dic[keys], val].flatten.compact.uniqとuniqを加えるだけだけでよかった。)
nattotest_2.rb

 require 'natto'
 require 'pp'
 str = 'おばばはお綾のいたずらを見つけるたびに「お綾や、親にお謝りなさい」と言ったが、もとよりそのようなことを聞くお綾ではなく、おばばはいつも「これではお綾の
 親に見せる顔がない」と嘆いたものだったが、お綾の親は存外のんきでむしろお綾のじゃじゃ馬ぶりに振り回されるおばばの様子を見て楽しんでいる風であった。'
 parsetest = Natto::MeCab.new
 per_arr = []
 parsetest.parse(str) do |line|
   per_arr.push line.surface
 end
 # pp per_arr
 moe_dic = {}
 cycle = per_arr.size - 3
 cycle.times do |key1, key2, val|
     key1 = per_arr[0]
     key2 = per_arr[1]
     val = per_arr[2]
     keys = [key1, key2]
     moe_dic[keys] = [moe_dic[keys], val].flatten.compact.uniq
     per_arr.shift
 end
 pp moe_dic
 

実行結果(部分)

 {["お", "ばば"]=>["は",  "の"],
  ["ばば", "は"]=>["お", "いつも"],
  ["は", "お"]=>["綾",],
  ["お", "綾"]=>["の", "や", "で"],
  ["綾", "の"]=>["いたずら", "親", "じゃじゃ馬"],
  ["の", "いたずら"]=>["を"],
  ["いたずら", "を"]=>["見つける"],
  ["を", "見つける"]=>["たび"],
  ["見つける", "たび"]=>["に"],