excel日excel表格常用技巧大全使用快捷键有那些。

&&源码搜搜[中文],大家一起找最好的开源代码。
&&请提交您认为需要收录的源码网站。
垃圾邮件过滤系统源代码基于全局的即时垃圾邮件过滤模型的研究标签:电子通讯&评论:0条
邮件地址必须有效,否则出错! 在本机测试必须要联网才行,否则发布出去,还要出错。 一般的服务器都支持JMAIL.EXE组件 如果你的服务器没有,请上传一下就可以了 发送任何垃圾邮件与本站和本人无关,别说我发的,否则人家骂死我:( 发现任何问题,不要来问我,最近比较忙:(. 标签:邮件列表&评论:0条
一.金笛邮件网关反垃圾技术&br&&br&1.关键字过滤&br&2.基于规则的评分系统&br&3.贝叶斯数据库&br&4.黑名单&br标签:DNS&评论:0条
SpamAssassin 是一种安装在邮件伺服主机上的邮件过滤器,用来辨识垃圾信。它是使用大量的预设规则检查垃圾信,这些规则会检查寄到网域内所有邮件的标头,内文,以及送信者。他采取的过滤方式是采用记分制,也就是说会根据我们所设定的标准来给予分数超过标准值的时候即判定为 SPAM(垃圾邮件)如果你是一个提供邮件服务的ISP,标签:linux, unix&评论:0条
邮件发送身份验证功能可以有效的防止垃圾邮件发送者的入侵。管理员可以通过浏览器进行远程邮件帐号管理。...轻松杀除邮件病毒。邮件服务器CMailServer还支持邮件过滤和IP过滤,有效的防止垃圾邮件。标签:Win9x/NT/2000/XP/2003&评论:0条
Postfix是作者在UNIX上所见过的MTA中在反垃圾邮件(Anti- ...甚至有很多公司在Postfix代码的基础上进行二次开发而推出反垃圾邮件网关产品。MTA的反垃圾邮件功能,实际上就是在MTA处理过程中对会话进行过滤。这个过滤不但过滤了发往自身的垃圾邮件,标签:linux, unix&评论:0条
防垃圾邮件功能 、病毒邮件过滤功能 、内嵌防火墙功能 、黑白名单功能 、多语言支持 ...支持公告管理 、支持多域名、支持批量开户 、日志分析功能 、用户自助申请功能 、BIG5自动转换为GB码 HTML在线编辑功能 、邮箱有效期限制 、邮件过滤功能 、语音邮件 、视频邮件、SMTP, POP3, IMAP支持TLS邮件加密 webmail支持https加密、SMTP, POP3,标签:Windows/Linux&评论:0条
Postfix是作者在UNIX上所见过的MTA中在反垃圾邮件(Anti- ...甚至有很多公司在Postfix代码的基础上进行二次开发而推出反垃圾邮件网关产品。MTA的反垃圾邮件功能,实际上就是在MTA处理过程中对会话进行过滤。这个过滤不但过滤了发往自身的垃圾邮件,标签:Unix_Linux&评论:0条
开源邮件服务器zimbra,安装简单,功能强大,继承postfix,clamav、垃圾邮件过滤等等。标签:解决方案&评论:0条
功能齐全 简单易用,功能强大,个性化配置,Thunderbird邮件客户端带给你全方位的体验。 Thunderbird 支持 IMAP内置RSS技术, 功能强大的快速搜索, 自动拼写检查等等. 垃圾邮件过滤 智能垃圾邮件过滤装置将实时检测您的每一封来信,并能够根据您的设置情况自适应做出策略调整,更高效的封锁垃圾邮件。标签:windows, linux&评论:0条
您可以将其加入到拒收列表中. 高级邮件过滤功能 高级邮件过滤功能, 可以让系统帮助您自动将符合指定条件(“邮件地址”、“发件人”、“邮件大小”或“主题”)的邮件进行删除、自动回复或是移到垃圾箱的操作. 我们可以使用此功能对付**益增多的垃圾邮件和其他不受欢迎的邮件. 每一个过滤器的排列顺序是很重要的, 当用户接收到一封符合某一过滤器的邮件后, 如果此过滤器的&标签:邮件列表&评论:0条
IMAP,FTP)、数字水印/SSL加密、网络硬盘、邮件过滤、邮件监控、任务事件、反垃圾邮件,邮件杀病毒、多域名邮件收发和邮件发送验证等功能,是公司,...和传统邮件服务器一样,MuseMail Server 支持互联网邮件收发、网页邮件收发、邮件杀毒、智能邮件过滤、邮件监视、邮件备份、邮件转发、多域名邮件收发和邮件发送验证等功能。同时,由于内核基于数据库,标签:Win9x/NT/2000/XP/2003&评论:0条
说明:java 过滤垃圾邮件 贝叶斯过滤 内含语料
有正常邮件
便以过滤标签:Java&评论:0条
在2008年10月份行将结束之际,Canonical Ltd.终于发布了Intrepid Ibex Ubuntu 8.10的最终正式版本,而且同时放出了桌面版和服务器版。Ubuntu0和OpenJDK。3、增强的邮件服务器能力:提供ClamAV和SpamAssassin,支持垃圾邮件检测、病毒过滤。4、改进的RAID支持:通过DMRaid支持软件SATA RAID控制器,标签:linux, 操作系统&评论:0条
上的网页您的访问者可以评论的新闻物品(可选新闻项目)电子邮件通知一份副本的意见发送给网站管理员贬义词过滤器配置反垃圾邮件设置用户评论(履带与cookies和/或IP地址)动画表情受密码保护的控制中心修改或删除新闻标签:ASP, mysql&评论:0条
说明:垃圾邮件过滤器,你可以将快捷方式直接放到桌面上就可以用了,很方便哦!
打开后先训练, 然后选择你需要测试的txt文件 进行测试 , 其中, 自带的那个“邮件测试文件夹”是用来测试用这个邮件库过滤邮件正确率的,当然你也可以自己用自己准备好的邮件进行测试,不过“邮件测试文件夹”“合法邮件”“垃圾邮件”标签:Java&评论:0条
您的访问者可以评论的新闻物品(可选新闻项目) 电子邮件通知一份副本的意见发送给网站管理员 贬义词过滤器 配置反垃圾邮件设置用户评论(履带与cookies和/或IP地址) 动画表情 受密码保护的控制中心 标签:新闻文章&评论:0条
* IP访问过滤
* 用户邮件大小限制
* ... CHUNCKING support
* SMTP定制消息过滤(可以发现及过滤部分垃圾邮件)
* 支持IP访问中继和验证
标签:CSharp&评论:0条
Endian Firewall是一份统一风险管理工具,它保护网络并改善连接性能。基于Red Hat Enterprise Linux,Endian Firewall百分之百地源码开放,并广泛包含多种功能部件,例如状态检测防火墙、HTTP/FTP病毒防护、内容过滤、POP3/SMTP病毒防护、反网络钓鱼和反垃圾邮件工具、SSL/TLS虚拟专用网、入侵检测系统,以及其他一些功用。标签:linux, 操作系统&评论:0条
上的网页您的访问者可以评论的新闻物品(可选新闻项目)电子邮件通知一份副本的意见发送给网站管理员贬义词过滤器配置反垃圾邮件设置用户评论(履带与cookies和/或IP地址)动画表情受密码保护的控制中心修改或删除新闻标签:ASP, MSSQL&评论:0条
CopyRight (&)
All Rights Reserved&> 断鸿的博客详情
前一段时间用Python写了一个简单的垃圾邮件过滤器,感觉还蛮有意思的,顺便学习一点Python今天做了一点改进,
刚刚升级到1.2版本。项目地址在[mailFilter](/lvwangbeta/mailFilter.git) /lvwangbeta/mailFilter.git。
我想趁2012年还没结束,而且也快考试啦,发篇博文简单介绍一下,主要用到的知识还是 list
dic 这些最基本的数据结构,再加上一点儿概率统计。
好了,还没说怎么个邮件过滤法呢...
它不同于以往的基于关键字和IP阻挡等方法,而是基于贝叶斯推断,也就是条件概率,如果你学过概率论或看过
吴军的数学之美,应该对此概念不陌生,也就是说通过邮件史料库来推断一封新收到的邮件是否为垃圾邮件,我第一次
看到这个想法就比较好奇,真有那么准吗,干脆写一个试试吧。其实,我也是前些日子逛阮一峰的博客看到的,然后
自己写了个简单的实现,所以下面的数学原理还是很感谢阮一峰的日志,参考资料有引用,可详见。下面我就结合代码说一下~
####垃圾邮件过滤的原理大概是这样的:
1. 先通过8000封正常邮件和8000封垃圾邮件“训练”过滤器:
解析所有邮件,提取每一个词,然后,计算每个词语在正常邮件和垃圾邮件中的出
现频率这里涉及到两个问题1)哪来那么多邮件2)怎么中文分词
1. 起初浪费我很多时间的就是这个邮件资料准备,还专门写了个邮件下载脚本,
可惜我的gmail里只有1000多封邮件,根本不够,最后还是靠Google,不过还
真找到了一份05年的邮件史料, 项目文件中的data.rar文件就是,如果想运
行本程序的话,需要先把data.rar解压到当前文件夹.如果想看下载自己邮箱
里邮件的那个脚本,可以到项目主页里去找mailDownload.py文件~
2. 提取邮件中的汉语词汇,这就涉及到中文分词了,我只是给出了一种最易实现
的中文分词方式,基于字典的单词查找:先将中文文本切成最小的单位汉字,
再从词典里找词,将这些字按照最左最长原则,合并为以词为单位的集合。
也就是说把邮件内容先分成单个的汉字(英文这时候就已经是整词了),再在
字典里找最长匹配的。分词的代码如下:
def init_wordslist(self, fn=r"./words.txt"):
读入字典,默认是当前目录的words.txt,也可自己传入位置参数
f = open(fn)
lines = sorted(f.readlines())
return lines
#字典树原理可以看这里
#http://my.oschina.net/u/158589/blog/61037
def words_2_trie(self, wordslist):
将单词表存入字典树
for word in wordslist:
chars = self.regex.findall(word)
for char in chars:
ref[char] = ref.has_key(char) and ref[char] or {}
ref = ref[char]
def search_in_trie(self, chars, trie, res):
逐字检索已经拆分为英文单词或单个汉字的邮件并在字典中查找最长匹配的词语
ref = trie
for char in chars:
if ref.has_key(char):
temp += char
count += 1
ref = ref[char]
index += 1
if temp != 0:
#表示上一个单词已经分离出
res.append(temp)
if index == 0:
#字典中没有以上一个char结尾的单词
res.append(char)
chars = chars[index:]
self.search_in_trie(chars, trie, res)
if count != 0:
#最后一个词
res.append(temp);
不过你也可以使用结巴分词这个第三方扩展库,也是用来中文分词的,我的代码里提供了接口,可以调用splitByjieba
来分割这些邮件。
做完这些后就要对信息进行汇总了,即统计邮件中每个词汇分别在垃圾邮件和正常邮件中出现的频率
self.regex = re.compile(r"[\w-]+|[\x80-\xff]{3}")
self.wordlist = {'normal': [], 'trash': []}
self.maildic = {'normal': {}, 'trash': {}}
self.ratio = {}
self.normalnum = 0
#正常邮件和垃圾邮件数目
self.trashnum = 0
#初始为史料库中的统计
#随着接收邮件的判断,其值还会变动
这里设置几个属性 wordlist记录所有邮件的分词结果,按noraml trash分类.
maildic记录各个邮件的具体分词结果maildic[normal|trash][filename]为该邮件的分词结果集.
ratio记录词汇在正常邮件和垃圾邮件分别出现的概率:
word: [ratio_of_noraml, ratio_of_trash]
&我们假定"sex"这个词,在4000封垃圾邮件中,有200封包含这个词,那么它的出现频率
&就是5%;而在4000封正常邮件中,只有2封包含这个词,那么出现频率就是0.05%,如果某
&个词只出现在垃圾邮件中,就假定,它在正常邮件的出现频率是1%,反之亦然。
&随着邮件数量的增加,计算结果会自动调整
代码如下:
def getNTRatio(self, typ):
分别计算正常(Normal)邮件和垃圾(Trash)邮件中某词在其邮件总数的比例
typ:['normal', 'trash']
counter = collections.Counter(self.wordlist[typ])
dic = collections.defaultdict(list)
for word in list(counter):
dic[word].append(counter[word])
mailcount = len(self.maildic[typ])
if typ == 'normal':
self.normalnum = mailcount
elif typ == 'trash':
self.trashnum = mailcount
for key in dic:
dic[key][0] = dic[key][0] * 1.0 / mailcount
return dic
def getRatio(self):
计算出所有邮件中包含某个词的比例(比如说10封邮件中有5封包含'我们'这个词,
那么'我们'这个词出现的频率就是50%,这个词来自所有邮件的分词结果)
dic_normal_ratio = self.getNTRatio('normal')
#单词在正常邮件中出现的概率
dic_trash_ratio = self.getNTRatio('trash')
#单词在垃圾邮件中出现的概率
dic_ratio = dic_normal_ratio
for key in dic_trash_ratio:
if key in dic_ratio:
dic_ratio[key].append(dic_trash_ratio[key][0])
dic_ratio[key].append(0.01)
#若某单词只出现在正常邮件或垃圾邮件中
dic_ratio[key].append(dic_trash_ratio[key][0])
#那么我们假定它在没出现类型中的概率为0.01
for key in dic_ratio:
if len(dic_ratio[key]) == 1:
dic_ratio[key].append(0.01)
return dic_ratio
2. 当收到一封未知邮件时,在不知道的前提下,我们假定它是垃圾邮件和正常邮件的概率各
为50%,p(s) = p(n) = 50%
3. 解析该邮件,提取每个词,计算该词的p(s|w),也就是受该词影响,该邮件是垃圾邮件的概率
p(w|s)p(s)
p(s|w) = -----------
----------------------
p(s)p(w|s) + p(n)p(w|n)
此处的解析邮件还是类似于前面的邮件分词,对应实现是splitsingle()
4. 提取该邮件中p(s|w)最高的15个词,计算联合概率。
p(s|w1)p(s|w2)...p(s|w15)
p = ---------------------------------------------------------------
p(s|w1)p(s|w2)...p(s|w15) + (1-p(s|w1))(1-p(s|w2)...(1-p(s|w15)))
5. 设定阈值 p & 0.9 :垃圾邮件
p & 0.9 :正常邮件
上面这几部运算都在analysisEmail.py中的judge函数中:
#init是splitEmail对象, trie为先前建立的字典树,email为新接收到的email
def judge(self, init, trie, email):
res = init.splitsingle(trie, email)
#res是分词结果,为list
for i in [';', '', ' ', ':', '.', '。', ':', ',', ' ', '!', '(', ')', '(', ')','!','、']:
if i in res:
res.remove(i)
#剔除标点字符
ratio_of_words = []
#记录邮件中每个词在垃圾邮件史料库(init.ratio[key][1])中出现的概率
for word in res:
if word in init.ratio:
ratio_of_words.append((word, init.ratio[word][1]))
#添加(word, ratio)元祖
init.ratio[word] = [0.6, 0.4]
#如果邮件中的词是第一次出现,那么就假定
#p(s|w)=0.4
ratio_of_words.append((word, 0.4))
ratio_of_words = sorted(ratio_of_words, key = lambda x:x[1], reverse=True)[:15]
rest_P = 1.0
for word in ratio_of_words:
print word[0].decode('utf-8'), word[1]
print word[0], word[1]
P *= word[1]
rest_P = rest_P * (1.0 - word[1])
trash_p = P / (P + rest_P)
if trash_p & 0.9:
typ = 'trash'
typ = 'normal'
init.flush(typ, res)
return trash_p
& 注:如果新收到的邮件中有的词在史料库中还没出现过,就假定p(s|w) = 0.4
下面通过简单地socket通信模拟邮件收发
1.server端:
# -*- coding: utf-8 -*-
import socket
import analysisEmail
import splitEmail
if __name__ == '__main__':
#加载历史邮件资料库,即建立判断条件
init = splitEmail.SplitEmail()
words = init.init_wordslist()
trie = init.words_2_trie(words)
init.split(trie, ['./data/'])
init.ratio = init.getRatio()
#for key in dic_of_ratio:
print key, dic_of_ratio[key]
####################################################################
port = 8888
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(5)
while True:
print "Waiting for clients..."
conn, addr = s.accept()
print 'Connected by', addr
while True:
data = conn.recv(1024)
if not len(data):
msg += data
conn.close()
P = analysisEmail.JudgeMail().judge(init, trie, msg)
print "P(spam) = ", P
# -*- coding: utf-8 -*-
import socket
import sys
if __name__ == '__main__':
host = 'localhost'
port = 8888
fi = str(sys.argv[1])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
msg = open(fi).read()
s.connect((host, port))
s.sendall(msg)
print "error: Input the email location"
好了,说了这么多有点乱,咱们从server启动到接收到client发来邮件,判断是否为垃圾邮件整个过程走一遍
server端运行,首先建立splitemail对象,然后调用init_wordlist()加载字典,之后调用words_2_trie()将
字典转换为字典树,再之后将史料库中的邮件分词,统计各个单词在正常和垃圾邮件中出现的概率。
client发来邮件,server接收后按2~4步(也就是judge函数实现)来判断其是否为垃圾邮件。
具体运行方法可看[mailFilter](/lvwangbeta/mailFilter.git)的readme
####参考资料:
[/blog/2011/08/bayesian_inference_part_two.html](/blog/2011/08/bayesian_inference_part_two.html)
[http://en.wikipedia.org/wiki/Bayesian_spam_filtering](http://en.wikipedia.org/wiki/Bayesian_spam_filtering)
[/zhasm/simpleNLP](/zhasm/simpleNLP)
[http://en.wikipedia.org/wiki/Bayesian_spam_filtering#History](http://en.wikipedia.org/wiki/Bayesian_spam_filtering#History)
[/fxsjy/jieba](/fxsjy/jieba)
人打赏支持
参与源创会
领取时间:
“”在线下联结了各位 OSCer,推广开源项目和理念,很荣幸有你的参与~
领取条件:参与过开源中国“源创会”的 OSCer 可以领取
码字总数 2911
支付宝支付
微信扫码支付
打赏金额: ¥
已支付成功
打赏金额: ¥
& 开源中国(OSChina.NET) |
开源中国社区(OSChina.net)是工信部
指定的官方社区8078人阅读
算法(20)
一. 贝叶斯过滤算法的基本步骤
1) 收集大量的垃圾邮件和非垃圾邮件,建立垃圾邮件集和非垃圾邮件集。
2) 提取邮件主题和邮件体中的独立字串例如 ABC32,¥234等作为TOKEN串并统计提取出的TOKEN串出现的次数即字频。按照上述的方法分别处理垃圾邮件集和非垃圾邮件集中的所有邮件。
3) 每一个邮件集对应一个哈希表,hashtable_good对应非垃圾邮件集而hashtable_bad对应垃圾邮件集。表中存储TOKEN串到字频的映射关系。
4) 计算每个哈希表中TOKEN串出现的概率P=(某TOKEN串的字频)/(对应哈希表的长度)
5) 综合考虑hashtable_good和hashtable_bad,推断出当新来的邮件中出现某个TOKEN串时,该新邮件为垃圾邮件的概率。数学表达式为:
A事件----邮件为垃圾邮件;&
t1,t2 …….tn代表TOKEN串
则P(A|ti)表示在邮件中出现TOKEN串ti时,该邮件为垃圾邮件的概率。
P1(ti)=(ti在hashtable_good中的值)
P2(ti)=(ti在hashtable_ bad中的值)
则 P(A|ti)= P1(ti)/[(P1(ti)+ P2(ti)];
6) 建立新的哈希表 hashtable_probability存储TOKEN串ti到P(A|ti)的映射
7) 至此,垃圾邮件集和非垃圾邮件集的学习过程结束。根据建立的哈希表 hashtable_probability可以估计一封新到的邮件为垃圾邮件的可能性。
当新到一封邮件时,按照步骤2)生成TOKEN串。查询hashtable_probability得到该TOKEN 串的键值。
假设由该邮件共得到N个TOKEN串,t1,t2…….tn, hashtable_probability中对应的值为P1,P2,。。。。。。PN,
P(A|t1 ,t2, t3……tn)表示在邮件中同时出现多个TOKEN串t1,t2…….tn时,该邮件为垃圾邮件的概率。
由复合概率公式可得
P(A|t1 ,t2, t3……tn)=(P1*P2*。。。。PN)/[P1*P2*。。。。。PN+(1-P1)*(1-P2)*。。。(1-PN)]
当P(A|t1 ,t2, t3……tn)超过预定阈值时,就可以判断邮件为垃圾邮件。
二. 贝叶斯过滤算法举例
例如:一封含有“法轮功”字样的垃圾邮件 A
和 一封含有“法律”字样的非垃圾邮件B
根据邮件A生成hashtable_ bad,该哈希表中的记录为
计算得在本表中:
法出现的概率为0。3
轮出现的概率为0。3
功出现的概率为0。3
根据邮件B生成hashtable_good,该哈希表中的记录为:
计算得在本表中:
法出现的概率为0。5
律出现的概率为0。5
综合考虑两个哈希表,共有四个TOKEN串: 法 轮 功 律
当邮件中出现“法”时,该邮件为垃圾邮件的概率为:
P=0。3/(0。3+0。5)=0。375
出现“轮”时:
P=0。3/(0。3+0)=1
出现“功“时:
P=0。3/(0。3+0)=1
出现“律”时
P=0/(0+0。5)=0;
由此可得第三个哈希表:hashtable_probability 其数据为:
法:0。375
当新到一封含有“功律”的邮件时,我们可得到两个TOKEN串,功 律
查询哈希表hashtable_probability可得
P(垃圾邮件| 功)=1
P (垃圾邮件|律)=0
此时该邮件为垃圾邮件的可能性为:
P=(0*1)/[0*1+(1-0)*(1-1)]=0 (ps:实际应用时应该不能出现0,否则一项为零会影响全局)
由此可推出该邮件为非垃圾邮件
(本文是在2003年垃圾邮件大会上的一个讲话。它描述了我为提高在《一个计划》中提到算法所做的工作,以及我对未来的打算。)
我想在此给出的第一个发现,是一个用于评估科研论文的懒人算法。你只需写下你想写的,不去引用任何前人的工作,然后热心读者会把你应该引用的论文章节都寄给你。我在《一个计划》【1】发表于Slashdot之后发现的这个算法。
垃圾邮件过滤,是文件分类的一个子集,它是一个相当健全的领域。不过关于贝叶斯过滤法最早的两个文献都是在1988年大会上给出的,一个提供者是Pantel和Lin【2】,另一个是微软研究所的一个小组【3】。
当我听说这项工作时我有点吃惊。如果人们早在四年前就开始贝叶斯过滤法的话,那为什么如今没人在用它呢?读了文章后我明白为什么了。Pantel和Lin的过滤法时那两个中比较有效的一个,可它也只抓住了92%的垃圾邮件,并且是1.16%的错纠率。
当我试着编写一个贝叶斯过滤法时,它抓住了99.5%的垃圾邮件,且错纠率低于0.03%【4】。两个人做同一个实验却得到差别很大的结果,这是很应该引起注意的。在这件事中尤其如此,因为不同的结果可以导致完全相反的结论。诚然,不同用户有不同的需求,不过我想了,对很多人来说,过滤效率仅92%错纠率却高达1.16%,意味着这个过滤法是在不好接受。而99.5%对应小于0.03%的错纠率,则意味着相反。
那么,为什么我们得到如此不同的数字呢?我没有尝试去复制Pantel和Lin的结果,但只是读了他们的论文,我发现有五件事大概可以解释这个差异的。
第一个很简单,他们的过滤法建立在一个很小的数据库上:160个垃圾邮件和466个非垃圾邮件。即便数据库如此之小,过滤效率还是应该高得多的。所以这些数字大概不恩那个确切说明他们算法的有效程度,更不用说广义上的贝叶斯过滤法的有效程度了。
不过我认为,最重要的区别大概在于,他们忽略了邮件台头。这在任何致力于垃圾邮件过滤器的人看来,都是一个不合常理的做法。可实际上在我尝试编写第一个过滤器时,我也忽视了台头。为什么呢?因为我想让问题简单化。那会儿我对邮件台头知道得还不多,对我来说,它们就是一堆随机的玩意儿。这里,对过滤器编写者是一个教训:不要忽略数据。你会觉得这个教训太明显了,不值一提,可我实际上不得不把它吸取了好几遍。
第三,Pantel和Lin对token进行了剪切,好比说,他们把“mailing”和“mailed”都压缩成根词“mail”来处理。他们大概觉得必须得这样做,因为他们采用邮件集的容量之小。可若如此,这不过是一个不成熟的乐观想法。
第四,他们用了不同的方法来算概率。他们把所有的token都用上了,而我只用了15个最具代表性的。当你使用所有的token时,你就倾向错过较长的垃圾邮件,那些某人跟你讲他们一生的故事,讲直到某天他们通过某种分层营销手段而致富的邮件。并且这样的算法容易北垃圾散发者所愚弄:只需加上一大堆随机文档来中和掉那些垃圾术语就可以了。
最后一点是,他们没有对错纠提起注意。我认为,不管什么垃圾邮件过滤法,都需要包含一个方便旋钮,你一拧,就能在降低过滤率的代价之上降低错纠率。我用的法子,是把token在非垃圾邮件集里出现的次数加倍。
我认为,把过滤垃圾邮件当作单纯是一个文件分类问题来处理不是个好主意。你可以使用文件分类技术,可你的法子应当体现出这些文件是邮件的事实,并且特别是垃圾邮件。邮件不仅仅是文本,它具有自己的结构,过滤垃圾邮件不仅仅是分类,因为错纠比错放要恶劣得多多,你必须把它们看成是不同性质的差错,并且这些差错的来源并非什么随机偏差,而是活生生的致力于攻克你过滤器的垃圾邮件制作人。
在Slashdot文章(译者注:《一个计划》)之后,我听说的另一个项目是Bill Yerazunis的CRM114【5】。这是我刚提到过设计原理的一个反例。它是一个单纯的文本分类器,但却有着惊人的效率,可以在不知道自己在做什么的情况下,把垃圾邮件近乎完美地给过滤掉。
当我理解了CRM114是怎么工作的之后,看似不可避免地,我迟早德从基于单个单词的过滤法走向类似这个的方法。不过我先是想着,我得看看依靠单个单词能走多远。然后那答案是,令人吃惊之远。
总体上我致力于更精良的token化处理工作。对现有的垃圾邮件,我已能达到近似crm114的过滤效率。这些技术跟Bill的(译者注:CRM114用到的技术)基本上是正交的。一个理想化方案大概是合并这二者。
《一个计划》中用的是一个对token的简单定义方法:字母,数字,破折号,撇号,美元符号,这些是组成成分,其他的都是token分离符。我还忽略了词格(译者注:例如,主谓宾格)。
现在我有一个更复杂的token定义法则:
1. 词格保留。
2. 惊叹号是组成成分。
3. 当句号和逗号出现在两个数字之间时,它们也是组成成分。这样我可以使IP地址和价钱保持不碰。
4. 价格范围如$20-25,是两个token,$20和$25。
5. 在发往To,来自From,主题Subject,和回归路径Return-Path这些栏,或是url中的出现的token,作以相应的标记。例如,主题Subject中的“foo”就变成“Subject*foo”。(这里的星号可以是任何你没定义成token组成成分的符号。)
以上措施提高了过滤器的词汇量,于是使分辨率更高。举例说,在现有的过滤器中,主题栏出现的“free”一词具有98%的垃圾概率,而在正文出现的同一token概率仅为65%。
以下是现有的一些概率【6】:
Subject*FREE 0.9999
free!! 0.9999
To*free 0.9998
Subject*free 0.9782
free! 0.9199
Free 0.9198
Url*free 0.9091
FREE 0.8747
From*free 0.7636
free 0.6546
在上次的计划中,所有这些token的概率是一样的,都是0.7602。那个过滤器识别的token大约有23,000个,现有的约为187,000个。
更大的token世界带来的坏处是,错放的机会会增加。对一个邮件集来说,提高其token数目的效果类似于减小其容量。例如,你要是把惊叹号当成组成成分,结果你就找不到free连着7个惊叹号的概率,虽然你明知道free带两惊叹号的概率是99.99%。
一个解决方法是我所谓“退化法”。如果你找不到某个token的确切数值,你就把它处理成一个不那么明确的版本。像末尾的惊叹号,大写字母,以及在那五个标记位置里出现,这些我都看成是使token更明确化的标志。例如,假如我找不到“Subject*free!”的概率,我就去找“Subject*free”,“free!”和“free”,然后取其中离0.5最远的那个概率。
以下列举的是过滤器在主题栏看见“FREE!!!”并且找不到其概率是所拥有的其他选择【7】:
Subject*Free!!!
Subject*free!!!
Subject*FREE!
Subject*Free!
Subject*free!
Subject*FREE
Subject*Free
Subject*free
当你这么做时,注意一定要把开头字母大写和所有字母大写以及所有字母小写这些情况一起考虑进去。垃圾邮件倾向含有更多祈使句式的句子,同时那些句子的第一个字是动词。所以开头字母大写的动词比所有小写字母的有更高的垃圾概率。我的过滤器里,“Act”的垃圾概率是98%,而“act”仅有62%。
当你提高过滤器的词汇量,你结果会把相同的单词算上多遍,――就你过去定义的“相同”而言。逻辑上讲,它们不再是同一个token了。不过如果你还是觉得不爽的话,那么从我的经验看来,这些你看着是被重复计算的词,倾向于刚好就是你想要重复计算的那些。
加大了的词库带来的另一个后果,是当你观察一个收到的邮件时,你会发现更多有趣的token,即概率远离0.5的那些。我用15个最关键词来决定一封邮件是否垃圾,不过,若是用这样一个固定的数字你会遇上困难。如果你发现很多极度有趣的token,那结果会是,你的结论被一些莫名其妙的随机事件所左右,是它们决定了这些同等关键的token的排列次序。对付这情况的方法是,把其中一些token看成比其他的更为关键。
举例来说,“dalco”这个token在我的垃圾邮件集中出现过3次,从未在合法邮件集中出现过。“Url*optmails”这个token(意思是“optmails”包含在某url中)出现了1223次。可当我计算token的概率时,这两个有相同的垃圾概率,0.99那个槛。
这感觉不大对。关于给予这两个token本质上不同概率(Pantel和Lin是这么干的)的问题,存在有理论依据,不过我还没试过。看上去至少得这样:如果我们发现有多于15个token只出现在这个或那个邮件集,我们就得优先考虑出现次数很多的那些。所以现在有两个槛值。对于只出现在垃圾邮件集的token,当它们出现超过10次时其概率时0.999,否则0.998。对相反方向那些只出现在合法邮件集的token,我们作同样处理。以后我大概会对概率进行实质上的权衡。不过以上这些微小份量的差别,至少确保了token整理的方向正确性。
另一个可能应该是不只考虑15个token,而是把所有token放在一个特定的有趣程度槛上进行衡量。Steven Houser在他的统计法邮件过滤器中是这么做的【8】。如果你用一个槛,就得把它弄得非常高,不然垃圾散发者会拿更多合法词汇充斥其邮件来瞒过你。
最后一点是,我们可以拿html怎么办?我试过所有可能的选择,从忽略它到对它作语法分析。忽略html不号,因为它充满了有用的垃圾邮件信号。但你若是对它作语法分析,你的过滤器会退化成光是一个html识别器。看来最有效的是中间方法,即注意一部分token而放过其他部分。我是查看img和font标签,而忽略别的。链接和图片自然是你应该看的,因为它们包含了url。
对付html,我大概能做的更聪明些,不过我不认为它值得花很多时间在上面。那些满是html的垃圾邮件很容易过滤,精明些的垃圾散发者早已避开了这个。所以未来的工作情况,不应决定于你是怎么对付html的。
自日,至日之间,我收到约1750个垃圾邮件,其中有4个被放过了。这个过滤率大概有99.75%。这四个溜掉的垃圾邮件中,有两个是因为它们刚好用了我合法邮件中常出现的词。
第三个是利用一个不安全的cgi脚本把邮件发给第三方的那种垃圾邮件。只基于内容它们很难过滤,因为台头清白并且用词谨慎。即便如此,我一般还是能抓住它们。这一个是以0.88的概率给溜了,刚好低过0.9的槛。
自然,若是用查看多重token序列方法应该能轻易抓住它。“Below is the result of your feedback form”立马就把它给卖了。
第四个则是我所谓“未来型”垃圾邮件,因为它正是我指望垃圾邮件会进化成的样子:一些全然是中性的文本,接着来一个url。在这里,它来自某个声称刚做完主页让我去看一眼的家伙(那个主页自然是一个黄色网站的广告)。
如果垃圾散发者小心台头,并且使用新鲜的url,那这种“未来型”垃圾邮件将没什么好引起过滤器注意的地方。我们当然可以放一个爬虫去其网站,进行反击,不过那未必是必须的。这种未来型垃圾邮件,它们的回应率一定很低,不然的话所有人都在用它了。若是低得足够的话,垃圾散发者干这个就会划不来,那么我们也就不需要花大力气来进行过滤了。
现在让我们来看真正令人震惊的消息。在这同样的一个月之内,我弄出了三个错纠邮件。
在某种程度上,错纠的存在是一种解脱。当我写《一个计划》时,我一个错纠都没碰上,于是就没法知道它们该长什么样儿。现在我有了几个。解脱的是,它们不像我担心的那么糟。统计方法过滤器所产生的错纠邮件,其实就是那些听上去特象垃圾邮件的家伙,并且倾向是你最不介意错过的那些。
错纠邮件中,有两个是我买过东西商家发来的新闻信。我从没要求过接受它们,所以有理由说它们也是垃圾邮件。不过我当它们是错纠,因为我从未把它们当垃圾邮件一样删掉过。过滤器捕获它们的原因是,这两公司都于1月份从发送自他们自己的服务器转成商业邮件发送了,并且它们的台头和主体都变得更垃圾化了。
第三个错纠却是一个坏例子。它来自埃及的某人,从头到尾都大写。这是把token设置得更敏感的直接后果。《一个计划》中用到的过滤器不过错抓住它。
难说总体的错纠率会有多高,因为统计上讲,我们身处噪音之中。任何致力于过滤器的人(至少是有效的过滤器),都会警觉于这个问题。有些邮件你压根说不好它们是不是垃圾,而当你把过滤器做得严格了,这些刚好就是你到头来得面对的邮件。举例说,迄今为止过滤器抓住了两个因拼写错误误发到我地址来的邮件,其中一个是把我当成另外什么人了。它们究竟是我的垃圾邮件还是非垃圾邮件,这可说不好。
另一个错纠邮件是来自Virtumundo的某个副总经理。我装成是他们的顾客写信过去,然后他们回信过来。因为回信是通过Virtumundo的服务器,其台头是你想象得出最可疑的那种。同样这算不算错纠也很难说,不过带点Heisenberg不确定性效应(译者注:Heisenberg Uncertainty Effect---“The more precisely the position is determined, the less precisely the momentum is known.”你的位置越明确,状态就越难料。):我收到它,只因我在写关于垃圾邮件过滤器的东西。
不算这些的话,我总计碰到过五个错纠邮件,在约7740个合法邮件中计0.06%。另外两个是我买的东西被back-order的同志,和一个来自Evite的聚会提醒。
我不认为这些数字是可信的,部分因为样本太小,部分因为我相信我可以修改过滤器,使它不再抓其中一些。
错纠对我来说,同错放使不同种类的差错。过滤率是用来测量工作情况的,错纠我则认为更象是bug。我把提高过滤率当作优化工作来做,而减少错纠就象是debug。
所以这五个错纠邮件就是我的bug清单。举例说,那个垃圾邮件的被抓,是因为大写字母使过滤器看它象一个Nigerian垃圾邮件。这确实是一种bug。跟html相似,一封邮件所有字母都大写,从概念上讲的确只是一个特征,而非每个单词都分别有一个特征。我得用更高明的手段处理这事。
那么,我们拿这0.06%怎么办呢?我没想太多。呢可以当它是一个上限,同时别忘了样本空间之小。不过就现阶段而言,这更多是一个对在我使用下贝叶斯过滤器所产生bug的测度,而不能算成是贝叶斯过滤器本质上的错纠率。
随后是什么?过滤是一个优化问题,而优化的关键是概括。别试着去猜你的代码在哪变慢,因为你会猜错。你得去观察,你的代码在哪走慢了,然后改进它。在过滤中,以上过程即是:观察你所错过的垃圾邮件,然后搞明白你的怎么做才能抓住它们。
例如,现在垃圾散发者们正主动运作,要避开过滤器,他们在做的一件事是,把单词分割或者拼错,这样来防止被过滤器识别。不过这方面的努力不是我的重点,因为我能不费力地抓住这种垃圾邮件【10】。
有两种垃圾邮件,是我现在感到麻烦的。一个是那种假装来自某个女人,邀你去跟她聊天,或者看她在什么黄色网站上的资料。这些能溜过过滤器是因为,它们是那种不需使用推销词汇的推销手段,并且它们用的全是我真实邮件里那些词。
另一种我不大好过滤掉的,是那些来自(例如Bulgaria)的某公司发来的提供编程服务合约的垃圾邮件。它们能通过,是因为我也是个编程员,并且那些垃圾邮件的用词跟我真实邮件的一个样儿。
我大概会先致力于个人广告类。我想要是再看仔细点儿,我应该能发现它们跟我真实邮件之间的统计学差异。文笔自然是不同的,哪怕得用到多重单词过滤法。而且,我注意到它们都倾向重复提及其url,而在合法邮件中提到url的人不大会这么干【11】。
境外合约那种垃圾邮件将不好对付。即便你往那网站发个爬虫,你也不会发现一杆冒烟儿的统计枪。也许唯一的解答是,弄一个现有垃圾邮件包含域名的主要列表【12】。不过这种邮件的数量多不至此。如果垃圾邮件就只剩下这些不请自来的Bulgaria来的编程服务合约的话,我们也许不妨都去忙点什么别的。
统计过滤法真能令我们走这么远么?我不知道。现在对我个人来说,垃圾邮件不是个问题。不过至今为止,垃圾散发者还未曾认真努力过来瞒过统计过滤器。要是他们这么做了,那会怎么样?
对网络层的过滤器,我不感觉乐观【13】。当有一个值得通过的静止不动的障碍物在那呆着,垃圾散发者可以相当有效地通过去。现在已经有一个名叫Assurance Systems的公司,专门把你的邮件放在Spamassassin下运行,然后告诉你它是否会被过滤掉。
网络层的过滤器也不是全没用。他们大概足以用来干掉所有“opt-in”的垃圾邮件,意即来自诸如Virtumundo或Equalamail等公司的,声称他们确实在使用opt-in清单的垃圾邮件。你可以光是基于台头就过滤掉那些家伙,不管他们在邮件主题说些什么。不过,任何人只有乐意伪造台头,或是使用开放型中继站,(可以想象大多数黄色垃圾散发者都会如此)那他们就应该能让一些邮件(值得一提的是,那不会是他们最想传递的邮件)通过网络层过滤器,只要他们想。
我持乐观态度的的,是那些基于每个用户个人邮件来计算概率的过滤器。它们可以更有效得多,不光是避免错纠,而且在过滤上也是如此。例如,在任何地方发现64位编码的接受者地址,就是一个很好的垃圾警报器。
不过,个人化过滤器的真正优点在于,它们个个都不一样。如果每个人的过滤器都有不同的概率数字,那会使垃圾散发者的优化系统――程序员称之为“编辑-编译-测试”循环――以惊人缓慢的方式打转。他们不能光是修改一个垃圾邮件使之能通过他们桌面上的某个过滤器,而是得就每次修改都做一下测试。这就像是在缺乏互动层面的基础上,用某个语言进行编程,我不指望任何人会喜欢干这个。
【1】 Paul Graham. 《一个关于垃圾邮件的计划》。2002年8月。/spam.html。
这个算法用的是一种简化贝叶斯法则来计算概率。有两个简化的假设:一是单个物体(单词)的概率是独立的,一是我们对一封邮件是垃圾的概率一无所知。
第一个假设在文本分类中很常见。这么做的算法叫做“幼稚的贝叶斯”。
第二个假设,我是基于我的日常垃圾邮件进项每天(事实上,每小时)都不一样的事实而提出的,因为这样一来,整体比例就压根不能用来当作预设。如果你假设垃圾的概率和非垃圾的概率都是0.5,那它们就相互抵消了,你就可以把它们从计算公式里整个扔掉。
如果是在垃圾与非垃圾比例持续性很高或者,尤其是很低的情况下做贝叶斯过滤器,那你大概能用加进预设概率的方法来提高工作情况。要想这么做,你得在一天的不同时候对比例进行跟踪,因为垃圾邮件和合法邮件有各自不同的日常作息。
【2】 Patrick Pantel和Dekang Lin。《SpamCop-A Spam Classification & Organization Program》。AAAI-98工作间在学会文本归类方法之后。
【3】 Mehran Sahami,Susan Dumais,David Heckerman和Eric Horvitz。《A Bayesian Approach to Filtering Junk E-mail》。AAAI-98工作间在学会文本归类方法之后。
【4】 那时我在4000封合法邮件中没有一个错纠。如果下一个合法邮件被错纠,那结果会是0.03%。正如我后来指出的,这些错纠率不可信。我在这里引用这个数据,只是位了说明不管错纠率会是多少,它是小于1.16%的。
【5】 Bill Yerazunis。《Sparse Binary Polynomial Hash Message Filtering and the CRM114 Discriminator》。2003垃圾邮件大会之后。
【6】 在《一个计划》中,我用了0.99和0.1的槛。把槛设得跟邮件集的大小成比例应该是有道理的。因为我现在两种邮件都用10,000个做邮件集,现在的槛是0.1了。
【7】 这里有一个毛病是我大概应该修改的。现在情况是,当“Subject*foo”退化成“foo”时,这意味着你获取的是“foo”出现在我标记的那5个部分之外的主题或台头中的统计数字。我应该把“foo”这个词的总体出现情况以及特殊情况都记录下来,然后把“Subject*foo”退化成“Anywhere*foo”而不是“foo”。同样的,我应该把字母大写退化成所有形式,而不是字母小写。
用这个方法来对付价钱应该也是好的,好比,“$129.99”退化成“$--9.99”,“-$--.99”,和“$--”。
你还可以把单词退化成它们的一般形式,不过这当你使用小型邮件集时大概只能提高一开头的过滤率。
【8】 Steven Hauser。《Statistical Spam Filter Works for Me》。&.
【9】 错纠并不都等价,我们在比较各种针对垃圾邮件的技术时,应当记住这点。不光有那些近乎垃圾邮件的你不在乎丢失的错纠邮件,还有一些别的,好比因黑名单而造成的错纠,那只是些别人发给你的正常邮件,因为他们使用了错误的ISP而被丢失了。这两种情况下你都时抓住了“约等于”垃圾的邮件,不过对黑名单来说,这个“约等于”是物理意义上的,而对过滤器来说这是文本意义上的。
不过公平地说,象SBL这种值得信赖的新生代黑名单,它所造成的错纠,要比早期像MAPS RBL这种黑名单要少得多多,因为早期黑名单造成一大堆错纠,不过是它想要引起公众对ISP的注意的一种故意手段。
【10】 如果垃圾散发者改进到能用这种混淆token的方法制造出大麻烦,我们可以简单删除空格,句号,逗号等,来进行反击,并且可以用一个词典来把单词从得到的序列中给找出来。当然了,把这种隐藏在文本中的单词找出来,这事本身就是垃圾邮件的一个证据。
这种找词不会是简单的。它需要比重组单词边界更多的东西;垃圾散发者添加(“xHot nPorn cSite”)并且省略(“P#rn”)这些词。视觉研究在这里大概会有用处,因为人类视觉正是这些诡计所能尝试的极限。
【11】 一般来说,垃圾邮件的重复率要比普通邮件为高。他们想使他们的信息一步到位。现在我并不准许15个头号token中有重复,因为要是发送者刚好把什么坏词用上多遍,那就会导致错纠。(在我现有的过滤器中,“dick”的垃圾概率有0.9999,可它同时也是个人名。)不过看来我们至少得对重复提起注意,所以我大概会尝试,对每个token允许至多两遍的重复,正如Brian Burton在SpamProbe里做的那样。
【12】 这是一旦垃圾散发者被迫使用mad-lib技术来生成文件中的所有其他文本,像Brightmail那样的方法将退化成的样子。
【13】 争议是,我们是否应该致力于网络层的过滤器,因为它更有效。当人们这么说的时候,他们的意思一般是:我们已经在网络层有过滤器了,就不想再从底层开始。不过问题是,你不能为了支持你的解决方案而窜改题目。
历史上说,在软件设计上总是小规模那方失败。人们倾向于做的,是为使其他理由下作出的选择(特别是不动的选择)名正言顺而使用它们。
感谢Sarah Harlin, Trevor Blackwell, Dan Giffin阅读此文手稿,并且再次感谢Dan打造这个过滤器赖以工作的大部分基础。
P=(0*1)/[0*1+(1-0)*(1-1)]=0
由此可推出该邮件为非垃圾邮件
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:133075次
积分:1927
积分:1927
排名:第16220名
原创:53篇
转载:80篇
评论:28条
(1)(1)(1)(2)(1)(3)(1)(1)(3)(1)(4)(11)(7)(4)(6)(5)(8)(5)(4)(18)(5)(9)(2)(8)(6)(16)

我要回帖

更多关于 excel表格常用技巧大全 的文章

 

随机推荐