ベイジアンフィルタによるスパム対策

日々舞い込んでくるスパム(未承諾広告メール)はいまやオンラインのやっかいものだ。世界を行き交うメールトラフィックの50%以上がスパムで占められているとするリサーチ報告もある。

受信ボックスはスパムであふれ、その中から必要なメールを掘り出して整理するのは困難になる一方だ。しかし対抗手段はある。スパムを効率的に排除できるパッケージとその設定について考えてみよう。

スパム排除で最初に効果を上げたのは、ブラックリストを作成して共有するという試みだ。このリストには世界中から寄せられたジャンクメッセージのサンプルと送信元IPアドレスが載っていて、メール送信エージェント(MTA)はこのリストをチェックし、スパムであることが判明しているメッセージとアドレスを拒絶する。また、ユーザの間では、メールクライアントに用意されているキーワードベースのフィルタの使用も広がり始めた。これは、特定の言葉が含まれているメッセージをフィルタのアクションルールに従って自動的にごみ箱に捨てるというものだ。

しかし、これらの防御策は破られ始めている。プロのスパマーたちは、IPアドレスがブラックリストに載っていない新しいコンピュータを世界中から探して次々にハッキングしてメッセージの送信に利用し、最新のメール規格を悪用してメッセージの文面を巧みに隠しているのだ。たとえば、最近のスパムでは、HTMLコード、base-64 MIMEエンコーディング、添付ファイル、画像、その他のトリックが組み合わされていて、メッセージの文面はすぐにはわからないようになっている。スパマーは、これらのエンコーディング方法を駆使して(それなりにコストをかけて)メッセージをばらまき、あとは、メッセージの本当の文面が途中で見抜かれてMTAレベルで破棄されなければよし、と踏んでいるのだ。

メールの文面は長くてくどいものが増え始めている。その一方で、必要最小限の要件しか書いていないものも多い。そして、ランダムなテキストや書籍から抜粋した文章をちりばめて、本当の文面をカモフラージュしているものもしばしば見受けられる。これらの新しいトリックにルールベースのフィルタは撹乱され、ブラックリストも情報が古くなって前ほど役に立たなくなってきている。

このような状況の下、ジャンクメールと必要なメールを見分けるには、一種の「判断力」が必要だ。しかし、この、人間なら苦もなくできることが、コンピュータにとっては何よりも難しい作業なのである。

ベイジアンフィルタ

最近脚光を浴びているのが、ユーザによる判定を先例として学習し、必要なメールだけを識別することのできるベイジアンフィルタだ。ベイジアンフィルタは、ユーザが不要(スパム)または必要と「判定」したそれぞれのメールに基づいて、どの単語、単語グループ、またはバイトストリームが含まれていれば不要/必要と見なしてよいかを学習し、記憶することができる。ここで注意しておきたいのが、「判定」はあくまでもユーザ個人の主観だということだ。それゆえ、スパムメールの概念は、社会環境、ユーザの年齢、思想によって異なる。

実際のところ、ベイジアンフィルタはユーザがメールを不要/必要と分類するたびに統計を蓄積し、単語や単語グループなどの辞書を作成・更新して識別精度を徐々に高めていく。辞書の学習が終わると、それ以降着信するメッセージはすべてデコードおよび解析され、辞書との照合の結果、「スパム度」が計算される。

ベイジアンフィルタはインタラクティブに改良することができる。ユーザが分類を検証し、分類ミスだけをフィルタにフィードバックすることで、分類ルールの精度が向上するのだ。分類エラーには、見逃し(false negative)と誤認(false positive)の2種類がある。前者はスパムを非スパムと判定し、後者は非スパムをスパムと判定するものだ。影響が大きいのはfalse positiveの方だ。なにしろ、必要なメールを知らないうちにごみ箱に捨ててしまう危険性がある。とはいえ、少し使ってみれば、メールの約95%は正しく分類されていることがわかる。これはかなり信頼できる数字だ。ユーザによる介在の必要性は事実上ゼロと言ってよいだろう。辞書の学習が十分であれば(使用しているベイズ理論のアルゴリズムにもよるが)、分類精度が99.9%に達するプログラムもある。問題があるとすれば、それはユーザがフィルタの機能を過信することだけだろう。

しかし、スパムも「進化」する。そのシナリオは自然界の生態系のそれと同じだ。度重なる突然変異と分化の末に、環境変化に最もうまく対応した種だけが生き残るのだ。次々に新種のジャンクメールが誕生し、それが0.1%の分類エラーを引き起こす。これを考えると、最低1か月に1、2回は再学習が必要だろう。

ツールを選ぶ

スパムとの戦いにオープンソースのベイジアンフィルタを使ってみてはどうだろう。実に多くのフィルタがある。探し方によってはおそろしい数のフィルタが見つかるだろう。私が探したのは次の特徴を持つベイジアンフィルタだ。

  • オープンソース(GPLまたはBSDライセンス)
  • マルチプラットフォームに対応
  • 安定した正式リリース版(もしくはそれに準ずる)コード
  • 自己完結(外部のツール、データベースなどに依存しない)
  • 精度が高い(複数単語の分類)
  • 軽快に動作する(CまたはC++を使用、インタープリタ系言語は使用しない)
  • 簡単に使用でき、融通性も高い

さまざまなフィルタを試した結果、私が候補に選んだのはAnnoyance FilterとCRM114の2種類だ。自分のメールアーカイブやオンラインソースから集めた大量のスパムを分類してみたところ、精度はどちらも99.9%に達した。動作速度はAnnoyance Filterの方がCRM114より若干速い(Celeron 600MHzベースの古いノートパソコンではデータ処理速度は300KB/秒、2GHz Athlonベースのコンピュータでは1.5MB/秒に急上昇)。これは、通常の条件であれば、特に最適化を行わなくても1秒当たり60〜300通のメッセージを処理できる計算だ。自宅でも、そしておそらくは会社でも、これだけの処理能力があれば十分すぎるくらいだろう。もちろん、メールメッセージのサイズとエンコーディングの種類(プレーンテキスト、HTML、MIMEなど)、そして判定基準とする単語の数によってパフォーマンスが大きく変わることは言うまでもない。

どちらの製品も修正ベイジアンアルゴリズムを使用してはいるが、その実装方法には大きな相違がある。CRM114では5単語グループのハッシュコードのみの辞書を使用しているが、Annoyance Filterでは1〜n語のグループと従来型のフルテキスト辞書を使用している(高速のバイナリ辞書にも対応)。さらにAnnoyance Filterは統合POP3プロキシを使用することもでき、機能が限定されたメールクライアントに適している。

気に入ったのはコードの完成度の高さだ。Annoyance Filterについて言えば、去年マイナーバグフィックス(完全に下位互換)が2回リリースされており、コードの動作はきわめて安定している。CRM114はリリース準備段階に達している。そのコードは堅牢で数か月使用していても安定しているが、最近、大きな変更がいくつか加えられているため、ある程度時間が経ったら辞書を一から再構築した方がよいかもしれない。

Corrado Cau──IT業界で15年の経験を持つ。そのキャリアの大部分はシステム管理者、ネットワーク管理者としてのもので、さまざまなプラットフォームに精通している。