朴素贝叶斯算法描述应用贝叶斯定理进行分类的一个简单应用。这里之所以称之为“朴素”,是因为它假设各个特征属性是无关的,而现实情况往往不是如此.
贝叶斯定理也称贝叶斯推理,早在18世纪,英国学者贝叶斯(1702~1763)曾提出计算条件概率的公式用来解决如下一类问题:假设B[1],B[2]…,B[n]互斥且构成一个完全事件,已知它们的概率P(B[i]),i=1,2,…,n,现观察到某事件A与B[,1],B[,2]…,B[,n]相伴随机出现,且已知条件概率P(A/B[,i]),求P(B[,i]/A)。
关于这点建议大家去看《概率论与数理统计》。
贝叶斯定理在检测吸毒者时很有用。假设一个常规的检测结果的敏感度与可靠度均为99%,也就是说,当被检者吸毒时,每次检测呈阳性(+)的概率为99%。而被检者不吸毒时,每次检测呈阴性(-)的概率为99%。从检测结果的概率来看,检测结果是比较准确的,但是贝叶斯定理却可以揭示一个潜在的问题。假设某公司将对其全体雇员进行一次鸦片吸食情况的检测,已知0.5%的雇员吸毒。我们想知道,每位医学检测呈阳性的雇员吸毒的概率有多高?令“D”为雇员吸毒事件,“N”为雇员不吸毒事件,“+”为检测呈阳性事件。可得
- P(D)代表雇员吸毒的概率,不考虑其他情况,该值为0.005。因为公司的预先统计表明该公司的雇员中有0.5%的人吸食毒品,所以这个值就是D的先验概率。
- P(N)代表雇员不吸毒的概率,显然,该值为0.995,也就是1-P(D)。
- P(+|D)代表吸毒者阳性检出率,这是一个条件概率,由于阳性检测准确性是99%,因此该值为0.99。
- P(+|N)代表不吸毒者阳性检出率,也就是出错检测的概率,该值为0.01,因为对于不吸毒者,其检测为阴性的概率为99%,因此,其被误检测成阳性的概率为1-99%。
- P(+)代表不考虑其他因素的影响的阳性检出率。该值为0.0149或者1.49%。
我们可以通过全概率公式计算得到:此概率 = 吸毒者阳性检出率(0.5% x 99% = 0.495%)+ 不吸毒者阳性检出率(99.5% x 1% = 0.995%)。P(+)=0.0149是检测呈阳性的先验概率。用数学公式描述为:
P(+)=p(+,D)+P(+,N)=P(+|D)P(D)+P(+|N)P(N)
根据上述描述,我们可以计算某人检测呈阳性时确实吸毒的条件概率P(D|+):
P(D|+)=P(+|D)P(D)/P(+)=P(+|D)P(D)/(P(+|D)P(D)+P(+|N)P(N))=0.99*0.005/(0.99*0.005+0.01*0.995)=0.3322
尽管我们的检测结果可靠性很高,但是只能得出如下结论:如果某人检测呈阳性,那么此人是吸毒的概率只有大 约33%,也就是说此人不吸毒的可能性比较大。我们测试的条件(本例中指D,雇员吸毒)越难发生,发生误判的可能性越大。
该算法的优缺点:
优点 | 缺点 |
简单、快速有效 | 依赖于常用的错误假设,即一样的重要性和独立特征 |
能处理好噪声数据和缺失的数据 | 应用在含有大量数值特征的数据集时并不理想 |
需要用来训练的例子相对较少,但同样能处理好大量的例子 | 概率的估计值相对于预测的类而言更加不可靠 |
很容易获得一个预测的估计值 |
在R语言中,有2个包可以实现朴素贝叶斯分类,分别是e1071和klaR。二者具体有什么差别,本人尚未仔细研究。下面利用e1071包实现朴素贝叶斯分类:
library(e1071) data("iris") samples <- sample(nrow(iris),size = round(nrow(iris)*0.8),replace = F) iris_train <- iris[samples,] iris_train <- iris_train[,1:4] iris_test <- iris[-samples,] iris_test <- iris_test[,1:4] iris_train_labels <- iris[samples,5] iris_test_labels <- iris[-samples,5] classifier <- naiveBayes(iris_train,iris_train_labels) pre <- predict(classifier,iris_test) #传入参数为data.frame TF <- table(pre,iris_test_labels) accuracy <- (sum(diag(TF))/sum(TF)) cat("正确率",accuracy)
python版:
from sklearn import datasets
iris = datasets.load_iris()
from sklearn.naive_bayes import GaussianNB
clf = GaussianNB()
clf.fit(iris.data, iris.target)
clf.predict(iris.data[0])