私は現在蓄積しているコーパスを分析してスパムフィルタを生成しようとしています。Naive Bayesianスパムフィルタリングで個々の確率を組み合わせる
私は分類コードを開発するためにウィキペディアのエントリhttp://en.wikipedia.org/wiki/Bayesian_spam_filteringを使用しています。
私のPHPコード:
public function pSpaminess($word)
{
$ps = $this->pContentIsSpam();
$ph = $this->pContentIsHam();
$pws = $this->pWordInSpam($word);
$pwh = $this->pWordInHam($word);
$psw = ($pws * $ps)/($pws * $ps + $pwh * $ph);
return $psw;
}
メッセージがスパムはそれがウィキから次の式を実装することにより、特定の単語が含まれていることを与えていることを
は、私は確率を計算するコードを実装しました
「個々の確率を組み合わせる」セクションに従って、テストメッセージ内のすべてのユニークワードの確率を組み合わせてスパム性を判断するコードを実装しました。ウィキ式から
:
私のPHPコード: "これがすべてで非常に悪いわけではない" テスト文字列で
public function predict($content)
{
$words = $this->tokenize($content);
$pProducts = 1;
$pSums = 1;
foreach($words as $word)
{
$p = $this->pSpaminess($word);
echo "$word: $p\n";
$pProducts *= $p;
$pSums *= (1 - $p);
}
return $pProducts/($pProducts + $pSums);
}
は、次の出力が生成され:
C:\projects\bayes>php test.php
this: 0.19907407407407
isn't: 0.23
very: 0.2
bad: 0.2906976744186
at: 0.17427385892116
all: 0.16098484848485
probability message is spam: float(0.00030795502523944)
ここに私の質問があります。事実上の確率は正しくありますか?私は有効な個々の単語の確率を生成していると仮定し、組み合わせ方法は正しいですか?
私の懸念は、実際には計算の確率が非常に低いことです。私はより大きなテストメッセージでそれをテストし、結果として10個以上のゼロがある科学記法で確率を上げました。私は10番か100番の場所で値を期待していました。
問題は私のPHP実装にあると思っていますが、私がwikipediaの組み合わせ関数を調べると、数式の配当は分数の積になります。私は、複数の確率の組み合わせがどのように0.1%以上の確率で終わるのか見ていない。
メッセージが長くなるほど確率スコアは低くなりますが、小規模および大規模のテストケースでスパム/ハムを正しく予測するにはどのようにしてスパムの割り当てを補うことができますか?
追加情報
私のコーパスは、実際にはおよそ40Kのredditコメントのコレクションです。私は実際にこれらのコメントに対して私の "迷惑メールフィルタ"を適用しています。私は個々のコメントを下位票への票数に基づいてスパム/ハムとして評価しています。票数が票数を下回っている場合、票はハム、そうでなければ迷惑メールとみなされます。
コーパスタイプのため、実際にはハムよりもスパムで使用される単語はほとんどありません。つまり、ハムよりも頻繁にスパムに表示される単語の上位10個のリストです。
逆に、ほとんどの単語は、ハムよりもハムで非常に豊富に使用されています。たとえば、スパム件数が最も多い言葉の上位10リストを考えてみましょう。
+------+------------+-----------+
| word | spam_count | ham_count |
+------+------------+-----------+
| the | 4884 | 17982 |
| to | 4006.5 | 14658.5 |
| a | 3770.5 | 14057.5 |
| of | 3250.5 | 12102.5 |
| and | 3130 | 11709 |
| is | 3102.5 | 11032.5 |
| i | 2987.5 | 10565.5 |
| that | 2953.5 | 10725.5 |
| it | 2633 | 9639 |
| in | 2593.5 | 9780.5 |
+------+------------+-----------+
ご覧のとおり、スパムの使用頻度は、ハムの使用頻度よりも大幅に低くなっています。 40kコメントの私のコーパスでは、2100件のコメントはスパムとみなされます。
以下示唆したように、次のようにスパム率と考えるポストにテストフレーズ:
フレーズ
Cops are losers in general. That's why they're cops.
分析:
C:\projects\bayes>php test.php
cops: 0.15833333333333
are: 0.2218958611482
losers: 0.44444444444444
in: 0.20959269435914
general: 0.19565217391304
that's: 0.22080730418068
why: 0.24539170506912
they're: 0.19264544456641
float(6.0865969793861E-5)
これによると、非常に低いがありますこれがスパムである可能性があります。
フレーズ
Bill and TED's excellent venture?
分析
C:\projects\bayes>php test.php
bill: 0.19534050179211
and: 0.21093065570456
ted's: 1
excellent: 0.16091954022989
venture: 0.30434782608696
float(1)
さて、これは興味深いです:しかし、場合、私は今、ハムのコメントを分析することでした。私はこのアップデートを構成しているので、これらのサンプルを実行していますので、この特定のテストケースの結果を見たのは初めてです。私の予測は逆転していると思う。実際にはスパムの代わりにハムの確率を選んでいます。これは検証に値する。
既知のハムについての新しい試験。
フレーズ
Complain about $174,000 salary being too little for self. Complain about $50,000 a year too much for teachers.
Scumbag congressman.
分析
C:\projects\bayes>php test.php
complain: 0.19736842105263
about: 0.21896031561847
174: 0.044117647058824
000: 0.19665809768638
salary: 0.20786516853933
being: 0.22011494252874
too: 0.21003236245955
little: 0.21134020618557
for: 0.20980452359022
self: 0.21052631578947
50: 0.19245283018868
a: 0.21149315683195
year: 0.21035386631717
much: 0.20139771283355
teachers: 0.21969696969697
scumbag: 0.22727272727273
congressman: 0.27678571428571
float(3.9604152477223E-11)
残念ながらありません。それは偶然の結果であったことが分かります。おそらくコメントを簡単に数量化できないのだろうかと思い始めています。おそらく、悪いコメントの性質は、スパムメッセージの性質とあまりにも大きく異なります。
スパムフィルタリングは、特定の単語クラスのスパムメッセージがある場合にのみ機能する場合がありますか?
最終更新
回答で指摘したように、奇妙な結果は、コーパスの性質のためにしました。スパムの明示的な定義がない場合のコメントコーパスの使用ベイジアン分類は実行されません。いずれかのコメントが様々なユーザによってスパムとハムの両方の評価を受け取る可能性がある(そして可能性が高い)ので、スパムコメントのために厳密な分類を生成することはできない。
究極的には、コメント投稿が、コメントコンテンツに調整されたベイジアン分類に基づいてカルマを飾るかどうかを判断できるコメント分類子を生成したかったのです。私は依然として分類器のチューニングを調査してスパムメッセージを電子メールで送信し、そのような分類器がコメントシステムのカルマ応答で推測できるかどうかを調べることがあります。しかし、今のところ、質問に答えています。入力いただきありがとうございます。
数式を使用すると+1!そしてコード!そして完全な、よく書かれた説明。私は+10アップアップすることができたらいいと思う。 – wallyk
こんにちはジェレミー。スパムフィルタリングにこのアルゴリズムを使用することになりましたか?私は似たようなことをやろうとしていますが、矛盾した結果が出ます。 –
ヘイ・ポール。私はこれを運動として行いました。それは何にも使われていませんでした。それが価値があることについては、以下に述べるように、同じハム/スパムの例のコーパスを提供したときの結果が私の期待とより一致していることがわかりました。 –