朴素贝叶斯分类器原理与应用

贝叶斯公式

$$
P(c | x)=\frac{P(c) P(x | c)}{P(x)}=\frac{P(x, c)}{P(x)}
$$
其中:

  • P(c|x)是后验概率,一般是我们求解的目标。表示当拥有x这个条件后c的概率;
  • P(x|c)是条件概率,注意它也是后验概率,但是在计算贝叶斯公式时是已知量。
  • P(c)是先验概率,它表示我们对一个随机变量概率最初的认识,一般都是人主观给出的。
  • P(x)其实也是先验概率,只是在贝叶斯公式中往往被认为是已知的,因此它一般被当做一个常量看待。
  • P(x,c)是联合概率,即x和c同时发生时的概率。

在朴素贝叶斯分类器中,P(c|x)通常表示P(类别|特征)。
其中特征x可以是一个向量,即有很多个特征:
$$
X=(x_{1}, x_{2}, x_{3}, \dots, x_{n})
$$
同理,c也可以是一个向量。

属性条件独立性假设

朴素贝叶斯分类器之所以称为为”朴素”,是因为采用了属性条件独立性假设:即假设每个属性独立地对分类结果发生影响。
如果假设X中各个属性是独立的,那么p(c|x)可写为:
$$
P(c | x)=\frac{P(c) P(x | c)}{P(x)}=\frac{P(c)}{P(x)} \Pi_{i=1}^{d} P(x_{i} | c)
$$
其中
$$
p(x)=P(x_{1}) P(x_{2}) \ldots P(x_{n})
$$
也就是说,只要应用了属性条件独立性假设,那么条件概率p(特征集合|类别)就可以拆成在类别这个条件下每一个特征的条件概率的乘积。
由于对于不同的p(c|x),分母p(x)是常量均相同,与类别c无关,故我们计算c的各种取值的可能性时并不会对各结果的相对大小产生影响,因此可以忽略。

朴素贝叶斯分类器

假设特征集合为x,类别集合为c。

朴素贝叶斯分类器公式

我们由训练集可以计算出所有p(c)类别概率和p(x|c)以类别为条件下特征的概率,由
$$
P(c | x)=\frac{P(c) P(x | c)}{P(x)}=\frac{P(x,c)}{P(x)}
$$
可以求出p(x,c)联合分布概率,这种模型称为生成模型。所以我们说贝叶斯分类器是生成模型。
由于属性条件的独立性假设,各个特征的p(x)的值应当是一个常量(虽然我们不知道具体是多少),而且p(x)在训练集和测试集上应当一致,因此我们可以省略上式的分母。
朴素贝叶斯分类器公式:
$$
h_{nb}(x)=\underset{c \in \mathcal{Y}}{\arg \max } P(c) \prod_{i=1}^{d} P(x_{i} | c)
$$
贝叶斯分类器即用p(c)和p(x|c)来计算p(c|x),计算时不除以分母,通过比较测试样本的每个类别的p(c|x)大小,确定测试样本最有可能属于哪个类别。
注意我们的深度学习模型如lr最终所求的也是p(c|x),但是因为它们是直接求p(c|x),而不求p(x,c),所以被称为判别模型。

离散属性与连续属性值的分别处理

在估计条件概率时,若特征为离散值,那么我们只需计算每个特征取值的样本数量占每个类的训练样本数量的比值:
$$
P\left(x_{i} | c\right)=\frac{\left|D_{c, x_{i}}\right|}{\left|D_{c}\right|}
$$
Dc表示训练集D中第c类样本组成的集合,外加两条竖线表示的是集合的元素数量。Dc,xi表示在属于类别c的样本中,第i个特征值上取值为xi的样本组成的集合。

若特征为连续值,我们就得用概率密度函数。

这里以高斯分布为例,假设xi服从高斯分布,基于这个分布,我们就可以构造一个高斯朴素贝叶斯分类器。
若有
$$
p\left(x_{i} | c\right) \sim \mathcal{N}\left(\mu_{c, i}, \sigma_{c, i}^{2}\right)
$$

$$
P\left(x_{i} | c\right)
$$
的概率密度函数为:
$$
p\left(x_{i} | c\right)=\frac{1}{\sqrt{2 \pi} \sigma_{c, i}} \exp \left(-\frac{\left(x_{i}-\mu_{c, i}\right)^{2}}{2 \sigma_{c, i}^{2}}\right)
$$
这样根据测试样本的各个特征值的取值,我们计算出每个特征值的p(xi|c),就可以计算一个测试样本对每个类别ci的p(ci|x),即样本在各个特征值取值确定的条件下,属于某个类别ci的概率。仍然是下面这个公式:
$$
h_{nb}(x)=\underset{c \in \mathcal{Y}}{\arg \max } P(c) \prod_{i=1}^{d} P(x_{i} | c)
$$
计算出对每个类的h(x)值,最终取最大值对应的那个类作为这个测试样本的类预测结果。
计算实例见西瓜书P151-P153页。

拉普拉斯修正

如果某个特征是离散值,且有一个特征值的取值在训练集中没有与某个类同时出现过,那么当我们使用对其进行估计时,P(xi|c)会等于0。这时如果再用朴素贝叶斯分类器公式
$$
h_{nb}(x)=\underset{c \in \mathcal{Y}}{\arg \max } P(c) \prod_{i=1}^{d} P(x_{i} | c)
$$
进行判别时,若某个测试样本在属性i上恰好取值为xi,但是它其它的属性非常符合这个类型c的特征,于是在用最后的连乘式计算该样本属于该类的概率时,不管其它的属性如何取值,就会因P(xi|c)=0这一个零值导致分类器认为该样本属于这个类型c的概率为0,这显然是不合理的。
为了避免这个问题的出现,我们通常还是在估计概率值时,对其进行”平滑”(smoothing)操作,通常使用”拉普拉斯修正”(Laplacian correction)。
具体做法:
令N表示训练集D中可能的类别数,Ni表示第i个属性可能的取值数,那么我们估计类别概率值的P(c)和离散属性条件概率的p(xi|c)的两个公式分别被调整为:
$$
\hat{P}(c)=\frac{\left|D_{c}\right|+1}{|D|+N}
$$
$$
\hat{P}\left(x_{i} | c\right)=\frac{\left|D_{c, x_{i}}\right|+1}{\left|D_{c}\right|+N_{i}}
$$
即我们在分母上都加上取值的可能性个数,分子上都加1,这就保证了即使是存在某个属性i的取值xi未曾与类别ci同时出现过,我们也不会把其概率P(xi|c)算成0。
其余计算步骤与朴素贝叶斯分类器相同。
拉普拉斯修正避免了因训练集样本不充分而导致概率估值为零的问题,并且在训练集变大时,修正过程所引入的先验(prior) 的影响也会逐渐变得可忽略,使得估值渐趋向于实际概率值。

朴素贝叶斯分类器的应用:贝叶斯垃圾邮件过滤器

论文:A plan for Spam
论文地址:http://www.paulgraham.com/spam.html
论文:Better Bayesian Filtering
论文地址:http://www.paulgraham.com/better.html
我们假定新邮件是垃圾邮件的概率为50%。(有研究表明,用户收到的电子邮件中,80%是垃圾邮件。但是,这里仍然假定垃圾邮件的”先验概率”为50%)
用S表示垃圾邮件(spam),H表示正常邮件(healthy),于是有:
$$
P(S)=P(H)=50 \%
$$
现在我们对这封邮件进行解析,发现其中包含了sex这个词,请问这封邮件属于垃圾邮件的概率有多高?
我们用W表示”sex”这个词,那么问题就变成了如何计算P(S|W)的值,即在某个词语特征(W)已经存在的条件下,该邮件属于垃圾邮件S的概率有多大。
根据条件概率公式,可以写出:
$$
P(S | W)=\frac{P(W | S) P(S)}{P(W | S) P(S)+P(W | H) P(H)}
$$
P(W|S)和P(W|H)的含义是,这个词语在垃圾邮件和正常邮件中,分别出现的概率。这两个值可以从历史资料库中得到,对sex这个词来说,上文假定它们分别等于5%和0.05%。另外,P(S)和P(H)的值,前面说过都等于50%。
我们可以计算出P(S|W)的值:
$$
P(S | W)=\frac{5 \% \times 50 \%}{5 \% \times 50 \%+0.05 \% \times 50 \%}=99.0 \%
$$
因此,这封新邮件是垃圾邮件的概率等于99%。这说明,sex这个词的推断能力很强,将50%的”先验概率”一下子提高到了99%的”后验概率”。
计算了上面对sex这个词的p(s|w)后,我们能否确定这封邮件就是垃圾邮件呢?

当然不行,因为一封邮件包含很多词语,一些词语(比如sex)说这是垃圾邮件,另一些说这不是。你怎么知道以哪个词为准?
在这里一个词就相当于一个特征,而一封邮件中包含很多词语,因此就相当于我们要计算这些词语(特征)的联合概率。
Paul Graham的做法是,选出这封信中P(S|W)最高的15个词,计算它们的联合概率。(如果有的词是第一次出现,无法计算P(S|W),Paul Graham就假定这个值等于0.4。因为垃圾邮件用的往往都是某些固定的词语,所以如果你从来没见过某个词,它多半是一个正常的词)
现在我们先来讨论只有两个词W1和W2的情况:

在已知W1和W2的情况下,无非就是两种结果:垃圾邮件(事件E1)或正常邮件(事件E2)。
如果假定所有事件都是独立事件(严格地说,这个假定不成立,但是这里可以忽略),那么就可以计算P(E1)和P(E2),即一封邮件在包含两个词W1和W2时,是垃圾邮件/正常邮件的概率:
$$
P\left(E_{1}\right)=P(S | W_{1}) P(S | W_{2}) P(S)
$$
$$
P\left(E_{2}\right)=(1-P(S | W_{1}))(1-P(S | W_{2}))(1-P(S))
$$
又由于在W1和W2已经发生的情况下,垃圾邮件的概率等于:
$$
P=\frac{P\left(E_{1}\right)}{P\left(E_{1}\right)+P\left(E_{2}\right)}
$$
故可得
$$
P=\frac{P(S | W_{1}) P(S | W_{2}) P(S)}{P(S | W_{1}) P(S | W_{2}) P(S)+(1-P(S | W_{1}))(1-P(S | W_{2}))(1-P(S))}
$$
将P(S)=0.5代入,可得
$$
P=\frac{P(S | W_{1}) P(S | W_{2})}{P(S | W_{1}) P(S | W_{2})+(1-P(S | W_{1}))(1-P(S | W_{2}))}
$$
将P(S|W1)记为P1,P(S|W2)记为P2,公式就变成 :
$$
P=\frac{P_{1} P_{2}}{P_{1} P_{2}+\left(1-P_{1}\right)\left(1-P_{2}\right)}
$$
这就是对W1和W2的联合概率的最终计算公式,也是我们计算某个邮件是垃圾邮件的概率公式。
将上面的公式扩展到15个词的情况,就得到了最终的概率计算公式:
$$
P=\frac{P_{1} P_{2} \cdots P_{15}}{P_{1} P_{2} \cdots P_{15}+\left(1-P_{1}\right)\left(1-P_{2}\right) \cdots\left(1-P_{15}\right)}
$$
一封邮件是不是垃圾邮件,就用这个式子进行计算。这时我们还需要一个用于比较的门槛值。
Paul Graham的门槛值是0.9,概率大于0.9,表示15个词联合认定,这封邮件有90%以上的可能属于垃圾邮件;概率小于0.9,就表示是正常邮件。


 上一篇
KNN算法原理 KNN算法原理
KNN算法原理K最近邻(K-Nearest Neighbor,KNN)算法核心思想是如果一个样本在特征空间中的k个最临近的样本中的大多数属于某一个类别,则该样本也属于这个类别。K通常是不大于20的整数。 KNN算法三要素三要素为:k值的选取
下一篇 
准确率、精确率、召回率、P-R曲线 准确率、精确率、召回率、P-R曲线
算法预测结果的四种情况正确肯定(真正例,True Positive,TP):预测为真,实际为真;正确否定(真反例,True Negative,TN):预测为假,实际为假;错误肯定(假正例,False Positive,FP):预测为真,实际
  目录