bogofilter を正しく使おう
cygwin を更新すると bogofilter が動かなくなったので最新のソースからインストールし直しました。更に、プライベートではあまりメールを使わないのでこれまで真剣に取り組まなかったのですが、最近 bogofilter の判定精度がいま一つのようなので原因を調べてみました。するといろいろなことがわかりました。
1) MIME エンコードされた本文
本文が MIME エンコードされたスパムが多くなっているのですが、これを nkf や kakasi に喰わせる前にデコードしなければなりません。あちこちの Web に nkf の "-m" で MIME デコードと書いてあったのでそれをそのまま信用していたのですが、実は "-m" だけでは何も起きていないことがわかりました。
本文が MIME エンコードされたスパムが多くなっているのですが、これを nkf や kakasi に喰わせる前にデコードしなければなりません。あちこちの Web に nkf の "-m" で MIME デコードと書いてあったのでそれをそのまま信用していたのですが、実は "-m" だけでは何も起きていないことがわかりました。
参考までにnkf のソース(最新は 2.0.7) でオプションを解析する部分を見ると、
case 'm': /* MIME support */
/* mime_decode_f = TRUE; */ /* this has too large side effects... */
if (*cp=='B'||*cp=='Q') {
mime_decode_mode = *cp++;
mimebuf_f = FIXED_MIME;
} else if (*cp=='N') {
mime_f = TRUE; cp++;
} else if (*cp=='S') {
mime_f = STRICT_MIME; cp++;
} else if (*cp=='0') {
mime_decode_f = FALSE;
mime_f = FALSE; cp++;
}
continue;
(nkf.c より)
/* mime_decode_f = TRUE; */ /* this has too large side effects... */
if (*cp=='B'||*cp=='Q') {
mime_decode_mode = *cp++;
mimebuf_f = FIXED_MIME;
} else if (*cp=='N') {
mime_f = TRUE; cp++;
} else if (*cp=='S') {
mime_f = STRICT_MIME; cp++;
} else if (*cp=='0') {
mime_decode_f = FALSE;
mime_f = FALSE; cp++;
}
continue;
(nkf.c より)
のようになっています。"-mB" とすると base64 のデコードをしますが、メール全体をデコードしてしまいます。
判定用の bogo スクリプトは次の通りです。
「判定に用いるスクリプトのパフォーマンスが悪い」、「パートごとに charset が違うときはどうする?」、「content-type に "application/octet-stream" を指定してテキスト入れてくるスパムも除外したいなあ」等の問題はありますが、とりあえず今の段階ではここまでにしておきます。
2) データベースの内容
まずはどの程度の数のメッセージを学習させたか確認しようとしました。
まずはどの程度の数のメッセージを学習させたか確認しようとしました。
bogoutil -w ~/.bogofilter/wordlist.db .MSG_COUNT
を実行すると学習させたメッセージの数が出力されるのですが、思ったほど数が増えていません。実は spam/ham の登録は、 mew の summary モードより以前の記事で作成した newspam/newham スクリプトを呼び出していたのですが、このときに bogofilter コマンドのオプションに "-N"/"-S" を指定して登録するのはまずいようです。
これらのオプションはメッセージを間違えて登録してしまった時にそれを取り消す場合のみ指定するもので、例えば "-S" については bogofilter のマニュアルに以下のような記載があります。
If -S is used for a message that wasn't registered as spam, the counts will still be decremented.
ということは間違って登録したわけではないのにこれらのオプションを使ってしまうとカウントが減ってしまいます。
そこで newspam/newham スクリプト中の bogofilter 実行オプションを "-s -N" → "-s" 、"-n -S" → "-n" と変更しました。これも某所で見かけたオプションを深く考えず使っていました。newham は先の通りですが、newspam もついでに載せておきます。
これらを改善してデータベースを作り直してから使うと大分判定が良い感じになりました。前の記事では書いていませんが、スパムだけでなくハム(正常なメール)も学習させておかなければなりません。特に nkf の "-m" オプションは、間違って使って「bogofilter は使えない」と思ってしまった人が結構いるのではないでしょうか。
教訓: きちんと自らオプションの意味を確認しなければならない。