最終更新日: 2004-03-04 (公開日: 2004-01-05)
Shiro Kawai (shiro@acm.org)
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/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"))
学習に使うメールが少ないとあまり効果が出ないと思います。 「spamでは無いが捨てたメール」というのは貴重な情報源ですので、 nonspamの学習ソースとして取っておくと良いでしょう。
メールマガジン、オンラインショッピングのレシート、広告付き 無料メーリングリスト等はspam度が高くなりがちなので、ベイジアン フィルタでの判定を行う前にfromフィールド等で別フォルダに仕分けて 置くことを強くお奨めします。
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はPaul Graham方式の素直な実装ですが、日本語に対応するために 以下の処理を行っています。
さらに詳しい内容に関しては、Gauche:SpamFilterのページを参照して下さい。