English | Japanese

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

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

Shiro Kawai (shiro@acm.org)

## scbayesとは

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

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

- scbayesによって、spamと非spamを学習して確率テーブルを作成する。
- 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方式の素直な実装ですが、日本語に対応するために 以下の処理を行っています。

- 日本語の単語分割(トーカナイゼーション)は、bigram、すなわち連続する 2文字を使っています。但し、漢字以外の多バイト文字から漢字への遷移 箇所は単語の区切りとみなすほか、いくつかの多バイト文字の記号も 単語の区切りとみなしています。
- メールのエンコーディングに関しては、まずメールのcontent-typeに 含まれるcharset表記があればそれを信用してエンコーディングの正規化 を行い、それでコード変換や単語分割が失敗した場合はバイト列として 単語分割をやりなおしています。MIMEメッセージの場合にはMIMEパート 毎に扱います。また、text/* 以外のMIMEパートに関しては統計に加えません。
- 日本語メールとそれ以外のメールとで、spamとnonspamの比率が大きく 異なる場合に、単語の確率にバイアスがかかるのを防ぐため、日本語と それ以外とで確率テーブルを分けています。

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

## 参考文献

- Paul Graham: スパムへの対策 -- A Plan for Spam
  - スパムフィルタにベイズ確率を使うことを提案した論文。
- Paul Graham: ベイジアンフィルタの改善 -- Better Bayesian Filtering
  - さらなる改善への方策
- Gauche:SpamFilter
  - scbayesの開発記録