monoの開発ブログ

Ruby 1.9系でMeCabとClassifier::Bayesを使う

以下のサイトを参考にベイジアンフィルタを利用してみようと思ったのですが、Ruby 1.9.2ではそのまま動かなかったのでメモ。MeCabで日本語を分かち書きに変換し、Classifier::Bayesで推定しています。 - Ruby/ベイジアンフィルタ - TOBY SOFT wiki - classics. > Ubuntuにmecab-ruby入れるメモ

環境は例によってUbuntuです。

MeCabのインストール

sudo aptitude install mecab mecab-ipadic-utf8 libmecab-devcd ~/srcwget http://jaist.dl.sourceforge.net/sourceforge/mecab/mecab-ruby-0.98.tar.gztar zxvf mecab-ruby-0.98.tar.gz cd mecab-ruby-0.98gem build mecab-ruby.gemspecgem install mecab-ruby-0.97.gem

Classifierのインストール

sudo aptitude install libgsl0-devgem install classifier gsl

動作確認

以下のコードは参考にしたページのテストを少しいじったものです。

# -*- coding: utf-8 -*-require 'classifier'require 'stemmer'require 'MeCab'# 分類の設定bayes = Classifier::Bayes.new('mac', 'windows')wakati = MeCab::Tagger.new('-O wakati')# 分類する便利メソッドdef train(bayes, wakati, category, text)  parsed = wakati.parse(text)  bayes.train(category, parsed)  puts "original: #{text}"  puts "MeCabed: #{parsed}"  puts parsed.encoding.inspect  puts end# 分類の学習train(bayes, wakati, 'mac', 'iPodの設定はどのように変更したら良いですか。')train(bayes, wakati, 'mac', 'AirPortの無線ネットワークはどうやって設定しますか。')train(bayes, wakati, 'mac', 'MacOSXのMailはどうやって設定しますか。')train(bayes, wakati, 'windows', 'Internet Explorer 5以降を実行しておく必要があります。')train(bayes, wakati, 'windows', 'マイクロソフトダウンロードセンターからアップデートを取できます。')train(bayes, wakati, 'windows', '今の仕事のためにオフィスライブベーシックを手に入れよう。')comment = 'この書類を開くにはマイクロソフトオフィスが必要です。'parsed = wakati.parse(comment)puts "result original source: #{comment}"puts "result MeCabed source: #{parsed}"# 分類データの数値化puts bayes.classifications(parsed).inspect# 分類の結果puts bayes.classify(wakati.parse(comment))# Bayesオブジェクトの中身p bayes# 追加# 一度ダンプして再度ロードp Marshal.load(Marshal.dump(bayes))

このようにMarshalを利用してダンプすると以下のようなエラーが発生し、再度読み込むことができません。

