woshidan's blog

そんなことよりコードにダイブ。

Mac OSにmecabをインストールしてnattoを利用してrubyからmecabを叩いてみる

ちょっとある程度の量の短文から単語の出現頻度を抽出する必要があり、さわったのでメモ。

Mac OSにHomebrewでmecabをインストールする

Homebrewを通して入れます*1

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

$ brew install mecab
$ brew install mecab-ipadic

mecabrubyから叩きやすいようにnattoのgemを入れる

割と薄い感じのラッパーっぽいやつです。mecab-rubyでもよさそう。

参考:

$ gem install natto

ユーザー辞書を作る

普通の辞書だけだとインターネット業界の人間にとっては、単語が足りないので*2はてなキーワードからユーザー辞書を作ってみます。

手順としては、

となります。

参考:

ユーザー辞書の元となるデータの取得

curl -L http://d.hatena.ne.jp/images/keyword/keywordlist_furigana.csv | iconv -f euc-jp -t utf-8 > keywordlist_furigana.csv

ユーザー辞書の元となるデータをCSVにする

表層形,左文脈ID,右文脈ID,コスト,品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音という行が並んだCSVを作っていきます。

例: 工藤,1223,1223,6058,名詞,固有名詞,人名,名,*,*,くどう,クドウ,クドウ

# http://qiita.com/ynakayama/items/388c82cbe14c65827769 の引用に近いですが...
require 'csv'

CSV.open("custom.csv", 'w') do |csv|
  original_data.each do |type, filename|
    next unless File.file? filename
    open('keywordlist_furigana.csv').each do |title|
      title.strip!

      next if title =~ %r(^[+-.$()?*/&%!"'_,]+)
      next if title =~ /^[-.0-9]+$/
      next if title =~ /曖昧さ回避/
      next if title =~ /_\(/
      next if title =~ /^PJ:/
      next if title =~ /の登場人物/
      next if title =~ /一覧/

      title_length = title.length

      if title_length > 3
        score = [-36000.0, -400 * (title_length ** 1.5)].max.to_i
        csv << [title, nil, nil, score, '名詞', '一般', '*', '*', '*', '*', title, '*', '*', type]
      end
    end
  end
end

CSVユーザー辞書ファイルとしてコンパイルする

環境によって若干パスが違うので、注意。

/usr/local/Cellar/mecab/0.996/libexec/mecab/mecab-dict-index -d /usr/local/Cellar/mecab-ipadic/2.7.0-20070801/lib/mecab/dic/ipadic -u custom.dic -f utf-8 -t utf-8 custom.csv

ユーザー辞書ファイルをmecabの設定ファイルに追加する

nattoのドキュメント見てもユーザー辞書をその場で登録する感じの説明が見当たらなかったのでmecabの設定ファイルにユーザー辞書のパスを追加します。

#  /usr/local/etc/mecabrc に下記の行を追加
userdic = /Users/woshidan/path/to/custom.dic

nattoを使ってmeacbを叩いてみる

require 'natto'

irb(main):001:0> require 'natto'
=> true
irb(main):002:0> nm = Natto::MeCab.new
=> #<Natto::MeCab:0x007fd4431c0948 @model=#<FFI::Pointer address=0x007fd4442c90e0>, @tagger=#<FFI::Pointer address=0x007fd444300e10>, @lattice=#<FFI::Pointer address=0x007fd444300ea0>, @libpath="/usr/local/Cellar/mecab/0.996/lib/libmecab.dylib", @options={}, @dicts=[#<Natto::DictionaryInfo:0x007fd4431f3cf8 @filepath="/usr/local/lib/mecab/dic/ipadic/sys.dic", charset=utf8, type=0>], @version=0.996>
irb(main):003:0> nm.parse("はじめてのMecab")
=> "はじめて\t副詞,一般,*,*,*,*,はじめて,ハジメテ,ハジメテ\n\t助詞,連体化,*,*,*,*,の,ノ,ノ\nMecab\t名詞,固有名詞,組織,*,*,*,*\nEOS\n"
irb(main):004:0> puts nm.parse("はじめてのMecab")
はじめて  副詞,一般,*,*,*,*,はじめて,ハジメテ,ハジメテ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
Mecab 名詞,固有名詞,組織,*,*,*,*
EOS
=> nil

natto, あるいは、mecab-rubyについて、出力形式は他にも良さげなオプションがあった気がしますが、ひとまずこういう感じで。

*1:Yosemite以上にバージョンアップしていたので、自宅のPCのbrewが壊れており http://qiita.com/sue738/items/7ab03ecc9f6fcf37408d http://qiita.com/riocampos/items/b27952faa24524e2919f http://himenaotaro.hatenablog.com/entry/2016/02/14/105251の記事にお世話になりました

*2:プリキュアとか刀剣乱舞とかいろいろ