Rubyでベイジアンフィルター

ベイジアンフィルターという仕組みを知ったのは、何年か前に迷惑メールの多さに困り始めた頃だった。OSX付属のMailにも迷惑メールフィルター機能は存在するが、これがあまり賢くない。(いくら学習させても、すり抜けてくる迷惑メールが日に何通かあり、また必要なメールを迷惑メールとしてしまったり。)そんな時に巡り会ったのが、PopfileMgrだった。
使い始めは全くトンチンカンな分類だが、間違って分類した時は、正しく訂正して学習させる。そうしているうちに、驚くほど高精度にメールを分類できるようになる。単なる迷惑メールのフィルタリングだけに留まらず、設定した通りに、どんな風にも分類してくれる。(例えば、「プライベート」「仕事」「DM」「買物」「迷惑」など。)
最近の1ヶ月を振り返って、迷惑メールか、それ以外で、その分類の精度を確認してみた。最近では1日に50通前後の迷惑メールが届く。今確認したところ、ゴミ箱には1701件の迷惑メールが溜まっている。その中でうまく分類できなかったのは、検索してみると、何とたったの5件。迷惑メールの見逃し率は、5÷1701=0.00293944738389、つまり0.294%以下。最近の普通預金金利*1よりは多少高いが、それでも素晴らしい精度だ!しかも、必要なメールであるのに、迷惑メールと分類されたものは1件も無かった。その信頼性も素晴らしい!

PopfileMgrPOPFileがベースになっているらしい。そしてPOPFileは、ベイズ理論に基づく、ベイジアンフィルターという仕組みで、このような高度な分類を可能にしている。(自分自身、その仕組みはちゃんと理解できていない...。)以下はベイジアンフィルターに関する興味深いリンク。

以前からベイジアンフィルターを使えば、何か面白いサービスが出来るのではないか、是非使ってみたい、Rubyで使ってみたい、と思っていたら、最近Rubyベイジアンフィルターを利用できることを知った。早速、実験の開始!
 

利用環境

  • MacBook
  • Locomotive(Rails1.1.6, Ruby1.8.4)

インストール

  • classifier
  • stemmer

ターミナルから以下のように入力するだけで、インストール完了。

gem install classifier stemmer

使ってみる

  • まだ、日本語の取り扱いが出来ないが、以下のコードを実行してみた。
require 'rubygems'
require 'classifier'
require 'stemmer'

# 分類の設定
bayes = Classifier::Bayes.new('mac', 'windows')

# 分類の学習
bayes.train('mac', 'How do I customize my iPod settings?')
bayes.train('mac', 'How do I set up an AirPort wireless network?')
bayes.train('mac', 'How do I set up Mac OS X Mail?')
bayes.train('windows', 'You must be running Microsoft Internet Explorer 5 or later.')
bayes.train('windows', 'You can obtain updates from the Microsoft Download Center.')
bayes.train('windows', 'Get Office Live Basics for your business today')

# 判定する文章
comment = 'How do I sync audio and video to my iPod?'

# 分類データの数値化
puts bayes.classifications(comment).inspect

# 分類の結果
puts bayes.classify(comment)

# Bayesオブジェクトの中身
p bayes
  • 分類の結果、Macと判定された。
# 分類データの数値化
{"Windows"=>-26.7355376535873, "Mac"=>-18.6338897776217}

# 分類の結果
Mac

# Bayesオブジェクトの中身
#{:updat=>1, :must=>1, :live=>1, :"."=>2, :for=>1, :center=>1, :later=>1, :microsoft=>2, :your=>1, :basic=>1, :download=>1, :internet=>1, :busi=>1, :get=>1, :explor=>1, :todai=>1, :obtain=>1, :offic=>1, :run=>1}, :Mac=>{:set=>3, :network=>1, :mac=>1, :custom=>1, :mail=>1, :airport=>1, :ipod=>1, :"?"=>3, :wireless=>1}}, @total_words=34>
  • Locomotiveの環境では、classifierのドキュメントのパスは以下になる。
    • /Applications/Locomotive2/Bundles/standardRailsSept2006.locobundle/i386/lib/ruby/gems/1.8/gems/classifier-1.3.0/doc/index.html


面白い!まだまだ使い始めで分からないことだらけだが、ちゃんと分類できたようだ。次は日本語を取り扱ってみたい。

参考ページ

Fine page! Thanks!

*1:0.200%...。