original: iPodの設定はどのように変更したら良いですか。MeCabed: iPod の 設定 は どの よう に 変更 し たら 良い です か 。#<Encoding:ASCII-8BIT>original: AirPortの無線ネットワークはどうやって設定しますか。MeCabed: AirPort の 無線 ネットワーク は どう やっ て 設定 し ます か 。#<Encoding:ASCII-8BIT>original: MacOSXのMailはどうやって設定しますか。MeCabed: MacOSX の Mail は どう やっ て 設定 し ます か 。#<Encoding:ASCII-8BIT>original: Internet Explorer 5以降を実行しておく必要があります。MeCabed: Internet Explorer 5 以降 を 実行 し て おく 必要 が あり ます 。#<Encoding:ASCII-8BIT>original: マイクロソフトダウンロードセンターからアップデートを取できます。MeCabed: マイクロソフト ダウンロード センター から アップデート を 取 でき ます 。#<Encoding:ASCII-8BIT>original: 今の仕事のためにオフィスライブベーシックを手に入れよう。MeCabed: 今 の 仕事 の ため に オフィスライブベーシック を 手 に 入れよ う 。#<Encoding:ASCII-8BIT>result original source: この書類を開くにはマイクロソフトオフィスが必要です。result MeCabed source: この 書類 を 開く に は マイクロソフト オフィス が 必要 です 。{"Mac"=>-60.186195920171905, "Windows"=>-53.927366061541434}Windows#<Classifier::Bayes:0x00000002bf7280 @categories={:Mac=>{:ipod=>1, :"\xE3\x81\xAE"=>3, :"\xE8\xA8\xAD\xE5\xAE\x9A"=>3, :"\xE3\x81\xAF"=>3, :"\xE3\x81\xA9\xE3\x81\xAE"=>1, :"\xE3\x82\x88\xE3\x81\x86"=>1, :"\xE3\x81\xAB"=>1, :"\xE5\xA4\x89\xE6\x9B\xB4"=>1, :"\xE3\x81\x97"=>3, :"\xE3\x81\x9F\xE3\x82\x89"=>1, :"\xE8\x89\xAF\xE3\x81\x84"=>1, :"\xE3\x81\xA7\xE3\x81\x99"=>1, :"\xE3\x81\x8B"=>3, :"\xE3\x80\x82"=>3, :airport=>1, :"\xE7\x84\xA1\xE7\xB7\x9A"=>1, :"\xE3\x83\x8D\xE3\x83\x83\xE3\x83\x88\xE3\x83\xAF\xE3\x83\xBC\xE3\x82\xAF"=>1, :"\xE3\x81\xA9\xE3\x81\x86"=>2, :"\xE3\x82\x84\xE3\x81\xA3"=>2, :"\xE3\x81\xA6"=>2, :"\xE3\x81\xBE\xE3\x81\x99"=>2, :macosx=>1, :mail=>1}, :Windows=>{:internet=>1, :explor=>1, :"\xE4\xBB\xA5\xE9\x99\x8D"=>1, :"\xE3\x82\x92"=>3, :"\xE5\xAE\x9F\xE8\xA1\x8C"=>1, :"\xE3\x81\x97"=>1, :"\xE3\x81\xA6"=>1, :"\xE3\x81\x8A\xE3\x81\x8F"=>1, :"\xE5\xBF\x85\xE8\xA6\x81"=>1, :"\xE3\x81\x8C"=>1, :"\xE3\x81\x82\xE3\x82\x8A"=>1, :"\xE3\x81\xBE\xE3\x81\x99"=>2, :"\xE3\x80\x82"=>3, :"\xE3\x83\x9E\xE3\x82\xA4\xE3\x82\xAF\xE3\x83\xAD\xE3\x82\xBD\xE3\x83\x95\xE3\x83\x88"=>1, :"\xE3\x83\x80\xE3\x82\xA6\xE3\x83\xB3\xE3\x83\xAD\xE3\x83\xBC\xE3\x83\x89"=>1, :"\xE3\x82\xBB\xE3\x83\xB3\xE3\x82\xBF\xE3\x83\xBC"=>1, :"\xE3\x81\x8B\xE3\x82\x89"=>1, :"\xE3\x82\xA2\xE3\x83\x83\xE3\x83\x97\xE3\x83\x87\xE3\x83\xBC\xE3\x83\x88"=>1, :"\xE5\x8F\x96"=>1, :"\xE3\x81\xA7\xE3\x81\x8D"=>1, :"\xE4\xBB\x8A"=>1, :"\xE3\x81\xAE"=>2, :"\xE4\xBB\x95\xE4\xBA\x8B"=>1, :"\xE3\x81\x9F\xE3\x82\x81"=>1, :"\xE3\x81\xAB"=>2, :"\xE3\x82\xAA\xE3\x83\x95\xE3\x82\xA3\xE3\x82\xB9\xE3\x83\xA9\xE3\x82\xA4\xE3\x83\x96\xE3\x83\x99\xE3\x83\xBC\xE3\x82\xB7\xE3\x83\x83\xE3\x82\xAF"=>1, :"\xE6\x89\x8B"=>1, :"\xE5\x85\xA5\xE3\x82\x8C\xE3\x82\x88"=>1, :"\xE3\x81\x86"=>1}}, @total_words=75>mecab-classifier-test.rb:44:in `load': invalid encoding symbol (EncodingError)        from mecab-classifier-test.rb:44:in `<main>'

Marshalが利用できないと学習したオブジェクトを保存しておくことができず不便なので、なんとか解決してみます。

