2003年10月24日

MT用ベイズ系フィルタ

上記のサイトを見ているとコメントスパムが結構深刻な状況になってるなぁと思ったので、何か対策しようとやってみました。

最初に思いついたのはベイズ系フィルタをMovableTytpeに実装する方法。
で、Bayesfilterを実装するなPerlで実装しているところからモジュール借りてくればいいかなぁと POPFileのソースを眺めてみましたが、バケツのおかげで処理が煩雑なのでやめ(笑)

次にSpamAssassinに実装されているベイズフィルタ機能をパクろうかと思ったんですが、こっちはモジュール同士の依存性が高くってベイズフィルタ機能だけ切り出せそうも無いのでやっぱりやめ。

で、いつものBogofilterをコマンドラインからコールして処理を行わせる用法を考えましたが、その前に同様の実装をしている人はいないかとぐぐって見たところ・・・

MovableTypeのプラグインとして実装されている神を発見(≧▽≦)ノ

早速上記サイトからmt-bayesian-1.1.tar.gzを落として実装してみました。

インストール方法は大体以下のような感じ

展開して出てきたファイルを次のように再配置します。
mt.cgiがあるディレクトリ(以下MTDir)と同じところに mt-bayesian.cgi を移動してCGIの実行権限を付与
(つまりパーミッションを700とか755に変更<プロバイダごとに異なるので注意)
同時にMTDirにディレクトリ「bdb/」をディレクトリごと移動

   {MTDir}/plugins に
     mt-bayesian.pl

   {MTDir}/lib/MT に
     Bayesian.pm
     BayesianBlog.pm
     BayesianToken.pm

   {MTDir}/lib/MT/App に
     BayesianTrain.pm

   {MTDir}/tmpl/cms に
     bayesian_menu.tmpl 
     bayesian_list_blog.tmpl
     bayesian_list_comments.tmpl
     bayesian_list_pings.tmpl
