当前位置:文档之家› 基于贝叶斯算法的JavaMail垃圾邮件过滤实现

基于贝叶斯算法的JavaMail垃圾邮件过滤实现

基于贝叶斯算法的JavaMail垃圾邮件过滤实现刘岚,贾跃伟武汉理工大学信息工程学院,武汉(430070)E-mail: simon_jia_2005@摘要:JavaMail 在中小型企业的邮件系统中有着广泛的应用,谨以贝叶斯算法为基础,提出并实现一套简单,高效的自适应垃圾邮件的过滤方案。

它采用基于词熵的特征提取方法,在过滤的过程中不断的进行自学习,具有较强的自适应能力,最终通过阈值来判别邮件是否为垃圾邮件。

关键词:JavaMail;贝叶斯算法;垃圾邮件;自学习1.引言JavaMail是Sun发布的处理电子邮件的应用程序接口,预置了常用的邮件传送协议(如SMTP、POP、IMAP、NNTP)的实现方法,与JSP和QMAIL 结合开发出稳定可靠的企业级web mail系统,可以满足中小型企业的日常办公需求。

但目前这种办公邮箱最大的困扰是来自internet的大量以广告为目的垃圾邮件,尤其是在网站上对外公布的邮箱,其垃圾邮件的比例甚至达到了90%以上,日平均有20封以上的垃圾邮件,对邮箱使用造成了很大的不便,这是邮箱系统的开发和维护首要解决的问题。

2.反垃圾邮件过滤技术2.1 基于黑白名单的过滤技术此技术使用最早也最为常用,即是对于地址在白名单的服务器的邮件全部接收,对地址在黑名单的服务器的邮件全部拒收,国际和国内的一些反垃圾邮件组织会实时更新和提供一种实时的黑名单(Real Time Black List)的邮件服务器IP数据库,简称RBL,任何邮件服务器都可以订阅RBL以达到过滤垃圾邮件的目的[1]。

但这种方法缺点很也很明显:处理陌生邮件无能为力;需要不断更新和维护;效率不高容易误判。

2.2 基于加密信息的过滤技术加密信息过滤技术主要是采用类似于公钥密码的一类方法,主要目的是对邮件发送者进行验证,防止目前泛滥的伪造域名和木马发送,域名密钥体制利用公钥技术和DNS构建一个域名层次的电子邮件来源和内容认证框架,简单的讲,即为发送邮件时候同时产生密钥和公钥,密钥跟随邮件,收件服务器从密钥中获取签名和域名,然后通过网络公钥验证通过后完成邮件的发送。

此种方法的缺点也显而易见,即使得邮件的网络传递负担加重,同时缺乏大规模的认证标准,使得目前阶段难以大范围的推广。

2.3 基于规则和统计的过滤技术规则是指预设垃圾邮件关键词进行的邮件过滤,而其最大的缺点是实效性较差,不易维护,垃圾邮件往往通过关键词中增加特殊符号来躲避规则,同时也会使过滤缺乏弹性。

而贝叶斯过滤算法是一种典型的基于统计的垃圾邮件过滤技术,这种理论的基础是通过对大量垃圾邮件的常见关键词进行分析后得出其分布的统计模型,并由此推算目标是垃圾邮件的概率,再根据所设阈值来判断是否接受邮件,它最大的特点是自学习功能,不断的自我更新过滤规则,保证了不需维护即可获得长期稳定的过滤效率。

但贝叶斯算法其缺点也同样明显,它同时需要一定量的垃圾邮件数据库完成初始自学习过程,同时需要用来匹配的大量的汉字和英文单词样本库,而且对于基于JavaMail 中小型规模的企业邮件服务器,其初始大量的自学习过程所耗费的系统资源是办公环境无法忍受的,基于此,本文将结合规则过滤的优点,将两个种方法进行互补的整合,在初始预设一定规则的情况下,由贝叶斯算法所实现的模块完成对垃圾邮件的判断并且不断的通过自学习功能对规则进行完善和修改,以达到自我维护的目的。

3. 贝叶斯过滤算法推理根据贝叶斯公式[5]:1(|)()(|)(|)()i i j jj P A B P B P B A P A B P B ==∑把两种邮件看作是两个随机事件A 、B ,其中A 为垃圾邮件,B 为正常邮件,是全部自学习E 的样本空间S 的全部随机事件。

T 为邮件单词的集合,其中i T 为T 的元素。