出力を見た感じだと、どうやらMeCabとstemmerが出力した文字列のエンコーディングが正しく設定されていないことが原因のようです。このような場合にどう対処すればよいかはよく分からないのですが、今回はとりあえず自分のコードが動けばよいということで、強制的に設定するようなワークアラウンドを用意してみました。requireの直後に以下のようなコードを追加することで、今回のエラーを抑止することができます。

class String  alias_method :original_stem, :stem  def stem    self.original_stem.force_encoding(self.encoding)  endendclass MeCab::Tagger  alias_method :original_parse, :parse  def parse(text)    original_parse(text).force_encoding(text.encoding)  endend

この状態で実行すると出力は以下のようになり、無事ダンプすることができました。

original: iPodの設定はどのように変更したら良いですか。MeCabed: iPod の 設定 は どの よう に 変更 し たら 良い です か 。#<Encoding:UTF-8>original: AirPortの無線ネットワークはどうやって設定しますか。MeCabed: AirPort の 無線 ネットワーク は どう やっ て 設定 し ます か 。#<Encoding:UTF-8>original: MacOSXのMailはどうやって設定しますか。MeCabed: MacOSX の Mail は どう やっ て 設定 し ます か 。#<Encoding:UTF-8>original: Internet Explorer 5以降を実行しておく必要があります。MeCabed: Internet Explorer 5 以降 を 実行 し て おく 必要 が あり ます 。#<Encoding:UTF-8>original: マイクロソフトダウンロードセンターからアップデートを取できます。MeCabed: マイクロソフト ダウンロード センター から アップデート を 取 でき ます 。#<Encoding:UTF-8>original: 今の仕事のためにオフィスライブベーシックを手に入れよう。MeCabed: 今 の 仕事 の ため に オフィスライブベーシック を 手 に 入れよ う 。#<Encoding:UTF-8>result original source: この書類を開くにはマイクロソフトオフィスが必要です。result MeCabed source: この 書類 を 開く に は マイクロソフト オフィス が 必要 です 。{"Mac"=>-60.186195920171905, "Windows"=>-53.927366061541434}Windows#<Classifier::Bayes:0x00000001378c18 @categories={:Mac=>{:ipod=>1, :の=>3, :設定=>3, :は=>3, :どの=>1, :よう=>1, :に=>1, :変更=>1, :し=>3, :たら=>1, :良い=>1, :です=>1, :=>3, :。=>3, :airport=>1, :無線=>1, :ネットワーク=>1, :どう=>2, :やっ=>2, :て=>2, :ます=>2, :macosx=>1, :mail=>1}, :Windows=>{:internet=>1, :explor=>1, :以降=>1, :を=>3, :=>1, :し=>1, :て=>1, :おく=>1, :必要=>1, :が=>1, :あり=>1, :=>2, :。=>3, :マイクロソフト=>1, :ダウンロード=>1, :センター=>1, :から=>1, :アップデート=>1, :取=>1, :でき=>1, :今=>1, :の=>2, :仕事=>1, :ため=>1, :に=>2, :オフィスライブベーシック=>1, :手=>1, :入れよ=>1, :う=>1}}, @total_words=75>#<Classifier::Bayes:0x0000000135af38 @categories={:Mac=>{:ipod=>1, :の=>3, :設定=>3, :は=>3, :どの=>1, :よう=>1, :に=>1, :変更=>1, :し=>3, :たら=>1, :良い=>1, :です=>1, :=>3, :。=>3, :airport=>1, :無線=>1, :ネットワーク=>1, :どう=>2, :やっ=>2, :て=>2, :ます=>2, :macosx=>1, :mail=>1}, :Windows=>{:internet=>1, :explor=>1, :以降=>1, :を=>3, :=>1, :し=>1, :て=>1, :おく=>1, :必要=>1, :が=>1, :あり=>1, :=>2, :。=>3, :マイクロソフト=>1, :ダウンロード=>1, :センター=>1, :から=>1, :アップデート=>1, :取=>1, :でき=>1, :今=>1, :の=>2, :仕事=>1, :ため=>1, :に=>2, :オフィスライブベーシック=>1, :手=>1, :入れよ=>1, :う=>1}}, @total_words=75>