朴素贝叶斯分类器

朴素贝叶斯分类器是用来做分类的一个简便方法。在贝叶斯公式的基础上,引人条件独立的假设,使得贝叶斯分类器具有简单易行的优点和假设时常与实际不符的缺点。下面简单介绍一下朴素贝叶斯分类器。

首先规定一下数据格式:输入的每一个样本为${{x}^{i}},{{c}^{i}}$,其中:$i$为样本编号,$x$为样本的特征,是一个$n$维向量,${{x}^{i}}={{[x_{1}^{i},x_{2}^{i},\cdots ,x_{n}^{i}]}^{T}}$(先假设$x_{j}^{i}(j=1,\cdots ,n)$是离散型变量);$c$为样本类别,${{c}^{i}}\in \{1,2,\cdots ,k\}$表示共有$k$个类别。

分类问题需要对输入的样本$x$给出一个样本类别$c$。朴素贝叶斯方法采用“软指定”的方式,对于样本$x$给出其属于每一个类别的概率,采用概率最大的类别作为预测类别。也就是说,对于样本$x$,需要分别计算$p(c=1|x),p(c=2|x),\cdots ,p(c=k|x)$,找到取值最大的即可。

作为一个“生成式”模型,朴素贝叶斯方法并不是对$p(c|x)$直接建模的,而是对$p(x|c)$和$p(c)$建模。根据贝叶斯公式:

$$p(c|x)=\frac{p(x|c)p(c)}{p(x)}$$

显然,$p(c|x)$取值最大,只需要$p(x|c)p(c)$最大即可,现在看看$p(x|c)$和$p(c)$怎么计算。

$p(c)$很好办,就是样本类别的先验概率,可以事先指定,也可以和容易的根据样本估计出来。问题是$p(x|c)$,因为$x$是一个$n$维向量,所以$p(x|c)$就是一个$n$个变量的联合分布,这就很不好计算,假设每一维都有$l$个可能取值(假设每一维是离散变量),那么光$p(x|c)$就有$k*{{l}^{n}}$个取值($c$有$k$个,$x$有${{l}^{n}}$个),也就是说要估计这么多个参数,当数据维度比较大,也就是$n$比较大时,参数个数就太多了,没法估计。

为了解决这个问题,朴素贝叶斯方法做了一个很强的假设,即样本$x$的各个维度之间在类别条件下是相互独立的:

$$p(x|c)=p({{x}_{1}}|c)*p({{x}_{2}}|c)*\cdots *p({{x}_{n}}|c)$$

原来的联合概率现在变成了多个独立分布的乘积,这就简化了问题。现在不需要直接估计$p(x|c)$,而分布估计$p({{x}_{1}}|c),\cdots ,p({{x}_{n}}|c)$,参数的个数变为$k*l*n$比原来少了许多,估计参数也比较可行。

当然,实际中,这个假设好多时候是不成立的,这是朴素贝叶斯方法的弊端,比如根据身高和体重估计一个人的性别,用朴素贝叶斯方法就不合适了,因为身高和体重显然不是独立的,但如果根据头发长短和体重作为特征,朴素贝叶斯方法就大概就可以用了,体重和头发长短没有关系吧~当然你可以根据某人体重6.5斤推出他是婴儿进一步推出他头发很短。。。呵呵,好冷~

接下来就是具体估计这些参数,写出似然函数最大化求解即可。推导过程不写了,直接给出结果。

参数估计的结果和直觉很符合,以上面根据身高和头发长短判断性别为例,假设头发长短离散化为长、中、短三个取值,而身高是连续变量,用$\text{h}$表示。需要估计的参数有先验概率 $p(boy),p(girl)$,类条件概率$p(hair=long|boy)$ ,$p(hair=mid|boy)$,$p(hair=short|boy)$,$p(hari=long|girl)$,$p(hari=mid|girl)$$p(hari=short|girl)$以及$p(height=h|boy)$,$p(height=h|girl)$。

