在贝叶斯垃圾邮件过滤器中计算令牌成为垃圾邮件的概率
Posted
技术标签:
【中文标题】在贝叶斯垃圾邮件过滤器中计算令牌成为垃圾邮件的概率【英文标题】:Calculating the probability of a token being spam in a Bayesian spam filter 【发布时间】:2010-10-17 17:25:21 【问题描述】:我最近写了一个贝叶斯垃圾邮件过滤器,我使用Paul Graham's article Plan for Spam 和an implementation of it in C# I found on codeproject 作为参考来创建我自己的过滤器。
我刚刚注意到 CodeProject 上的实现使用唯一令牌的总数来计算令牌成为垃圾邮件的概率(例如,如果 ham 语料库总共包含 10000 个令牌但有 1500 个 unqiue 令牌,则 1500 用于计算概率为 ngood),但在我的实现中,我使用了 Paul Graham 的文章中提到的帖子数量,这让我想知道其中哪一个在计算概率时应该更好:
-
帖子计数(如 Paul Graham 的文章中所述)
唯一令牌总数(在 codeproject 的实现中使用)
令牌总数
包含的令牌总数(即 b + g >= 5 的令牌)
包含的唯一令牌总数
【问题讨论】:
【参考方案1】:This EACL paper by Karl-Michael Schneider(PDF) 表示您应该使用多项模型(即总令牌数)来计算概率。具体计算请参见论文。
【讨论】:
【参考方案2】:一般来说,大多数过滤器已经超越了 Graham 论文中概述的算法。我的建议是获取 SpamBayes 源并阅读 spambayes/classifier.py(尤其是)和 spambayes/tokenizer.py(尤其是顶部)中概述的 cmets。那里有很多关于已完成的早期实验、评估此类决策的历史。
FWIW,在当前 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。
【讨论】:
非常感谢您的回答,我会检查一下。我目前正在使用总令牌计数,因为这比使用帖子/消息计数更实用,更具体地说,它更实用,因为您不必为帖子/消息计数保留单独的计数器,这是尤其是在我的情况下很有用,因为我将尸体统计信息保存在一个文件中(即令牌和它们在尸体中重复的时间),以便不必在每次尸体需要更新时扫描所有帖子(帖子可以一次扫描太多)。 所以,我将统计信息保存到一个文件并“增量”更新它,如果使用帖子计数,这很容易变得混乱(可能与实际扫描的帖子不同步,例如以防万一错误)【参考方案3】:您可以更改您的代码以使用其他方法吗?然后您可以使用不同的数据集进行测试,然后发布结果。
【讨论】:
实际上我没有足够大的火腿和垃圾邮件语料库,所以如果没有这个就很难测试..我现在使用#3,因为它似乎对我有意义(也使得更新语料库比使用帖子计数更容易) 您可能不需要大型语料库来训练您的过滤器。查看entrian.com/sbwiki/TrainingIdeas,了解 SpamBayes 开发人员发现的有效方法。【参考方案4】:您可能想查看 PopFile,这是一个经过时间考验的 perl 实现。它做得很好。我很确定它是开源的,你可以看到他们使用的公式。
【讨论】:
以上是关于在贝叶斯垃圾邮件过滤器中计算令牌成为垃圾邮件的概率的主要内容,如果未能解决你的问题,请参考以下文章
Atitti 文本分类 以及 垃圾邮件 判断原理 以及贝叶斯算法的应用解决方案