bogofilter notes

naive贝叶斯

前提假设:邮件中出现的各个词之间完全独立、不相关。

【前提假设未必正确但此模型效果很好】

(贝叶斯公式)

上式左端理解为F1, F2,,,,Fn同时出现时, 属于类别C的概率。

式中分子就是

根据前提假设F之间独立,因此

p(Fi|C, Fj)理解为当Fj出现在类别C中时,Fi的条件概率

因此判别由单词F1,,,Fn构成的待识别邮件属于哪个类, 可以求使得上式最大的C即可

当只有两类:垃圾邮件C1、正常邮件C2时,可以直接计算p(C1|F1,F2,,,Fn)p(C2|F1,F2,,,Fn)

http://en.wikipedia.org/wiki/Naive_Bayes_classifier

 

在使用贝叶斯实现bogofilter中, 只需要求p(垃圾类|待识别邮件)

对应的,C就表示垃圾类别; p(C)就表示垃圾样本数/总样本数, p(Fi|C)表示第i个词出现在垃圾邮件样本中的概率。

如果计算得到的p很大,超过spam_cutoff就认为是垃圾邮件.

robinson-fisher算法改进

robinson-fisher算在在传统naïve bayes的基础之上逐步做了如下几点改进:

1 使用f(w)代替p(w):

p(w)表示w在垃圾邮件中出现的概率(就是p(Fi|C));使用fw代替pw

pw = ((bad / badmsgs) / (bad / badmsgs + good / goodmsgs));

假设ham10 spam20

wham中出现4 good

wspam中出现2bad

那么pw就是0.2

fw计算公式:

    (s * x) + (n * p(w))
f(w) = --------------------
              s + n 

sx都是robinson系数robs,robx; nw出现的总次数

#define ROBS        0.0178  /* Robinson's s */

#define ROBX        0.52    /* Robinson's x */

这两个值可以使用bogofilter根据我们的样本库来得到推荐值。

 

对应bogofilter的代码如下:

//good表示w出现在ham中的次数,bad则为在spam中的次数  

uint n = good + bad;

fw = (robs * robx + n * pw) / (robs + n);

//src/score.c

 

2 robinson改进贝叶斯链的计算公式

贝叶斯链就是计算

C表示垃圾邮件类别; 当该值大于spam_cutoff时就认为是垃圾邮件

 

 

robinson改进

P = 1 - ((1-p1)*(1-p2)*...*(1-pn))^(1/n)     [spamminess]
Q = 1 - (p1*p2*...*pn)^(1/n)                 [non-spamminess]
S = (P - Q) / (P + Q)                        [combined indicator]