根据贝叶斯公示有:(|)*()(|)(|)*()(|)*()i i i i P T A P A P A T P T A P A P T B P B =+ 而样本空间中垃圾邮件的数量与正常邮件相当,故()()0.5P A P B ==,又令()(|)A i i f T P T A =、()(|)B i i f T P T B =,由此推导出由一个单词的出现的情况下,判断邮件是否为垃圾邮件的概率:()(|)()()A i i A iB i f T P A T f T f T =+ (公式3.1) 当拒收关键词列表学习完毕,在多关键词过滤的情况下,由合并概率公式(Combining Probabilities )可得:1211211(|)*(|)*.....(|)(|,...,)[(|)*(|)*.....(|)][(1(|))*(1(|))*......(1(|))]n n n n n P A T P A T P A T P A T T P A T P A T P A T P A T P A T P A T −=+−−− (公式3.2) 由此,我们很容易算出所收到邮件时垃圾邮件的概率,再根据所设阈值判定是否为垃圾邮件。

4. 本算法实现的JavaMail 环境本次是实现的贝叶斯算法的JavaMail 系统逻辑架构如下图所示:图1 JavaMail服务器系统架构图但由于是中小企业级邮件系统,数据库服务器没有专门配置,而是将邮件,和配置文件数据一起存放在应用服务器上,邮件文件存放在根目录下的domain文件夹中。

5.贝叶斯过滤算法的java实现贝叶斯过滤算法在企业应用的邮件系统的具体实现中,会遇到以下几个关键问题:关键字表单等数据的存储问题;邮件箱中大量邮件的读取;收邮件的同时邮件内容解码分析的问题;对邮件内容进行关键词的遍历比较并进行自学习。

下面便分别实现上述功能:5.1 关键字表单数据的存储问题由于本系统是中小型企业的邮件服务器,所以并未使用大型的数据库如:oracle等,而是采用xml文件的形式进行数据的存储,它的优点是系统架构简单,便于修改和维护[3]。

import org.dom4j.document;import org.dom4j.Element;import org.dom4j.Element;//完成对xml文件的操作需要org.dom4j 的开发包this.m_FileName = pPath + "/" + Domain + "/" + Name + "/Config.xml" ;doc = DocumentHelper.parseText("<root/>");OutputFormat format = OutputFormat.createPrettyPrint(); //格式化输出format.setEncoding("GBK"); //指定XML编码writer = new XMLWriter(new FileWriter(new File(pFileName)), format);El =Root.addElement("Filter"); //增加“Filter”的节点El.setText("");// 完成对xml文件的创建El = (Element)doc.selectSingleNode("root/Filter");this.Filter = El.getText();//完成对xml文件的读取5.2 邮箱中大量邮件的读取由本文第四部分可知,本系统的邮件文件的存储是放在根目录下的文件夹中。

import java.io.FileInputStream;File f = new File(BoxDir); File[] files = f.listFiles();// BoxDir 为邮件所存放文件夹的路径,如:“/maildir/inbox”for (int i = files.length-1; i >= 0; i--) {FileInputStream in = new FileInputStream(files[i]);}//这样变利用java.io的fileinputStream将所有邮件从文件夹中循环的读入内存5.3 收邮件并对邮件内容进行解码分析由于邮件发送是根据SMTP(Simple Mail Transfer Protocol)协议,而smtp服务器只能接受7bit字节流,所以要根据MIME(Multipurpose Internet Mail Extensions)协议将邮件内容进行编码,所以再解码端也要对应的将信件内容的格式作出判断,如图1:图 2 MIME解码过程示意图import javax.mail.* ;Store store = mailsession.getStore("pop3");store.connect(pop3Server, userName, password); //利用pop3协议和账户,密码连接服务器Folder folder = store.getFolder("INBOX");folder.open(Folder.READ_WRITE); //打开收件箱文件夹Message message[] = folder.getMessages();//通过以上几个步骤,已经把邮件从服务器中收到系统中。

for (int i = 0; i < message.length; i++){ String ContentString = new String();Object object = message[i].getContent(); //获得邮件内容if ( message[i].isMimeType("text/plain")|| message[i].isMimeType("text/html")){ ContentString=" "+(String)object+" ";} //判断是否为“text/html”if ( message[i].isMimeType("multipart/*")){ Multipart mp = (Multipart)object; //判断是否为 “Multipart”for (int j = 0; j < mp.getCount(); j++) {ContentString =ContentString+"\t"+ mp.getContent (); //将所有邮件内容放入一个字符串 }//邮件内容分析完毕5.4 根据规则对邮件样本进行遍历自学习由第2节可知,鉴于实用资源和效率的考虑,本模块将预设一定的规则。

相关主题