MeCabとRubyで日本語の頻出単語を調べる
こちらのサイトに影響を受けて、日本語の頻出単語を調べてみたくなった。
http://blog.fenrir-inc.com/jp/2011/10/ruby-mecab-japanese-keyword.html
このサイトにRubyのスクリプトが乗っているのですが、なぜか一行になっていて、うまく動かない。だから頑張って自分で作ってみた。
# -*- encoding: utf-8 -*- require 'MeCab' require 'pp' $h = Hash.new $h.default = 1 def add_to_hash s, c stem = s + ":" + c if $h.key?(stem) then $h[stem] = $h[stem] + 1 else $h[stem] = 1 end end m = MeCab::Tagger.new() open(ARGV[0]).each do |line| node = m.parseToNode(line) p_category = "" p_surface = "" while node do category = node.feature.split(',')[0] surface = node.surface if (category == p_category) then p_surface = p_surface + surface elsif (category == "助詞" && surface == "て" && p_category == "動詞") then p_surface = p_surface + surface category == "動詞" elsif (category == "名詞" && surface == "の" && p_category == "動詞") then p_surface = p_surface + surface category == "動詞" elsif (category == "助動詞" && p_category == "動詞") then p_surface = p_surface + surface elsif (p_category == "") then # the first round. Nothing to do else case p_category when "BOS/EOS","記号","助詞","助動詞","連体詞" then # Skip this word else add_to_hash p_surface, p_category end p_surface = surface end node = node.next p_category = category end end hh = $h.to_a.sort do |a,b| (b[1] <=> a[1]) * 2 + (a[0] <=> b[0]) end hh.each do |sc| next if sc[1] == 1 puts "#{sc[0]} : #{sc[1]}" end
たとえば、有島武郎のカインの末裔をUTF8のテキストにして読ませてみる。
彼:名詞 : 212
よう:名詞 : 182
仁右衛門:名詞 : 148
中:名詞 : 87
妻:名詞 : 82
事:名詞 : 77
小屋:名詞 : 72
馬:名詞 : 66
それ:名詞 : 55
の:名詞 : 53
笠井:名詞 : 46
顔:名詞 : 44
眼:名詞 : 42
もの:名詞 : 41
そして:接続詞 : 40
上:名詞 : 39
二人:名詞 : 38
赤坊:名詞 : 37
する:動詞 : 34
所:名詞 : 34
自分:名詞 : 34
し:動詞 : 33
ない:形容詞 : 31
畑:名詞 : 30
風:名詞 : 30
いる:動詞 : 28
前:名詞 : 28
そこ:名詞 : 27
うーん、使えなくもない、というレベルだ。どなたか、もっとキレイに書く方法教えてください。