在贝叶斯垃圾邮件过滤器中计算令牌成为垃圾邮件的概率。

8

我最近写了一个贝叶斯垃圾邮件过滤器,参考了Paul Graham的文章Spam计划我在codeproject上找到的C#实现 来创建自己的过滤器。

我刚注意到CodeProject上的实现在计算垃圾邮件概率时使用了唯一标记总数(例如如果Ham语料库中总共包含10000个标记,但只有1500个是唯一的标记,则将1500用于计算概率作为ngood),而在我的实现中,我使用了Paul Graham文章中提到的帖子数,这让我想知道哪种方法更好地计算概率:

  1. 帖子计数(如Paul Graham文章中所述)
  2. 唯一标记总数(如codeproject上的实现中使用的)
  3. 标记总数
  4. 包括标记总数(即b + g >= 5的那些标记)
  5. 唯一包括标记总数
4个回答

2

Karl-Michael Schneider 的这篇 EACL 论文建议使用多项式模型,即使用总令牌数来计算概率。请参阅论文获取详细计算方法。


1
一般来说,大多数过滤器已经超越了 Graham 论文中概述的算法。我的建议是获取 SpamBayes 源代码并阅读 spambayes/classifier.py(特别是)和 spambayes/tokenizer.py(特别是顶部)中概述的注释。那里有很多关于早期实验的历史,评估了像这样的决策。
就相关性而言,在当前的 SpamBayes 代码中,概率计算如下(spamcount 和 hamcount 是在该令牌所见到的消息数量(任意次数),nham 和 nspam 是总的消息数量):
hamratio = hamcount / nham
spamratio = spamcount / nspam
prob = spamratio / (hamratio + spamratio)
S = options["Classifier", "unknown_word_strength"]
StimesX = S * options["Classifier", "unknown_word_prob"]
n = hamcount + spamcount
prob = (StimesX + n * prob) / (S + n)

unknown_word_strength 默认值为0.45,unknown_word_prob 默认值为0.5。


非常感谢您的答复,我会去检查一下。目前我正在使用总令牌计数,因为这比使用帖子/消息计数更实用,更具体地说,在不必为帖子/消息计数保留单独的计数器的情况下更为实用,这在我的情况下尤其有用,因为我将尸体统计信息保存在文件中(即令牌及其在尸体中重复出现的时间),以便在需要更新尸体时不必每次扫描所有帖子(一次扫描可能会扫描过多的帖子)。 - Waleed Eissa
所以,我将统计数据保存到文件中,并进行“增量式”更新,如果使用帖子计数(例如在出现错误的情况下),可能会与实际扫描的帖子不同步,这可能会让事情变得混乱。 - Waleed Eissa

0

你能否修改你的代码以使用其他方法?这样你就可以用不同的数据集进行测试,并发布结果。


实际上,我没有足够大的垃圾邮件和正常邮件语料库,所以测试有点困难。目前我正在使用#3,因为它对我来说似乎有些意义(也比使用帖子计数更容易更新语料库)。 - Waleed Eissa
1
你可能不需要大规模语料库来训练你的过滤器。请查看http://entrian.com/sbwiki/TrainingIdeas,了解SpamBayes开发人员发现有效的培训大纲。 - ScottS

0

你可能想看一下PopFile,这是一个经过时间考验的Perl实现。它做得非常好。我很确定它是开源的,你可以看看他们使用了什么公式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接