最後にbayesian-init-db.cgiをMTDirに置いてCGIの実行権限を付与、そしてそのCGIを一度だけブラウザから見てください。
(つまり http://my.domain.blog/mt/bayesian-init-db.cgi てな感じのURLにアクセスする)

成功すると「Done loading bayesian data into the database! All went well.」というメッセージが表示されるのでそれを確認したらbayesian-init-db.cgiは削除してしまってもいいです。
(なお「You are using DBM so there is no need to initalized the database.」と表示された場合はすでにデータベースが出来ているということなのでこれでも成功です)

さて、これでインストールは終わりましたが、このベイズフィルタは英単語しか比較用文字列として収集してくれないのであんまり日本人向きじゃありません。

なので、今度は日本語も収集していくれるようにちょこっとソースをいじることにします。
でも、その前に日本語の判定を行うためには日本語を単語ごとに分解してやる必要があります。
そのために私はText::Kakasiモジュールを使いました。
(サーバの設定をいじれるならcpanで簡単にインストール出来ますし)
なのでこれ以降の変更を行う際は自分のサーバでText::Kakasiモジュールが使えるか確認してから行ってください。
(適当なcgiの最初の方に「use Text::Kakasi;」の一行を加えてサーバにアップして、そのCGIがちゃんと動けばText::Kakasiモジュールは利用可能です)

さていじるファイルは「{MTDir}/lib/MT/Bayesian.pm」だけで、変更点は以下の通り

12行目あたりに
    use Text::Kakasi;
を追加

16行目あたりに
    my $kakasires = Text::Kakasi::getopt_argv('kakasi', '-ieuc', '-w');
を追加

40行目あたりを
    my $max_token_length = 15;
            ↓
    my $max_token_length = 30;
に変更

112行目あたりを
    foreach $token (split /[^-\$A-Za-z0-9\']+/,$message) {
                   ↓
    $message = Text::Kakasi::do_kakasi($message);
    foreach $token (split /[\s]+/,$message) {
に変更
これで日本語の単語もDBに登録されるようになりました。

次にコメントをspamかどうか学習させなければなりません。
学習するためには自分のMovableTypeのエントリ記入用URL(http://my.domain.blog/mt/mt.cgi)の「mt.cgi」の部分をを「mt-bayesian.cgi」に変更してアクセスしてください。

一件変わらぬ管理ページの初期画面になりますが、ブログ一覧の「新しいエントリー」などのリンクの下に「Manage Comments | Manage Pings 」が増えています。

で、Manage Commentsにアクセスするとコメントの一覧が表示され、それぞれのコメントについてスパムかどうか指示するためのチェックボックスがあるので、それを使ってスパムコメントとそうでないコメントをベイズフィルタに学習(「TRAIN」ボタンを押す)させます。

なお、Manage Pingsについてはトレースバックのスパム判定でこれも上記と同じ方法で学習させます。

全部終われば一通り準備完了です

2004年3月3日(水) 追記
ちなみにこのフィルタは自動でスパムコメントを弾いてくれるものではありません。
フィルタがspamを自力で判別出来るようになるとManage Commentsでspamとおぼしきコメントが最初からspam判定(spamの方にチェックボックスが入る)になるので、後は「DELETE SPAM」ボタンで一気に削除しちゃってください。

もし、判定が間違っていたらSPAMとNOT SPAMのチェックを入れ替えてから「TRAIN」ボタンを押すと間違いを正すことが出来ます。

はじめはあんまり頭良くないかもしれませんが、根気よく続けていくとどんどん頭が良くなりますので、気長につきあってください( ̄▽ ̄)ノ

なお、どうしても待てない人はこっちのエントリに対スパムボット用ハックがあるので試して見ると良いかもしれません。
(これのおかげか未だにコメントスパムは無かったりします(≧▽≦)ノ)

Posted by Takuchan at 2003年10月24日 11:20 | トラックバック(40)

あ〜、なんか勘違いしている人がいるようですが、スパムコメントはこのプラグインでは自動で削除されません。

削除するかどうかは最終的に人間が決定します。

このプラグインは削除画面でスパムっぽいメッセージに削除するためのチェックを入れておいてくれるだけです。

そのため大量に来るようなケースでは効果覿面ですが、散発的に1通とかずつ来るケースでは余り効果は望めません。

Posted by: Takuchan at 2004年08月05日 09:01

英語のスパムがひどくて本当にうんざりしているところに、こちらのサイトを見かけて早速導入させていただきました。

TRAINまではうまくいくのですが、いざ「DELETE SPAM」ボタンをおしても、以下のエラーが出てしまいます…

Can't call method "remove" on an undefined value at lib/MT/App/BayesianTrain.pm line 519.

初歩的な何かの間違いかもしれませんが、どうしようもできなくて…
もし、なにかわかるようでしたらアドバイスいただけませんか?

Posted by: あかさ at 2004年08月05日 11:26

ソースを見てみたらコメントの番号を調べてそれを削除する場所なんですが、どうもそれに失敗しているようです。

別の手段で既に消してしまったコメントをさらに消そうとしたりするとそんなエラーが出そうな気がしますが、そういうことも無いですよね?

ちょっと簡単には答えられそうに無いです。

Posted by: Takuchan at 2004年08月05日 16:45

お答えありがとうございます。
特にコメントは自分で削除しない状態で、やっていたので…
きっとなにか自分がアップなどで失敗したに違いないです。
どうもありがとうございました。

Posted by: あかさ at 2004年08月06日 11:15

お力になれずすみませんm(_ _)m

にしても、コメントがちゃんとあるのになんでこけるんだろう。
考えられるのは、プログラムのアップミスか、DBがきちんと出来てないか・・・

どちらにしても大変そうですヽ(´〜`;

Posted by: Takuchan at 2004年08月06日 12:43

こんばんは。

参考にさせていただきました。
なんとか導入できました。ありがとうございました。

Posted by: hiro at 2004年08月21日 00:17

こんにちは。
何とか導入しようと四苦八苦しております。

MySQLを使用しておりますのでDBを認識させるところまではいったのですが、
mt-bayesian.cgiをいざ実行するとエラーが出て止まってしまいます…。

テンプレート bayesian_list_blog.tmpl の読み込みに失敗しました: HTML::Template->new() : Cannot open included file logonav.tmpl : file not found. at extlib/HTML/Template.pm line 2024.

きちんと所定の場所に*.tmplファイルも置いてるのですが…
何か良い対処方法があればご教授いただけると幸いです。

Posted by: keroyon at 2004年09月24日 19:24

エラーメッセージには「logonav.tmplが無いよ」と書いて居ますが、きちんとこのファイルはありますか?

通常は、
{MTDir}/tmpl/cms/
にlogonav.tmplがあるはずですが、もし無いようならMTの大元のパッケージから持ってきて上記の場所にアップロードしてみてください。

Posted by: Takuchan at 2004年09月24日 19:41

インストールフォルダの中にはなかったので、確認をしてみたところ
3.x系ではどうもlogonav.tmplそのものが存在していないようです。
#3.01D-jaと3.1enのフルパッケージを落としなおして確認をしました

2.661からlogonav.tmplを引っ張ってきたところ動くようになりました。
#imagesの中身も一部2.661から引っ張らないと表示がアレになります…

お騒がせして申し訳ありませんでした。
3.x系で設置に引っかかった方の助けになれば幸いです。

Posted by: keroyon at 2004年09月24日 20:48

書き忘れてしまいました。
logonav.tmplのほかに、mininav.templも必要になります。
UTF-8で日本語化したものを使っていますが、今のところ問題なく動いているようです。

imagesは「lang-ja」フォルダをフォルダごとそっくりそのまま追加しました。

Posted by: keroyon at 2004年09月24日 20:52

なるほどMT3.x系でしたか。
今のところMT3に移るメリットが全く無いんでいじってないんですが、やっぱり移行は大変そうですね。

報告ありがとうございました( ̄▽ ̄)ノ

Posted by: Takuchan at 2004年09月24日 22:00

> Can't call method "remove" on an undefined value at lib/MT/App/BayesianTrain.pm line 519.

私も同様の問題を経験しましたが、dbディレクトリ内にある一連のファイルを削除したところ、正常に動作するようになりました。
再度全てのコメントをTrainしなおさなければなりませんが。。。
この問題の原因はどなたかも指摘されていたように、フィルターを使わずにあるコメントを削除したためにコメントのIDがずれてしまったためではないかと思います。(その辺のことは詳しくありませんが、身に覚えがあるので。)

Posted by: etecoo at 2004年11月29日 12:58

>dbディレクトリ内にある一連のファイルを削除したところ、正常に動作するようになりました。
DBをまっさらにすれば復旧は簡単ですが、やはり再学習が面倒ですね。

DBとしてMySQLやPostgreSQLを用いていれば、SQL文を直接発行することでDBの中身を操作して修正することも可能なのですが、割と面倒な作業なので、学習済の件数次第ではまっさらにして再学習が最も早いような気がします。

Posted by: Takuchan at 2004年11月29日 14:32

james seng'sのサイトからBayesian filter for MTをダウンロードしてインストールしたのですが、keroyonさんと同じエラーがでて困ってました。いろいろとググってここにたどり着き、解決方法を見つけてほんと助かりました。
Takuchanさん、keroyonさんありがとうございました。
で、MT本家から2.6のパッケージをダウンロードしようと思ったけど「最新版」しかダウンロードできませんでした。なんでー
kigonav.tmp他探してきまっす!!

Posted by: nama at 2005年09月06日 16:28