2009/03/20

MeCabを用いてスパムフィルタを作ってみよう


Photo by vsz, night glow

以前このブログでMeCabによる形態素解析を紹介しました。正直その後すっかり取り上げたことを忘れてのほほんと過ごしていたわけです(*1)が、ふとしたことでベイジアンフィルタに関するアルゴリズムの記事を見つけ、日本語でこのような記事があるなんて珍しいなということで、ちょっくら実装してみようと思い立ったわけです。

形態素解析部分はMeCabくんがやってくれるので、こっちがするのは名詞を抜き出してデータベース辞書を作り、Graham方式を用いて実装したくらいです。正直ただ単純に実装しただけなのでそこまで参考にならないと思いますが、一応coderepos上に公開してみます。

svn checkout http://svn.coderepos.org/share/lang/python/spam Somewhere

でチェックアウトしてください。

テストにつきましては正直自分のメールアドレスにスパムが届かなかったので(*2)、『Google ニュース』を使って『政治』分野をスパム、『スポーツ』分野を非スパム文章として40件サンプルを手作業で作り(*3)、2つのセンテンス

大阪府の橋下徹知事が進める、府庁を大阪市の第三セクター「大阪ワールドトレードセンタービルディング」(WTC)に移転する構想について、公明党府議団は19日、「原案には賛成できない」として府議会で審議中の移転関連予算案と条例案に反対する方針を決めた。 公明党は自民党とともに知事与党の立場だが「議会として十分な議論ができていない。あまりに拙速だ」としている。条例案の可決には出席議員の3分の2以上の賛成が必要で、原案通りの可決は極めて厳しい状況となった。橋下知事は同日、高齢の障害者らの医療費自己負担を引き上げる案などを、議会側の求めに応じて修正する意向を議会側に伝達。府庁移転問題の好転を図る狙いがあるとみられるが、先行きは不透明だ。橋下知事は、府議会総務常任委員会であらためて移転への意欲を示し、記者団に「(反対は)公明の政治的決断。自民、民主、諸派に納得していただくよう精いっぱい頑張る。可能性はゼロではない」と述べた。

フィギュアスケートの金妍児(キムヨナ)(韓国)が過去の国際大会の練習中、日本選手に進路を妨害されたなどとする韓国メディアの報道について、日本スケート連盟は19日、韓国スケート連盟に対し、報道内容についての調査を求める要望書を提出した。また、国際スケート連合(ISU)に対しても同日、報道への見解を問う文書を提出した。日本スケート連盟によると、韓国側からの直接の抗議や、ISUからの警告はこれまでないという。同連盟の常山正雄専務理事は「日本選手が意図的に妨害した事実はなく、今回の報道には大変困惑しているし、遺憾」としている。


がきちんと判定されているか確かめました。これらの記事を選んだ深い理由は得にないです。
結果は、

$ python test.py
センテンス1がスパムである確率 : 1.0
センテンス2がスパムである確率 : 6.07068879794e-100
スパム文章のサンプル数 : 20
非スパム文章のサンプル数 : 20
スパム辞書が学習した単語数 : 1040
非スパム辞書が学習した単語数 : 854

大体大丈夫そうです。よかったよかった。

学んだこと

  • ベイズ理論を用いたフィルタリングは結構面倒かと思ってましたが、意外と楽でした。まぁ面倒な部分はMeCabがやってくれたっていうのもあるんでしょうけど。
  • pythonのreduce()はとてもエレガントに扱えて便利。たった一行ですむっていうのは気分いいですね。
  • どうでもいいですけどフレッシュネスバーガーのスパムバーガーはおいしいのでお勧めです。

うーんおいしそう!明日食べに行ってきます。

*1 どれくらい忘れていたかというと、"MeCab python"で検索したら自分の記事がトップに出て、「そんなん書いたっけ?」と驚いたくらい。自分の欠点は熱しやすく冷めやすいところだと思う
*2 出会い系とかに登録していればたくさん来ていたかもしれない
*3 本来は4000件くらい作るらしいんですが、さすがに勘弁してください

追記

Robinson方式も扱えるようにレポジトリを更新しました。Robinson方式は未知の単語が出てきた際に、Graham方式よりも適切に判定が行えるアルゴリズムです。

$ python test.py
=====Graham方式による判定=====
センテンス1がスパムである確率 : 1.0
センテンス2がスパムである確率 : 6.07068879794e-100
=====Robinson方式による判定=====
センテンス1がスパムである確率 : 0.999957539928
センテンス2がスパムである確率 : 0.0234555720353
=====辞書に関する情報=====
スパム文章のサンプル数 : 20
非スパム文章のサンプル数 : 20
スパム辞書が学習した単語数 : 1040
非スパム辞書が学習した単語数 : 854

Robinson方式に対応させるために逆カイ二乗関数が必要になったので、今回はchi2pモジュール(http://garyrob.blogs.com/chi2p.py)を利用することにしました。chi2pモジュールはMIT Licenseの元で配布されています。

0 件のコメント: