查看原文
其他

R语言机器学习 | 6 朴素贝叶斯

RH 鹿鸣Cogn 2022-04-26


第三种判别分析方法是贝叶斯判别法,与前两种方法不同,贝叶斯判别是基于后验概率的判别法,通俗来说就是判断某样本属于各个类别的后验概率,哪个后验概率高就分到哪类去其中最简单的就是朴素贝叶斯(Naive Bayes)判别法。


1  贝叶斯定理简介

贝叶斯判别法,顾名思义是以贝叶斯定理为基础,贝叶斯定理公式如下:

# P(X): X发生的概率;P(Y): Y发生的概率。
# P(Y|X) 是条件概率:即X成立的条件下,Y成立的概率。具体而言,可以认为是在具有某特征的样本X中,假设Y正确的概率。例,CT检测阳性(X)时确实患某肺炎(Y)的概率。
# P(Y)是假设Y成立先验概率。例,人群中患某肺炎的概率。
# P(X) 是特征X出现的先验概率:例,CT检测呈阳性的概率。
# P(X|Y)同样是条件概率: 即H成立的条件下,X成立的概率。例,在患肺炎的患者中(Y),CT检测阳性(X)的概率。


可用下面文氏图理解贝叶斯定理:

如果要计算A、B同时发生的概率,可以先计算A发生的概率P(A),再计算A发生时B发生的概率P(B|A),如果要两者同时发生,即 P(A∩B) = P(A)*P(B|A)

另一方面,要计算A、B同时发生的概率,也可以先计算B发生的概率P(B),再计算B发生同时A发生的概率P(A|B),使两者同时发生P(A∩B)=P(B)*P(A|B)

所以,P(A∩B) = P(A)P(B|A) = P(B)P(A|B),移动一下可得P(B|A) = P(B)P(A|B)/P(A),或P(A|B)=P(A)P(B|A)/P(B),即贝叶斯定理,描述了P(A|B)和P(B|A)的关系



用上面举的例子来说,就是:

CT检测阳性(X)时真正患某肺炎(Y)的概率 = 患肺炎的人中CT检测阳性的概率 * 患某肺炎的先验概率 / CT检测阳性的先验概率 


感受一下贝叶斯定理的应用:如果通过文献已知该肺炎的患病率是0.001,CT检测的真阳性率(得病条件下且检测出来的概率)是0.9;CT检测假阳性率(没得病条件下检测出得病的概率)是0.09,则如果一个人去检测发现是阳性,他真得该病的概率有多大?


在这个情况下,得病是Y,检测阳性是X,要求的是P(Y|X)。已知得病的先验概率P(Y)=0.001,真阳性率P(X|Y)=0.9。要用公式计算的话还缺一个检测阳性的先验概率P(X),检测出阳性包含两种情况,一种是真得病且检测出阳性(0.001*0.9),另一种是没得病但是检测出阳性了(0.999*0.09)。把这两种情况相加,可得: P(X) = P(X|Y)P(Y)+P(X|1-Y)P(1-Y) = (0.001*0.9)+(0.999*0.09)=0.09081。再把这些数值代入贝叶斯公式,可得P(Y|X)=0.01。就是说,在这种情况下,CT检测发现阳性的时候,真患病的概率只有0.01。


这一结果似乎和大多数人心里想的不一样,这一定程度上也是人们进行非理性决策的原因,即忽视了发病的先验概率很低,Kahneman的著作中也有很多研究可以用贝叶斯定理来解释,见这个非常好的介绍贝叶斯定理的视频:https://www.bilibili.com/video/BV1R7411a76r?from=search&seid=4741823831438569937


2  朴素贝叶斯及其R实现


朴素贝叶斯分类,顾名思义是一种比较简单的基于概率的分类方法。举个不一定恰当的例子,如果在路上看见一个长头发的人,让我们猜其性别,那我们大概率会认为他是女性,因为长发在女性中比例较高。当然,他也可能是男性,但在无其他特征的情况下,我们会选择条件概率最大的类别,这就是朴素贝叶斯的思想。


如果一个数据样本有n个特征X1/X2/...Xn,有m个类别C1/C2/...Cm,现在分别计算P(C1|X),P(C2|X)...P(Cm|X),然后选取有最高后验概率的类Ci,即:P(Ci | X) > P(Cj | X), 其中1≤ j ≤m, j≠m.


此时就最大化了P(Ci | X),  因此就把该样本分类到Ci中去,这里的Ci称为最大后验假定。但由于如果是属性很多的数据集,计算P(X | Ci)的开销会很大,需要分别计算P(X1|C1),P(X2|C1)...P(Xm|Cm),为此,朴素贝叶斯做了“类条件独立”朴素假定,也就是说,假定样本的每个特征都与其他特征相互独立,这样就可以极大的简化运算,然后再用贝叶斯定理进行计算即可。尽管这样的朴素假定会有些简单粗暴,但实际上能够取得不错的分类效果。


朴素贝叶斯的R实现就很简单了,和之前的判别分析没有什么区别~ 这里使用e1071包的naiveBayes()函数:

library(e1071) #klaR包也可以做朴素贝叶斯 data(iris)set.seed(100) #设置seed,保证每次抽样一样 index <- sample(nrow(iris),0.75*nrow(iris)) train <- iris[index,] #训练集 test <- iris[-index,] #测试集 nb1 <- naiveBayes(Species ~., data =train )#计算朴素贝叶斯模型 prediction1 <- predict(nb1, test[,-5],type = 'class') #默认type=class;如果使type=raw即为输出概率,可用于画ROC nb.table <- table(predict=prediction1 , actural=test$Species) #混淆矩阵 nb.tablenb_ratio <- sum(diag(nb.table))/sum(nb.table) #预测正确率 nb_ratio

可以看到朴素贝叶斯的表现还是不错的,分类正确率为0.947。


除了e1071包,klaR包也可以完成同样的工作,结果是一样的。

library(klaR)set.seed(100)index <- sample(nrow(iris),0.75*nrow(iris)) train <- iris[index,]test <- iris[-index,]nb2=NaiveBayes(Species ~., data =train )prediction2 = predict(nb2,newdata = test)$classtable(predict=prediction2 , actural=test$Species) #混淆矩阵



注:部分图片来源于网络,侵删。贝叶斯判别法的理论知识可参考b站炼数成金机器学习系列讲座。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存