S代表待识别邮件属于垃圾邮件的概率。(p1, p2, p3表示邮件中出现的单词在垃圾邮件中的概率;实际bogofilter使用了第一个改进得到的fw代替pi

 

((1-p1)*(1-p2)*...*(1-pn))^(1/n), (p1*p2*...*pn)^(1/n) 表示开n次方,称作robinson geometric mean, robinson几何均值

 

S介于[-1,1]之间,可做线性处理成S =  (1 + (P - Q) / (P + Q))/2

3 fisherP, Q,S的求法做了改进

如上P, Q, S的计算公式

改进之后的计算公式://src/score.c : get_spamicity

Fisher's method uses an inverse chi-squared function, prbx, to get the probability associated with -2 times the sum of the logs of f(w) with 2n degrees of freedom:
P = prbx(-2 * sum(ln(1-f(w))), 2*n)
Q = prbx(-2 * sum(ln(f(w))), 2*n)
S = (1 + Q - P) / 2
 
 
Prbx, 就是函数gsl_cdf_chisq_Q(double x, double k), 计算k个符合标准正态分布的随机变量之和x cummulative distribution(累积分布函数):
因此,prbx的作用就是下图式中以第1个参数为横坐标x, 第2个参数为k,得到其纵坐标
 

 
http://en.wikipedia.org/wiki/Chi-square_distribution
http://linux.math.tifr.res.in/manuals/html/gsl-ref-html/gsl-ref_16.html
 
code:(代码中的prbf就是上文中的prbx)
score.p_pr = prbf(-2.0 * score.p_ln, sp_df);         /* compute P */
score.q_pr = prbf(-2.0 * score.q_ln, ns_df);         /* compute Q */
score.spamicity = (1.0 + score.q_pr - score.p_pr) / 2.0;
 
prbx作用同算术均值,几何均值类似, 是一种更复杂的统计推断方式:假设已有k个独立、符合标准正态分布的随机变量之和为x,推断这k个随机变量同时出现时这个标准正态分布函数的累积分布值,也就是属于垃圾邮件的概率】
 
 
 
 

4 优点/比较

http://www.bgl.nu/bogofilter/BcrFisher.html
          改进1,2              改进1,2,3         Naïve bayes
Robinson-geometric-mean  Robinson-Fisher  Bayes Chain Rule
           ---                  ----              --------
          /                    /                  |
         /                    |                   |
        /                     |                   |
       /                      |                   |
      /                       |                   |
     /                       /                    |
  ---                    ----              --------
图中值均介于[0,1]之间, 为1表示肯定是垃圾邮件,为0表示是正常邮件。
使用样本对检验上述三个算法效果图如上。
第一个图中[0, 0.55]被识别为正常邮件, [0.45, 1]被识别为垃圾邮件, 存在交集, 甚至无法选择合适的spam_cutoff
第三个图中绝大部分值都是0或者1if a mistake is made, the algorithm leaves almost no room to express doubt.【如果训练样本中存在无间道, 将对识别结果造成很大影响】
第二个图【现有bogofilter按此实现】没有第一、三的缺点。绝大多数spam得分接近1, 绝大多数ham得分接近0 [0.1, 0.9]之间为unsure,可以在其中选择一个合适的阀值,spam_cutoff in [0.93, 0.98]
 
 

上图是比较naïve bayesbcr bayes chain rule,  使用fw替代pwnaïve bayes, 以及robinson-fisher的测试结果图

 

【使用robinson-fisher效果最好:

http://www.bgl.nu/bogofilter/BcrFisher.html

http://www.bogofilter.org/pipermail/bogofilter/2002-November/000699.html

Bogofilter 现版本使用了robinson-fisher算法计算一封邮件属于垃圾邮件的概率

 

5 改进的理由/讨论

1 fw代替pw fw包含了background info

Pw的含义是任意一封邮件包含单词w时, 此封邮件是垃圾邮件的概率;

fw是如下二项式分布的数学期望值:已知单词w出现了n次,在已有垃圾邮件中出现的概率是pw;那么第n+1次出现这封邮件时垃圾邮件的概率是多少【这个就是所谓的fw结合了backgroud info 因为每次出现w时只有两种结果,垃圾邮件、非垃圾邮件; 且每次出现独立不相关的,所以符合二项式分布; fw就是上述所求概率的期望】

http://www.linuxjournal.com/article/6467

 

2 使用P, Q, S代替bayes chain rules

Bayes chain rules把各个词的出现看做是独立的来计算这些词同时出现时的垃圾概率【理想世界】

P, Q, S计算的是这些词combined起来计算 probability

 

bogofilter基本用法

训练

bogofilter -B ../sample_mail/non_spam_test/* -n -o0.00,0.99 -k 64 -d ./wordlist

-B 指明文件列表

-n 表示为正常邮件

-ospam_cutoff[,hamcutoff]

-k 指明BDB文件的大小

-d 指明wordlist所在目录

./wordlist下的BDB文件作为内容特征输入; 训练完毕后./wordlist下的文件同时会被更新

不需要指明-u参数, 上述语句本身就是增量式训练;

 

bogofilter -B ../sample_mail/non_spam_test/* -Ns -o0.00,0.99 -k 64 -d ./wordlist

将已训练过的、non_spam_test下的邮件, 作为垃圾邮件重新训练。

-N, unregister non-spam

-s, register-spam

 

 

bogofilter中查看bdb文件:

bogoutil -d wordlist

 

 

bogofilter分类:

bogofilter –B path –v –ov1[,v2] –d wordlist ; 从该命令行中输出分析结果

 

说明

two state  -o0.99,0.00 只分两类, spam, ham
hamcutoff = 0 spamcutoff = 0.99,
得分大于0.99为垃圾邮件, 低于0.99为正常邮件

tristate  -o0.99,0.8:
分三类, spam, unsure, ham

hamcutoff = 0.8 spamcutoff = 0.99, 得分大于0.99为垃圾邮件, 低于0.8为正常邮件, (0.8, 0.99)之间判定为unsure

 

robx 对于新词给的预定概率: 初始值为0.5,表示该词出现在垃圾邮件中的概率是0.5
robs
低于该阀值的作为新词对待

 

 

SP_ESF, effective size factor(ESF) from spam
NS_ESF, effective size factor(ESF) from nonspam
bogofilter
中默认值均为1.0

 

垃圾邮件识别有两种错误:

False negative(fn), 将垃圾邮件识别为非垃圾邮件;漏报

False positive(fp), 将非垃圾邮件识别为垃圾邮件; 误报

bogotune 推荐参数

n=·ls nonspam | gawk {s = sprintf(“ %s –n %s”, s, $NF);}END{print s}·

Bogotune –C –d wordlist $n $s

 

 

config file中需要指定ignore file 包含停用词、无关词等

你可能感兴趣的:(Algorithm,c,算法,function,File,express)