贝叶斯垃圾邮件过滤器在ASP.NET应用中的实现

随着互联网的快速发展,博客、论坛、电子邮件和Wiki等应用面临着日益严重的垃圾邮件问题。本文将介绍如何通过实现贝叶斯垃圾邮件过滤器来有效减少这些应用中的垃圾邮件。

运营着一个名为“博客漫游者”的小型旅行博客网站,近年来,该网站受到了越来越多的垃圾邮件攻击。最初,通过一些简单的反机器人措施来拒绝那些明显不是Web浏览器的帖子。不久之后,不得不实施一个简单的静默人类检测脚本,以确保有人在真实键盘上手动输入博客条目。

这种方法在很长一段时间内都非常有效。每隔一段时间,一些有抱负的旅行社就会开始发布广告,不得不手动删除它们,直到他们明白这是行不通的。然而,在幕后,每天大约有10,000条自动评论垃圾邮件被拦截。这还不错。

现在是2008年,游戏规则已经改变。开始在“博客漫游者”上看到一种新型的垃圾邮件,而且情况每天都在恶化。这是由真人发送的垃圾邮件。由一个真人在某个工资足够低的地方,广告商可以雇人复制/粘贴评论垃圾邮件。没有任何自动化的人类检测技巧能对抗这种垃圾邮件,因为它不再是自动化的了。

贝叶斯方法

现代电子邮件客户端都使用贝叶斯垃圾邮件过滤,所以认为需要实现的就是这个。在Google上搜索“贝叶斯C#”,惊讶地发现没有人发布过可以直接插入代码库的C#贝叶斯垃圾邮件过滤器。这是怎么回事?这项技术自2002年以来就已经存在了。实现起来真的那么可怕吗?一定是的。不过,手动审核“博客漫游者”真的越来越烦人了。想会尝试一下。知道吗?这其实并不难。

不会详细介绍算法本身。毕竟,只是直接实现了Paul Graham的原始贝叶斯垃圾邮件过滤算法,不认为对他的分析有什么有趣的补充。

使用代码

在本文附带的压缩文件中,会发现两个类,它们让整个事情工作起来。有一个“语料库”类,它保存了单词列表,以及它们在给定文本中出现的次数。还有一个“垃圾邮件过滤器”类,它接受两个这样的语料库,将它们相互碰撞,以产生一个概率列表,即包含给定单词的文档可能是垃圾邮件。

一旦填充了“垃圾邮件过滤器”,可以给它提供其他文档,并询问它是否认为它正在查看垃圾邮件。在测试中,发现它在这方面做得非常好。在所提供的10,000篇博客条目中,大约有6%的假阴性(没有被标记为垃圾邮件的垃圾邮件),只有0.2%的假阳性(错误地被标记为垃圾邮件的好信息)。实际上,它做得如此之好,以至于它的“假阳性”中只有一个实际上是试图审核时漏掉的真正的垃圾邮件。

包括了一个示例WinForms应用程序,让可以看到过滤器在行动中的效果。它有几个文本文件,它读取这些文件来填充“垃圾邮件过滤器”,以提供足够的好和坏的内容,以进行有用的演示。还提供了3个示例博客条目进行测试。其中一个是实际的博客条目,一个是明显的垃圾邮件,另一个是写得很好的垃圾邮件,作为假阴性溜了进来。示例应用程序让可以编辑消息的文本,以查看添加更多或更少的“坏”内容的效果。

投入生产

这对测试目的来说很好,但是如何将这个很酷的过滤器实时投入使用呢?让快速介绍一下今天在“博客漫游者”上是如何做的:

在服务器上保持一个静态的“垃圾邮件过滤器”对象在内存中,这样就不必每次需要它时都重建它。每天,一个作业运行,它从数据库内容中重建“垃圾邮件过滤器”,将其存储在内存中,并通过.Tofile()方法保存一个备份副本。如果发现“垃圾邮件过滤器”对象丢失了(由于服务器循环自身),只需使用.FromFile()方法拉起最后一个状态。

当一个新的博客条目被保存时,将其运行通过“垃圾邮件过滤器”,并根据需要设置博客条目的“是垃圾邮件”位。所有显示代码都知道要检查这个位,并根据需要抑制显示或为被标记为垃圾邮件的条目提供404响应。有一个例外:在新的垃圾邮件条目发布后,会在一分钟内显示它,就好像它不是垃圾邮件一样。这足以让垃圾邮件发送者审查条目并对自己完成的工作表示祝贺,但不足以让页面被搜索引擎索引。自然会从RSS源、站点地图和博客Ping服务请求中排除任何垃圾邮件条目。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485