python朴素贝叶斯算法(sklearn.naive_bayes),会通过了解什么是朴素贝叶斯、贝叶斯公式推导、实际案例去讲解。也同时记录学习的过程帮组大家一起学习如果实际应该贝叶斯算法去分析。
贝叶斯算法是英国数学家贝叶斯(约1701-1761)Thomas Bayes,生前提出为解决“逆概”问题写的一篇文章。
“逆概”就是逆向概率
,有逆向概率就会有正向概率
。举个简单的例子就能理解什么是正向概率和逆向概率:
现实世界本身就是不确定的,人类的观察能力有限。我们日常所观察到的只是事物表面上的结果,因此我们需要提供一个猜测。这个就是贝叶斯需要解决的问题。
有一个学校男生女生比例分别为60%和40%,男生100%穿长裤,女生50%会穿长裤剩下的会穿裙子。远处的校门口走来一个穿长裤的学生,无法判断性别。求这个学生是女生的概率有多大?
我们先按自己现在方式进行思考一下,要求这个穿长裤的学生是女生的概率。
案例公式推导:
因为不知道学校总人数是多少,我们就假设总人数为U
穿长裤的男生人数:
P(Boy)
男生的概率,P(Pants|Boy)
男生穿长裤的概率
U ∗ P ( B o y ) ∗ P ( P a n t s ∣ B o y ) U*P(Boy)*P(Pants|Boy) U∗P(Boy)∗P(Pants∣Boy)
穿长裤的女生人数:
P(Girl)
女生的概率,P(Pants|Girl)
女生穿长裤的概率
U ∗ P ( G i r l ) ∗ P ( P a n t s ∣ G i r l ) U*P(Girl)*P(Pants|Girl) U∗P(Girl)∗P(Pants∣Girl)
穿长裤的总人数:
U ∗ P ( B o y ) ∗ P ( P a n t s ∣ B o y ) + U ∗ P ( G i r l ) ∗ P ( P a n t s ∣ G i r l ) U*P(Boy)*P(Pants|Boy)+U*P(Girl)*P(Pants|Girl) U∗P(Boy)∗P(Pants∣Boy)+U∗P(Girl)∗P(Pants∣Girl)
那么女生穿长裤的概率:穿长裤的女生数/穿长裤的总人数 U ∗ P ( G i r l ) ∗ P ( P a n t s ∣ G i r l ) U ∗ P ( B o y ) ∗ P ( P a n t s ∣ B o y ) + U ∗ P ( G i r l ) ∗ P ( P a n t s ∣ G i r l ) \frac{U*P(Girl)*P(Pants|Girl)}{U*P(Boy)*P(Pants|Boy)+U*P(Girl)*P(Pants|Girl)} U∗P(Boy)∗P(Pants∣Boy)+U∗P(Girl)∗P(Pants∣Girl)U∗P(Girl)∗P(Pants∣Girl)
公式化简:
P ( G i r l ) ∗ P ( P a n t s ∣ G i r l ) P ( G i r l ) ∗ P ( P a n t s ∣ G i r l ) + P ( B o y ) ∗ P ( P a n t s ∣ B o y ) \frac{P(Girl)*P(Pants|Girl)}{P(Girl)*P(Pants|Girl)+P(Boy)*P(Pants|Boy)} P(Girl)∗P(Pants∣Girl)+P(Boy)∗P(Pants∣Boy)P(Girl)∗P(Pants∣Girl)
所以最终走过了穿长裤可能是女生的概率为:
0.4 ∗ 0.5 0.6 ∗ 1 + 0.4 ∗ 0.5 = 0.2 0.8 = 0.25 \frac{0.4*0.5}{0.6*1+0.4*0.5}=\frac{0.2}{0.8}=0.25 0.6∗1+0.4∗0.50.4∗0.5=0.80.2=0.25
P ( A ∣ B ) = P ( B ∣ A ) P ( A ) P ( B ) P(A|B)=\frac{P(B|A)P(A)}{P(B)} P(A∣B)=P(B)P(B∣A)P(A)
结合上面我们讲女生穿裤子的概率问题来带入一下,我们拟定:
A1:女生,A2:男生
B1:穿裤子,B2:未穿裤子
P(A1):就是女生的概率,已知条件 0.4 0.4 0.4
P(B1):就是穿裤子的概率,男生穿裤子的概率+女生穿裤子的概率及 0.6 ∗ 1 + 0.4 ∗ 0.5 0.6*1+0.4*0.5 0.6∗1+0.4∗0.5
我们要求的P(A1|B1):穿裤子中是女生的概率
P(B1|A1):就是女生穿裤子的概率,已知条件 0.5 0.5 0.5
P ( A 1 ∣ B 1 ) = P ( B 1 ∣ A 1 ) P ( A 1 ) P ( B ) = 0.5 ∗ 0.4 0.6 ∗ 1 + 0.5 ∗ 0.4 = 0.25 P(A1|B1)=\frac{P(B1|A1)P(A1)}{P(B)}=\frac{0.5*0.4}{0.6*1+0.5*0.4}=0.25 P(A1∣B1)=P(B)P(B1∣A1)P(A1)=0.6∗1+0.5∗0.40.5∗0.4=0.25
所以带入公式就得到上面通推导的结果,穿裤子的女生概率为0.25。这个地方有点绕,需要多多理解一下。
如果不清楚的可以看李永乐老师讲贝叶斯。
参考博主:https://blog.csdn.net/brucewong0516/article/details/78798359
朴素贝叶斯是一类比较简单的算法,scikit-learn中朴素贝叶斯类库的使用也比较简单。相对于决策树,KNN之类的算法,朴素贝叶斯需要关注的参数是比较少的,这样也比较容易掌握。在scikit-learn中,常用的有3个朴素贝叶斯的分类算法类。分别是GaussianNB
,MultinomialNB
和BernoulliNB
。这三个类适用的分类场景各不相同其中:
GaussianNB类的主要参数仅有一个,即先验概率priors,对应Y的各个类别的先验概率P(Y=Ck)。这个值默认不给出,如果不给出此时P(Y=Ck)=mk/m。其中m为训练集样本总数量,mk为输出为第k类别的训练集样本数。如果给出的话就以priors 为准。 在使用GaussianNB的fit方法拟合数据后,我们可以进行预测。此时预测有三种方法,包括predict,predict_log_proba和predict_proba
import numpy as np
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
Y = np.array([1, 1, 1, 2, 2, 2])
from sklearn.naive_bayes import GaussianNB
clf = GaussianNB()
#拟合数据
clf.fit(X, Y)
print("==Predict result by predict==")
print(clf.predict([[-0.8, -1]]))
print("==Predict result by predict_proba==")
print(clf.predict_proba([[-0.8, -1]]))
print("==Predict result by predict_log_proba==")
print(clf.predict_log_proba([[-0.8, -1]]))
==Predict result by predict==
[1]
==Predict result by predict_proba==
[[ 9.99999949e-01 5.05653254e-08]]
==Predict result by predict_log_proba==
[[ -5.05653266e-08 -1.67999998e+01]]
此外,GaussianNB一个重要的功能是有 partial_fit方法,这个方法的一般用在如果训练集数据量非常大,一次不能全部载入内存的时候。这时我们可以把训练集分成若干等分,重复调用partial_fit来一步步的学习训练集,非常方便。后面讲到的MultinomialNB和BernoulliNB也有类似的功能
MultinomialNB参数比GaussianNB多,但是一共也只有仅仅3个。其中,参数alpha即为上面的常数λ,如果你没有特别的需要,用默认的1即可。如果发现拟合的不好,需要调优时,可以选择稍大于1或者稍小于1的数。布尔参数fit_prior表示是否要考虑先验概率,如果是false,则所有的样本类别输出都有相同的类别先验概率。否则可以自己用第三个参数class_prior输入先验概率,或者不输入第三个参数class_prior让MultinomialNB自己从训练集样本来计算先验概率,此时的先验概率为P(Y=Ck)=mk/m。其中m为训练集样本总数量,mk为输出为第k类别的训练集样本数
fit_prior | class_prior | 最终先验概率 |
---|---|---|
False | 填或不填没有意义 | P ( Y = C k ) = 1 / k p ( Y = C k ) = 1 / k P(Y=Ck)=1/kp(Y=Ck)=1/k P(Y=Ck)=1/kp(Y=Ck)=1/k |
True | 不填 | P ( Y = C k ) = m k / m p ( Y = c k ) = m k / m P(Y=Ck)=mk/mp(Y=ck)=mk/m P(Y=Ck)=mk/mp(Y=ck)=mk/m |
True | 填 | P ( Y = C k ) = p ( Y − c k ) = c l a s s p r i o r P(Y=Ck)=p(Y-ck)=class_prior P(Y=Ck)=p(Y−ck)=classprior |
BernoulliNB一共有4个参数,其中3个参数的名字和意义和MultinomialNB完全相同。唯一增加的一个参数是binarize。这个参数主要是用来帮BernoulliNB处理二项分布的,可以是数值或者不输入。如果不输入,则BernoulliNB认为每个数据特征都已经是二元的。否则的话,小于binarize的会归为一类,大于binarize的会归为另外一类。
在使用BernoulliNB的fit或者partial_fit方法拟合数据后,我们可以进行预测。此时预测有三种方法,包括predict,predict_log_proba和predict_proba。由于方法和GaussianNB完全一样,这里就不累述了。
贝叶斯的主要优点:
贝叶斯的主要缺点:
本文案例数据点击下载
之前使用过决策树算法对该数据进行分析决策树算法点这里查看,现在我们用同样的数据但是使用贝叶斯来看看。
数据背景是有一组关于天气、是否是周末、有没有促销对销量高低的影响数据,我们先来看一下代码。
import pandas as pd
data=pd.read_excel(r'C:\Users\huangjunwen\Desktop\sales_data.xls',index_col='序号')
#导入数据,将序号列转变成索引
data_new=data.replace(['坏','否','低','好','是','高'],[-1,-1,-1,1,1,1])
#将数据内容转化成可以计算的数字,-1代表:坏、否、低;1代表:好、是、高
from sklearn.utils import shuffle
#这是一个可以将数据重新随机排序的模块
data_new=shuffle(data_new)
#对数据进行重新随机排列
data_train=data_new.iloc[:20,:3]
#创建训练集
data_test=data_new.iloc[:20,3:]
#创建测试的标签集
data_predict=data_new.iloc[20:,]
#创建最后要预测并检验结果准确的预测集
from sklearn.naive_bayes import GaussianNB
#导入高斯分布的贝叶斯
clf=GaussianNB()
#创建高斯分布的贝叶斯模型
clf.fit(data_train,data_test)
#将训练数据及标签数据放入模型进行训练
data_predict['贝叶斯拟合']=clf.predict(data_predict.iloc[:,:3])
#预测结果并赋值到预测集进行模型与实际标签比对
print(len(data_predict[data_predict['销量']==data_predict['贝叶斯拟合']])/len(data_predict))
#算出模型准确率