English | Japanese

scbayes: scmail 用のベイジアンフィルタライブラリ

最終更新日: 2004-07-27 (公開日: 2004-01-05)

Shiro Kawai (shiro@acm.org)


scbayesとは

Paul Grahamが提案した、ベイズ検定を用いてスパムフィルタリングを行う ツールです。理論的背景については、参考文献を参照して下さい。 scmailに組み込まれた形で動作します。また、学習や検証を行うために scbayesというスクリプトが用意してあります。

scmailでベイジアンフィルタを使うには、つぎの二つの準備が必要です。

学習

まず学習により確率テーブルを作る必要があります。 spamメールと正当なメールを別のフォルダに分けておいて下さい。 正当なメールを学習するには

% scbayes --learn-nonspam フォルダ ...

spamメールを学習するには

% scbayes --learn-spam フォルダ ...

とすれば、確率テーブルが作成されます。確率テーブルファイルは、 デフォルトでは ~/.scmail/ の下に作成されます。 ~/.scmail/config にてカスタマイズ可能です。既に確率テーブル がある場合はそれに追加されてゆきます。

例えば、正当なメールで保存するものが inbox-saveフォルダに、 spamメールが spamフォルダに、そしてspamではないがゴミとして 捨てたメールが trashフォルダにあるとすると、次のようにコマンド を実行します。

% scbayes --learn-nonspam inbox-save trash
% scbayes --learn-spam spam

筆者の手元の環境 (Pen4 2GHz) では15000通のspamを学習するのに 15分程かかりました。

なお、scbayesは既に学習したメールを記録しておくようになったので、 追加学習をする際には再び同じフォルダを指定すればOKです。 未学習のメールのみテーブルに追加します。

誤って学習させてしまったメールの影響を除きたい場合は、 --unlearn-spam、--unlearn-nonspam オプションを与えると、 指定フォルダに含まれるメールをすべて「忘れる」ことができます。

現在のところ、学習、学習の取消し共にフォルダ単位で扱います。 特定のメッセージのみ扱いたい場合は、それだけを別フォルダに移して 学習等を行って下さい。

scmailの設定

~/.scmail/refile-rules や ~/.scmail/deliver-rules 内に、

(add-bayesian-filter-rule!)

と書いておけば、scmail-refile/scmail-deliver が走った際にベ イジアンフィルタが適用され、spamと判定されたメールが"spam"と いうフォルダ (~/.scmail/config で設定できます) に送られます。

ルールは最初から順に適用されるので、(add-bayesian-filter-rule!)を 書く位置はフィルタリングの有効性に影響します。筆者の経験では、 身元がはっきりしているメールはベイジアンフィルタリングの前に 規則であらかじめ振り分けておき、残ったメールに対して ベイジアンフィルタリングを適用するのが効果が高いようです。

なお、lambda式でフィルタリングルールを書いている場合は、

(mail-is-spam? mail)

という式でspamかどうかの判定ができます。例えば次のように書くことができます。

(lambda (mail)
  (and (mail-is-spam? mail)
       (mail 'from #/\.kp\b/)
       (refile mail "spam-from-north-korea"))

Tips

学習に使うメールが少ないとあまり効果が出ないと思います。 「spamでは無いが捨てたメール」というのは貴重な情報源ですので、 nonspamの学習ソースとして取っておくと良いでしょう。

メールマガジン、オンラインショッピングのレシート、広告付き 無料メーリングリスト等はspam度が高くなりがちなので、ベイジアン フィルタでの判定を行う前にfromフィールド等で別フォルダに仕分けて 置くことを強くお奨めします。

scbayesのその他の機能

scbayesスクリプトには、他にいくつかの管理用機能が実装されています。

学習されたメール数および単語数を見るには、--table-statオプションを用います。

% scbayes --table-stat
lang       nonspam           spam
#t  :  184657w/ 3129m   453409w/14061m
jp  :   88720w/ 3834m    67379w/  813m
total: 273377w/ 6963m   520788w/14874m

langの項は、'#t' が非日本語メール、'jp' が日本語メール、'total' が合計です。 各行において、'w'の前の数字が学習された単語数、'm'の前の数字がメール数です。

scmailを通さずに特定のメールのspam度を調べたい場合は、--check-mail オプションにメールファイルを与えます (メールがひとつづつファイルとして 独立していることを仮定しています。) scbayesは、メールのspam度 および、その計算に寄与した「最も特徴的な単語」15個と各々のspam確率を 表示します。

% scbayes --check-mail ~/Mail/spam/13500
/home/shiro/Mail/spam/13500
  1.0
    wwww3 : 0.9999
    html4 : 0.9999
    style6 : 0.9999
    style5 : 0.9999
    discreetly : 0.9999
    delobel : 0.9999
    bastapharma : 0.9999
    meds : 0.9999
    estes : 0.9998
    overnight : 0.9685370077823972
    needed! : 0.9652974189631429
    medication : 0.9608080329456689
    prescription : 0.9600886615864224
    prescribed : 0.9578025262665094
    medications : 0.9520815441868073

scbayesによる判定そのものの統計をとりたい場合には、--check-spam, --check-nonspamオプションを使います。

% scbayes --check-spam folder

とすると、folderの中のメールを検査し、spamと判定されなかったメールの 総数および各々の単語の確率を出力します (それらのメールは、本来 spamであるのにフィルタをすり抜けたものと考えられます)。

% scbayes --check-nonspam folder

とすると、folderの中のメールを検査し、spamと判定されたメールの 総数および各々の単語の確率を出力します (それらのメールは、本来 nonspamであるのにspamと誤認識されたものと考えられます)。 あまりに誤認識が多い場合は、明示的なフィルタリングルール等を 組み合わせるといった対応が必要かもしれません。筆者の経験では、 ほとんどの場合、この検査は筆者自身の操作の誤りでnon-spamフォルダに 紛れ込んだspamを発見します。

scbayesの処理内容

scbayesはPaul Graham方式の素直な実装ですが、日本語に対応するために 以下の処理を行っています。

さらに詳しい内容に関しては、Gauche:SpamFilterのページを参照して下さい。

参考文献