朴素贝叶斯分类器,英文叫’naive Bayes classifier’.顾名思义,就是很naive的一个算法。naive主要体现在一个方面 —— “属性条件独立性假设”。就是用贝叶斯算法进行分类的时候,假设所有的属性相互独立。

公式符号说明:

  • sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器表示输入属性,等价xsparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_02(x粗写表示这是一个向量)。
  • sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_03表示分类的类别,等价sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_04
  • sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_05表示x的一个维度(属性)

1 . 预备知识

贝叶斯公式(不熟悉请戳《贝叶斯公式》 )

贝叶斯分类原理:

首先贝叶斯分类器具有所有分类器一样的功能:根据输入x给出一个分类结果c

假设用朴素贝叶斯分类选秀球员,输入属性xx是一个多维向量,包含: {百米速度,卧推,摸高,臂展,命中率,球商} 等6个维度。

输出的分类结构为sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_06sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_06的取值范围是:

{好,一般,差}。

在这里我们对每个属性进行0-1编码量化(每个属性取值都在0和1之间,越接近1说明程度越高)。

第一步,用贝叶斯建模:

sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_08


上图是贝叶斯公式的图解:

sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_Naive Bayes_09


那么,把实际问题映射到这张图上就是说:sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_10表示输入属性,sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_11表示分类结果。当输入是sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_10的时候,sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_10的可能实际类别是:sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_Naive Bayes_14sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_15,…,sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_16。分类器只能选出一个类别作为输出结果,那么怎么选呢?当然要选可能性最大的那个分类咯。

在图上可以清晰看到,sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_10sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_16的相交面积最大,所以贝叶斯分类器会把sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_10分类到sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_16。即:

输出类别= argmax(P(判断类别|输入属性))

事实上,要进行更智能的分类,可以加一个风险加权值,通过最小化风险来求得分类结果(这里只讨论思维,详细可以下一篇博文再讨论)。

实际分类过程中,我们从以往经验中总结得到先验概率sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_21(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_22)和似然概率sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_21(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_10|sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_22),然后通过贝叶斯公式获得结果。怎么操作呢?

  1. 首先用数据对分类器进行训练,这里的训练无非就是对训练数据进行一些统计(都有哪些类别,每种类别的概率等),根据大数定律,当训练集包含充足的独立同分布样本时,先验概率sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_26可通过各类样本出现的频率来进行估计。
  2. 然后获取似然概率sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_27,由于它涉及关于sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器所有属性的联合概率,难以从有限的训练样本直接估计而得。那么就可以引出这篇博文的主角——“朴素贝叶斯分类器”了。

2 . 朴素贝叶斯分类器

如上面最后一句话所说,朴素贝叶斯分类器就是解决似然概率难以统计获得的问题。假设每个属性独立地对分类结果产生影响
怎么理解上面这句话呢,属性之间不相互独立的例子如下:一个球员摸高和臂展其实是高度相关的。
现在就是要naive地认为每个属性都是独立产生影响的。则贝叶斯公式可以重写为:

sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_21(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_06|x) = sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_31 =sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_32
(x = sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_Naive Bayes_33)
公式 1通过统计求单独的属性对结果的似然概率是很容易的,所有单独属性似然概率的乘积就是sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_34了。那么,上面公式里的sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_35怎么求呢?

对于离散情况
离散情况的意思是:各属性的取值是离散的,比如说颜值的取值直接就是{高,中,低}这样的离散值,而不是0.889这样的连续取值,对于离散情况直接统计出来就行了:
sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_36
sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_37表示sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_38中在第i个属性取值为sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_39的样本组成的集合,sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_38表示训练集sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_41中第sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_06类样本组成的集合。
最后的sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_21(x|sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_06)就把各sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_21(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_39|sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_06)累乘起来就可以了,代入公式1可以求得sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_21(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_06|x)。

对于连续情况
x各维度连续取值时,你不可能在训练的时候遍历所有的取值。怎么理解呢?当训练数据某个属性取值有{0.1, 0.2, 0.3, 0.4, … , 1},当你用训练后的分类器去对新对象进行分类,而这个新对象在这个属性的取值是0.15,并不存在你的训练集中,这就是问题所在。那怎么解决呢?

我们有中心极限定理

随机变量如果是有大量独立的而且均匀的随机变量相加而成,那么它的分布将近似于正态分布。

上面是引用百度百科,这是对中心极限定理的总结。我用白话再翻译一遍:

如果变量的取值满足独立(可以不同分布),那么这些变量叠加之后的分布是满足正态分布的。这也是自然界随处可见各种‘钟形’分布的原因。

在这里,我们也可以假设sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_21(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_39|sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_06)服从正态分布,求得训练样本中sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_21(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_39|sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_06)的期望和方差,对sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_21(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_39|sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_06)的取值做一个正态分布建模,如下:

假定sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_21(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_39|sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_06) ~sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_62(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_63, sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_64),其中sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_63sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_64分别是第c类样本在第i个属性上取值的均值和方差:

sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_67


那这样就解决了连续取值问题,当输入属性取值xi并未在训练样本中出现,直接把这个取值输入sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_62(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_63, sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_64)中,获得的取值就是

sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_35了。

同上,最后的p(x|c)就把各sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_21(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_39|sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_06)累乘起来就可以了,代入公式1可以求得sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_21(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_sparkmllib朴素贝叶斯分类器_06|x)。

一个基于scikit-learn的高斯朴素贝叶斯实现代码:

from sklearn import datasets
from sklearn.naive_bayes import GaussianNB

iris = datasets.load_iris()
gnb = GaussianNB()

y = gnb.fit(iris.data, iris.target).predict(iris.data)

all_num = iris.data.shape[0]
hit_num = (iris.target == y).sum()
print("accuracy=%d%%, hit/predict=%d/%d" % (100 * hit_num/all_num, hit_num, all_num))

3. 总结

对于朴素贝叶斯分类器的操作可以理解如下:

  1. 输入大量训练样本,每个样本包括属性和类别,属性又有连续属性和离散属性之分。
  2. 对样本进行统计: 都有哪些类别,每种类别占比多少(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_77(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_04)),每个属性对样本分类单独造成的影响(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_77(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_05|sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_04))
  3. 对离散取值的属性可通过直接统计求得sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_77(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_05|sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_04);而对于连续取值的属性需要进行一个正态分布建模,求出训练样本中sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_77(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_05|sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_04)的期望和方差,代入到sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_88(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_89, sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_90)中完成建模。
  4. 根据上述3个步骤,我们可以获得sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_77(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_04)和各属性的sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_77(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯算法_05|sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_04),那么直接代入公式1中,就可以求得sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_77(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_04|x)了。
  5. 那最终进行分类,就比较各类别的sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_朴素贝叶斯_77(sparkmllib朴素贝叶斯分类器 朴素贝叶斯分类器公式_贝叶斯_04|x)(即取不同的c值),最大的那个就是我们的分类,即公式0所表示的。