朴素贝叶斯分类器是一个简单有效的分类模型。
贝叶斯定位公式为:P(A|B) = P(B|A)*P(A)/P(B)
其中P(A|B)表示在B发生的前提下A发生的概率。公式具体就不多说了,下面举一个例子来说明。
那么现在假设食堂来了10个四川人,8个人要了夫妻肺片。2个人要了酸辣土豆丝。来了10个湖北人;7个人要了酸辣土豆丝,3个人要了夫妻肺片。现在又来了一个四川人,预测它会点一个什么菜呢?可以很直观的看出来,四川人点夫妻肺片的概率为80%;点土豆丝的概率为20%。使用贝叶斯公式计算的过程如下。
首先:
他点夫妻肺片的概率:P(夫妻肺片|四川人) = P(四川人|夫妻肺片)*P(夫妻肺片)/P(四川人) = (8 / 11) * (11 / 20) / (10 / 20) = 0.8
他点酸辣土豆丝的概率:P(土豆丝|四川人) = P(四川人|土豆丝)*P(土豆丝)/P(四川人) = (2 / 9) * (9 / 20) / (10 / 20) = 0.2
可以预测,他点的菜为夫妻肺片。
对于多个条件,贝叶斯定理也依然成立。
我们需要预测某个样本属于哪一类,只要看他在各个条件发生的前提下,属于某一个分类的概率最大即可。也就是对于各个类Ci,求出P(Ci|F1F2F3…Fn)。
根据贝叶斯公式 P(Ci|F1F2F3…Fn) = P(F1F2F3…Fn|Ci) * F(Ci) / P(F1F2F3…Fn)
针对各个类Ci,P(F1F2F3…Fn)的值不变,因此目标函数变成P(F1F2F3…Fn|Ci)*F(Ci)记作f(Ci)。
f(Ci) = P(F1F2F3…Fn|Ci)*F(Ci) = P(F1|Ci)*P(F2|Ci)*P(F3|Ci)…P(Fn|Ci)*F(Ci)
该等式的右项都可以通过训练集中的数据得出。
朴素贝叶斯定理基于前提条件各个特征都彼此独立,但是在现实中,该前提条件往往不能达成。但是有统计数据表明,非该前提下对于分类的结果影响不大。
下面通过一个比较复杂的例子梳理一下计算的过程。
在这里我们摘选自泰坦尼克幸存者公开数据集的一部分:
PassengerId | Survived | Pclass | Sex | Age |
---|---|---|---|---|
1 | 0 | 3 | male | 22(小) |
2 | 1 | 1 | female | 38(小) |
3 | 1 | 3 | female | 26(小) |
4 | 1 | 1 | female | 35(小) |
5 | 0 | 3 | male | 35(小) |
6 | 0 | 3 | male | 20(小) |
7 | 0 | 1 | male | 54(大) |
8 | 0 | 3 | male | 39(小) |
9 | 1 | 3 | female | 27(小) |
10 | 0 | 3 | female | 31(小) |
我们这里为了计算方便,不妨暂时将年龄先粗糙的按照40作为分界线分为大小两个挡位。假设,现在要预测第11位船客的的生存状况,我们先看以下第十一位乘客的资料:
PassengerId | Survived | Pclass | Sex | Age |
---|---|---|---|---|
11 | 1 | 3 | female | 15(小) |
目标函数f(存活|3等舱*女性*年纪中) = P(3等舱|存活)* P(女性|存活)* P(年纪小|存活) *P(存活)= (3/7) * (4/5) * (4/9) * (1/2) = 0.0761 为第11个船客存货的概率
目标函数f(死亡|3等舱*女性*年纪小) = P(3等舱|死亡)* P(女性|死亡) * P(年纪小|死亡) *P(死亡) = (4/7) *(1/5)* (5/9)* (1/2) = 0.0317 为第11个船客死亡的概率
从计算结果可以看出,预期该乘客存活,并且数据集中显示,该船客确实存活。
从以上的例子,我们看到,有些属性值为连续的量,不太好像离散的值一样去进行分类,对于这种情况,常用的方法有两种:①像上述例子中的年龄一样,将其分档。②假设该值为正态分布的,计算出来均值和方差,得到密度函数,通过密度函数的值来反应概率。
朴素贝叶斯的逻辑比较清晰,所以代码就不贴了。很多第三方库也帮我们提供了朴素贝叶斯的接口,比如OpenCV。
OpenCV中的接口如下:
from cv2 import ml
# prepare train_data, label and predict_data
cv_bayes = ml.NormalBayesClassifier_create()
train_rst = cv_bayes.train(train_data, ml.ROW_SAMPLE, label)
if train_rst:
(ret, predict_rst) = cv_bayes.predict(predict_data)
代码中,train_data,predict_data,label为numpy.array结构。train_data和predict_data为一个二维数组,假设其大小为m*n,他的没一行表示一个特征向量,特征向量的长度为m。其元素的类型为float。
label是一个以为数组,他的长度是n,表示n个特征向量对应的结果。元素的类型为int。
一句话总结:朴素贝叶斯分类模型,通过统计数据和贝叶斯公式算出各个可能性的概率;比较,概率最高的就是预测的结果。