贝叶斯算法应用于反垃圾邮件

对抗垃圾邮件的技术有很多,今天学习的贝叶斯算法属于一种机器学习领域的技术。这是一种分类算法,根据贝叶斯原理来计算邮件可能是垃圾邮件的概率,如果高于阈值,就认为这是垃圾邮件。其判断的准确程度随着学习次数的增加而增加,这就需要以已知的邮件作为样本进行学习,因此贝叶斯方法常会和其他垃圾邮件检测技术相配合。

贝叶斯过滤算法的基本步骤
1. 利用其他技术收集大量的垃圾邮件和非垃圾邮件,建立垃圾邮件集和非垃圾邮件集。

2. 提取邮件主题和邮件体中的独立字符串,英文可以以一个单词、中文可以以一个汉字或者词语作为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 ) = P(A,ti)/P(ti) = P2 ( ti ) /[ ( P1 ( ti ) +P2 ( ti ) ]

6. 建立新的哈希表hashtable_probability存储TOKEN串ti到P(A|ti)的映射。

7. 至此,垃圾邮件集和非垃圾邮件集的学习过程结束。之后根据建立的哈希表 hashtable_probability可以估计一封新到的邮件为垃圾邮件的可能性。

8. 当新到一封邮件时,按照步骤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) 超过预定阈值时,就可以判断邮件为垃圾邮件。

算法举例
假设有2封正常邮件e1、e2和2封垃圾邮件e3、e4,test作为测试用的邮件。我写的下面这个程序的一个缺陷就是使用一个汉字作为一个TOKEN串,而不是先采用中文分词算法以词语作为TOKEN串。所以只是作为贝叶斯算法的实现例子,实用价值并不大。

[python]  view plain copy
  1. #coding=utf-8  
  2. from __future__ import division  
  3. import sys  
  4. reload(sys)  
  5. sys.setdefaultencoding('utf8')  
  6. exlist = ['\n',',','。','!','?','1','2','3','4','5','6','7','8','9','0']  
  7. word = ''  
  8. bad_file = ['e1','e2']  
  9. good_file = ['e3','e4']  
  10. #######################################################Learning  
  11. for name in good_file:  
  12.         f = file(name)  
  13.         ch = f.read()  
  14.         ch = unicode(ch, 'utf-8')  
  15.         for i in range(len(ch)):  
  16.                 if ch[i] in exlist:  
  17.                         continue  
  18.                 else:  
  19.                         word += ch[i]  
  20.         f.close()  
  21. #print 'Word\'s Num:',len(word)  
  22. #print word  
  23. ##############compute prequency  
  24. good_dict = {}   
  25. for i in range(len(word)):  
  26.         le = word[i]  
  27.         if good_dict.has_key(le):  
  28.                 good_dict[le] += 1  
  29.         else:  
  30.                 good_dict[le] = 1  
  31.   
  32.                   
  33. for k in good_dict.iterkeys():  
  34.         good_dict[k] = good_dict[k] / len(good_dict)  
  35.   
  36. print '####################################'  
  37. print 'Good Email Hash:'  
  38. for k in good_dict.iterkeys():  
  39.         print k,' : ',good_dict[k]  
  40.   
  41. ######################################################  
  42. word = ''  
  43. for name in bad_file:  
  44.         f = file(name)  
  45.         ch = f.read()  
  46.         ch = unicode(ch, 'utf-8')  
  47.         for i in range(len(ch)):  
  48.                 if ch[i] in exlist:  
  49.                         continue  
  50.                 else:  
  51.                         word += ch[i]  
  52.         f.close()  
  53. #print 'Word\'s Num:',len(word)  
  54. #print word  
  55. ##############compute prequency  
  56. bad_dict = {}   
  57. for i in range(len(word)):  
  58.         le = word[i]  
  59.         if bad_dict.has_key(le):  
  60.                 bad_dict[le] += 1  
  61.         else:  
  62.                 bad_dict[le] = 1  
  63.   
  64. for k in bad_dict.iterkeys():  
  65.         bad_dict[k] = bad_dict[k] / len(bad_dict)  
  66.   
  67. print '####################################'  
  68. print 'Bad Email Hash:'  
  69. for k in bad_dict.iterkeys():  
  70.         print k,' : ',bad_dict[k]  
  71.   
  72.   
  73. ###########################################################Hashtable_probability  
  74. proba = {}  
  75. for le in bad_dict.iterkeys():  
  76.         if good_dict.has_key(le):  
  77.                 proba[le] = bad_dict[le] / (bad_dict[le] + good_dict[le])  
  78.         else:  
  79.                 proba[le] = 1  
  80. print '####################################'  
  81. print 'Probability Hash:'  
  82. for k in proba.iterkeys():  
  83.         print k,' : ',proba[k]  
  84. ############################################################Test a new email  
  85. f = file('test')  
  86. word = ''  
  87. ch = f.read()  
  88. ch = unicode(ch, 'utf-8')  
  89. for i in range(len(ch)):  
  90.         if ch[i] in exlist:  
  91.                 continue  
  92.         else:  
  93.                 word += ch[i]  
  94. f.close()  
  95.   
  96. pr = [ 0 for i in range(len(word)) ]  
  97. j = 0  
  98. for i in range(len(word)):  
  99.         if proba.has_key(word[i]):  
  100.                 pr[j] = proba[word[i]]  
  101.         else:  
  102.                 pr[j] = 0  
  103.         j = j + 1  
  104.           
  105. p1 = 1  
  106. p2 = 1  
  107. for i in range(len(pr)):  
  108.         p1 =  p1 * pr[i]  
  109.         p2 =  p2 * (1 - pr[i])  
  110.   
  111. probability = p1 / (p1 + p2)  
  112. print '########################################'  
  113. print 'probability: ',probability  

你可能感兴趣的:(贝叶斯算法应用于反垃圾邮件)