先验概率$p(c)$的估计结果就是每个类别在样本中占的比例,100个人里有54个男,46个女,那么$p(boy)=0.54$,$p(girl)=0.46$。类条件概率$p({{x}_{j}}|c)$ 的估计结果也很直接,就是特征的不同取值在给定类别的样本中的比例,比如54个男人中有6个长发,13个中发,35个短发,那么$p(hair=long|boy)\text{=}{6}/{54}\;$,$p(hair=mid|boy)\text{=}{13}/{54}\;$,$p(hair=short|boy)\text{=}{35}/{54}\;$,其他参数也是类似的结果,这些结果跟直觉很符合,简单易记忆。

对身高,由于是连续变量,所以一般将其建模为正态分布变量(也可以根据需要弄成别的分布),根据样本估计出各个类别下的身高均值和方差就可以了,然后套用正太分布的概率密度公式计算$p(h|boy)$和$p(h|girl)$。

参数计算完成后,朴素贝叶斯分类器的模型就完整了。接下来,对于一个新的输入$x={{[height\text{=}165,hair=long]}^{\text{T}}}$,就可以计算出$p(boy|x\text{)}\propto p(165|boy)p(long|boy)p(boy)$和$p(girl|x\text{)}\propto p(165|girl)p(long|girl)p(girl)$,哪个结果大,就判别为属于哪一类了。

另外,实际应用中,为避免0概率,需要做平滑处理,常用拉普拉斯平滑。如果54个男生中没有长发的,那么直接计算就回导致参数的估计值$p(hair=long|boy)\text{=0}$,这将导致$p(x|boy)\text{=}p(height|boy)p(hair|boy)\text{=}0$,那么$p(boy|x)\text{=}\frac{p(x|boy)p(boy)}{p(x)}\text{=}0$ 也就是说,如果样本中没有长发男生,那么看到一个长发的人时,就一口咬定“他”不是男的,毫不留情,这当然是比较“暴力武断”的。

$\begin{align} p(boy|x)&=\frac{p(x|boy)p(boy)}{p(x)} \\ & =\frac{p(x|boy)p(boy)}{p(x|boy)p(boy)\text{+}p(x|girl)p(girl)} \\\end{align}$

因为同样的理由,值为0的参数估计也会导致$p(x|girl)p(girl)\text{=0}$,那么上式计算过程中就会出现$\frac{0}{0\text{+0}}$的尴尬情况。所以无论是从计算角度还是实际意义来讲,参数值为0的估计都是很讨厌的。

拉普拉斯平滑是一种简单的处理类概率的方法,思想很简单,对每个对应类别的数据加一后重新估计概率。比如要估计$p(hair=long|boy)$,这时候就要对原来男生中长发人数加1表示男生中长发人数,公平起见也要对男生中中发和短发的人数加1。假设男生中有$p$个长发的,那么$p(hair=long|boy)\text{=}\frac{\text{p+}1}{54\text{+}1\text{+}1\text{+}1}$,这样,即使真的没有长发男生,也不会搞出参数为0的估计结果。另外,拉普拉斯修正不会破坏概率和为1的性质,即$p(hari=long|boy)+p(hair=mid|boy)+p(hair=short|boy)\text{=1}$,简单又挺合理。当然也有其他的平滑处理方法,比如吴军的《数学之美》中提到古德—图灵方法,有兴趣的可以翻阅。

附:R中朴素贝叶斯方法

可以看出,朴素贝叶斯方法的实现没多大难度,即使这样,R包中还是提供了一些实现。

e1071包中的naiveBayes()提供了一个实现,klaR包在e1071的基础上提供了另一个实现,提供了更多选项。

参考资料

[1]Andrew Ng机器学习视频、讲义:http://cs229.stanford.edu/

[2]《数学之美》,吴军,人民邮电出版社,2012.6

[3]一个很直观的示例http://www.ruanyifeng.com/blog/2013/12/naive_bayes_classifier.html

        

原文地址:https://www.cnblogs.com/dreamvibe/p/4278032.html