失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 统计学习方法笔记(三)-朴素贝叶斯原理及python实现

统计学习方法笔记(三)-朴素贝叶斯原理及python实现

时间:2024-03-27 05:14:52

相关推荐

统计学习方法笔记(三)-朴素贝叶斯原理及python实现

朴素贝叶斯

条件概率特征条件独立假设朴素贝叶分类器朴素贝叶斯分类算法原理学习与分类算法朴素贝叶斯算法原理模型多项式模型高斯模型伯努利模型多项式模型的朴素贝叶斯分类器实现代码高斯模型的朴素贝叶斯分类器实现代码代码案例地址

条件概率

朴素贝叶斯是基于贝叶斯定理与特征条件独立假设的分类方法。

要明白什么是贝叶斯定理,则先复习一下几个术语:条件概率、特征条件独立假设.

什么是条件概率?

P(A∣B)P(A|B)P(A∣B)表示事件B已经发生的前提下,事件A发生的概率,也叫做事件B发生下事件A的条件概率。上述用数学语言描述为:

P(A∣B)=P(AB)P(B){P(A|B)=\frac{P(AB)}{P(B)}}P(A∣B)=P(B)P(AB)​

贝叶斯定理是基于条件概率,通过P(A∣B)P(A|B)P(A∣B)来求解P(B∣A)P(B|A)P(B∣A):P(B∣A)=P(A∣B)P(B)P(A)P(B|A)=\frac{P(A|B)P(B)}{P(A)}P(B∣A)=P(A)P(A∣B)P(B)​

根据全概率公式,上式又可以写为:

P(Bi∣A)=P(Bi)P(A∣Bi)∑j=1nP(Bj)P(A∣Bj){P(B_i|A)=\frac{P(B_i)P(A|B_i)}{\sum_{j=1}^{n} P(B_j)P(A|B_j)}}P(Bi​∣A)=∑j=1n​P(Bj​)P(A∣Bj​)P(Bi​)P(A∣Bi​)​

特征条件独立假设

上面介绍了条件概率,那什么是特征条件独立假设?

给定训练集(X,Y)(X,Y)(X,Y),xxx是集合XXX中的样本(x∈Xx \in Xx∈X),x=(x1,x2,...,xn)x=(x_1,x_2,...,x_n)x=(x1​,x2​,...,xn​),类标记集合含有KKK中类别,及Y={c1,c2,...,cK}\mathcal{Y}=\{c_1,c_2,...,c_K\}Y={c1​,c2​,...,cK​}.

如何预测新样本xxx的类别呢?从概率的角度分析,该问题的本质就是给定xxx,它属于哪个类别的概率最大.

即问题转化为求解P(Y=c1∣X=x),P(Y=c2∣X=x),...,P(Y=ck∣X=x)P(Y=c_1|X=x),P(Y=c_2|X=x),...,P(Y=c_k|X=x)P(Y=c1​∣X=x),P(Y=c2​∣X=x),...,P(Y=ck​∣X=x)中最大的概率,即求后验概率最大输出:arg⁡max⁡ckP(Y=ck∣X=x){\arg \max_{c_k} P(Y=c_k|X=x)}argmaxck​​P(Y=ck​∣X=x).后验概率最大的类作为xxx的类别输出.

要求后验概率最大输出:arg⁡max⁡ckP(Y=ck∣X=x){\arg \max_{c_k} P(Y=c_k|X=x)}argmaxck​​P(Y=ck​∣X=x),也就是要求出:P(Y=ck∣X=x){P(Y=c_k|X=x)}P(Y=ck​∣X=x).想要求出P(Y=ck∣X=x){P(Y=c_k|X=x)}P(Y=ck​∣X=x),就要用到贝叶斯定理,根据贝叶斯定理,可得:

(1)P(Y=ck∣X=x)=P(X=x∣Y=ck)P(Y=ck)∑kP(X=x∣Y=ck)P(Y=ck){P(Y=c_k|X=x)=\frac{P(X=x|Y=c_k)P(Y=c_k)}{\sum_{k} P(X=x|Y=c_k)P(Y=c_k)}} \tag{1}P(Y=ck​∣X=x)=∑k​P(X=x∣Y=ck​)P(Y=ck​)P(X=x∣Y=ck​)P(Y=ck​)​(1)

针对条件概率P(X=x∣Y=ck)=P(X(1)=x(1),...,X(n)=x(n))P(X=x|Y=c_k)=P(X^{(1)}=x^{(1)},...,X^{(n)}=x^{(n)})P(X=x∣Y=ck​)=P(X(1)=x(1),...,X(n)=x(n)),假设第iii维特征xix_ixi​可取值有SjS_jSj​个,类别取值个数为KKK个,那么参数个数为:K∏j=1nSjK \prod_{j=1}^{n}S_jK∏j=1n​Sj​,其规模为指数数量级别的。这在实际应用中肯定不行的。

为了解决这个问题,朴素贝叶斯法对条件概率分布作了条件独立性的假设,即假设各个维度的特征x1,x2,...,xnx_1,x_2,...,x_nx1​,x2​,...,xn​互独立.

朴素贝叶分类器

有了上述假设,条件概率可以转化为:

(2)P(X=x∣Y=ck)=P(X(1)=x(1),...,X(n)=x(n))=∏j=1nP(X(j)=x(j)∣Y=ck){P(X=x|Y=c_k)=P(X^{(1)}=x^{(1)},...,X^{(n)}=x^{(n)})}=\prod_{j=1}^{n}P(X^{(j)}=x^{(j)}|Y=c_k) \tag{2}P(X=x∣Y=ck​)=P(X(1)=x(1),...,X(n)=x(n))=j=1∏n​P(X(j)=x(j)∣Y=ck​)(2)

将式子(2)带入式子(1)可得:

(3)P(Y=ck∣X=x)=P(Y=ck)∏jP(X(j)=x(j)∣Y=ck)∑kP(Y=ck)∏jP(X(j)=x(j)∣Y=ck),k=1,2,...,K{P(Y=c_k|X=x)=\frac {P(Y=c_k) \prod_{j} P(X^{(j)}=x^{(j)}|Y=c_k)}{\sum_k P(Y=c_k) \prod_j P(X^{(j)}=x^{(j)}|Y=c_k)}},k=1,2,...,K \tag{3}P(Y=ck​∣X=x)=∑k​P(Y=ck​)∏j​P(X(j)=x(j)∣Y=ck​)P(Y=ck​)∏j​P(X(j)=x(j)∣Y=ck​)​,k=1,2,...,K(3)

式子(3)位朴素贝叶斯分类的基本公式。即 朴素贝叶斯分类器可由下式子表示:

(4)y=f(x)=arg⁡max⁡ckP(Y=ck)∏jP(X(j)=x(j)∣Y=ck)∑kP(Y=ck)∏jP(X(j)=x(j)∣Y=ck){y=f(x)=\arg \max_{c_k} \frac {P(Y=c_k) \prod_{j} P(X^{(j)}=x^{(j)}|Y=c_k)}{\sum_k P(Y=c_k) \prod_j P(X^{(j)}=x^{(j)}|Y=c_k)}} \tag{4}y=f(x)=argck​max​∑k​P(Y=ck​)∏j​P(X(j)=x(j)∣Y=ck​)P(Y=ck​)∏j​P(X(j)=x(j)∣Y=ck​)​(4)

由于对于所有的ckc_kck​,上式子分母的值是一样的,所以可以忽略掉分母部分。最终朴素贝叶斯分类器的表达式为:

y=arg⁡max⁡ckP(Y=ck)∏jP(X(j)=x(j)∣Y=ck){y=\arg \max_{c_k} P(Y=c_k) \prod_{j} P(X^{(j)}=x^{(j)}|Y=c_k)}y=argck​max​P(Y=ck​)j∏​P(X(j)=x(j)∣Y=ck​)

上述的表述是从头到尾推导出朴素贝叶斯分类器的过程.

朴素贝叶斯分类算法原理

若对推导过程不感兴趣,可跳过上述推导,直接看下面朴素贝叶斯分类算法:

基本方法:

设输入空间X⊆Rn\mathcal{X}\subseteq \mathcal{R}^nX⊆Rn是nnn维向量的集合,输出空间为类标记集合Y={c1,c2,...,cK}\mathcal{Y}=\{c_1,c_2,...,c_K\}Y={c1​,c2​,...,cK​}.其中特征向量x∈X{x}\in \mathcal{X}x∈X作为输入,类标记y∈Yy\in \mathcal{Y}y∈Y作为输出。

训练集T={(x1,y1),(x2,y2),...,(xN,yN)}T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\}T={(x1​,y1​),(x2​,y2​),...,(xN​,yN​)}由P(X,Y)P(X,Y)P(X,Y)独立同分部产生。其中XXX是定义在输入空间X\mathcal{X}X上的随机向量,YYY是定义在输出空间Y\mathcal{Y}Y的随机变量。P(X,Y)P(X,Y)P(X,Y)是XXX和YYY的联合概率分布。

学习与分类算法

朴素贝叶斯算法原理

输入:

训练数据T={(x1,y1),(x2,y2),...,(xN,yN)}T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\}T={(x1​,y1​),(x2​,y2​),...,(xN​,yN​)},其中xi=(xi(1),xi(2),...,xi(n))Tx_i=(x_{i}^{(1)},x_{i}^{(2)},...,x_{i}^{(n)})^{\mathrm{T}}xi​=(xi(1)​,xi(2)​,...,xi(n)​)T,xi(j)x_{i}^{(j)}xi(j)​是第iii个样本的第jjj个特征,xi(j)∈{aj1,aj2,...,ajSj}x_i^{(j)} \in \{a_{j1},a_{j2},...,a_{jS_j}\}xi(j)​∈{aj1​,aj2​,...,ajSj​​},ajla_{jl}ajl​是第jjj个特征可能取的第lll个值,j=1,2,...,nj=1,2,...,nj=1,2,...,n,l=1,2,...,Sjl=1,2,...,S_jl=1,2,...,Sj​,yi∈{c1,c2,...,cK}y_i \in \{c_1,c_2,...,c_K\}yi​∈{c1​,c2​,...,cK​},xxx是实例。

输出:

实例xxx的分类

第一步:先计算先验概率及条件概率

P(Y=ck)=∑i=1NI(yi=ck)N,k=1,2,...,K{P(Y=c_k)=\frac{\sum_{i=1}^{N}I(y_i=c_k)}{N}},k=1,2,...,KP(Y=ck​)=N∑i=1N​I(yi​=ck​)​,k=1,2,...,K

P(X(j)=ajl∣Y=ck)=∑i=1NI(xi(j)=ajl,yi=ck)∑i=1NI(yi=ck){P(X^{(j)}=a_{jl}|Y=c_k)=\frac{\sum_{i=1}^{N}I(x_i^{(j)}=a_{jl},y_i=c_k)}{\sum_{i=1}^{N}I(y_i=c_k)}}P(X(j)=ajl​∣Y=ck​)=∑i=1N​I(yi​=ck​)∑i=1N​I(xi(j)​=ajl​,yi​=ck​)​

Sj=1,2,...,n;l=1,2,...,Sj;k=1,2,...,KSj=1,2,...,n;l=1,2,...,S_j;k=1,2,...,KSj=1,2,...,n;l=1,2,...,Sj​;k=1,2,...,K

第二步:对于给定的实例x=(x(1),x(2),...,x(n))x=(x^{(1)},x^{(2)},...,x^{(n)})x=(x(1),x(2),...,x(n))计算

P(Y=ck)∏j=1nP(X(j)∣Y=ck),k=1,2,...,K{P(Y=c_k)}\prod_{j=1}^{n}P(X^{(j)}|Y=c_k),k=1,2,...,KP(Y=ck​)j=1∏n​P(X(j)∣Y=ck​),k=1,2,...,K

第三步:确定实例xxx的类

y=arg⁡max⁡ckP(Y=ck)∏j=1nP(X(j)=x(j)∣Y=ck){y=\arg \max_{c_k}P(Y=c_k)\prod_{j=1}^{n}P(X^{(j)}=x^{(j)}|Y=c_k)}y=argck​max​P(Y=ck​)j=1∏n​P(X(j)=x(j)∣Y=ck​)

针对最终的朴素贝叶斯分类算法,如何求解P(Y=ck),P(X(j)=x(j)∣Y=ck)P(Y=c_k),P(X^{(j)}=x^{(j)}|Y=c_k)P(Y=ck​),P(X(j)=x(j)∣Y=ck​),常见有三种模型:

多项式模型、高斯模型、伯努利模型。

模型

多项式模型

多项式模型

当特征是离散时,使用多项式模型,多项式模型在计算先验概率P(Y=ck)P(Y=c_k)P(Y=ck​)和条件概率P(X(j)=x(j)∣Y=ck)P(X^{(j)}=x^{(j)}|Y=c_k)P(X(j)=x(j)∣Y=ck​)时,会做一些平滑处理,具体公式如下:

P(Y=ck)=Nck+αN+kα{P(Y=c_k)=\frac{N_{c_k}+\alpha}{N+k\alpha}}P(Y=ck​)=N+kαNck​​+α​

其中NNN是总的样本个数,kkk是总的类别个数,NckN_{c_k}Nck​​是类别ckc_kck​的样本个数,α\alphaα是平滑值.

P(X(j)=x(j)∣Y=ck)=Nck,xi+αNck+nα{P(X^{(j)}=x^{(j)}|Y=c_k)=\frac{N_{c_k,x_i}+\alpha}{N_{c_k}+n\alpha}}P(X(j)=x(j)∣Y=ck​)=Nck​​+nαNck​,xi​​+α​

其中NckN_{c_k}Nck​​是类别ckc_kck​的样本个数,nnn是特征维数,Nck,xiN_{c_k,x_i}Nck​,xi​​是类别ckc_kck​的样本中,第iii维特征值是xix_ixi​的样本个数,α\alphaα是平滑值。

当**α=1\alpha=1α=1时,称作Laplace平滑Laplace平滑Laplace平滑

当0&lt;α&lt;10&lt;\alpha&lt;10<α<1时,称作Lidstone平滑Lidstone平滑Lidstone平滑**;

当α=0\alpha=0α=0时,不做平滑处理。

高斯模型

高斯模型 GaussianNB

特征的可能性被假设为高斯

其概率密度函数:

P(xi∣yk)=12πσyk2exp(−(xi−μyk)22σyk2)P(x_i | y_k)=\frac{1}{\sqrt{2\pi\sigma^2_{yk}}}exp(-\frac{(x_i-\mu_{yk})^2}{2\sigma^2_{yk}})P(xi​∣yk​)=2πσyk2​​1​exp(−2σyk2​(xi​−μyk​)2​)

数学期望(mean):μ\muμ

方差:σ2=∑(X−μ)2N\sigma^2=\frac{\sum(X-\mu)^2}{N}σ2=N∑(X−μ)2​

伯努利模型

与多项式模型一样,伯努利模型适用于离散特征的情况,所不同的是,伯努利模型中每个特征的取值只能是1和0.(举例说明:在文本分类中,某个单词在文档中出现过,则其特征值为1,否则为0)

在伯努利模型中,条件概率P(X(j)=x(j)∣Y=ck)P(X^{(j)}=x^{(j)}|Y=c_k)P(X(j)=x(j)∣Y=ck​)的计算方式如下:

当特征值x(j)=1x^{(j)}=1x(j)=1时,P(X(j)=x(j)∣Y=ck)=P(X(j)=1∣Y=ck)P(X^{(j)}=x^{(j)}|Y=c_k)=P(X^{(j)}=1|Y=c_k)P(X(j)=x(j)∣Y=ck​)=P(X(j)=1∣Y=ck​)

当特征值x(j)=0x^{(j)}=0x(j)=0时,P(X(j)=x(j)∣Y=ck)=1−P(X(j)=1∣Y=ck)P(X^{(j)}=x^{(j)}|Y=c_k)=1-P(X^{(j)}=1|Y=c_k)P(X(j)=x(j)∣Y=ck​)=1−P(X(j)=1∣Y=ck​)

多项式模型的朴素贝叶斯分类器实现代码

下面是是scikit-learn库中多项式模型的朴素贝叶斯分类器实现代码

案例代码已上传:Github地址

"""API Reference: http://scikit-/stable/modules/naive_bayes.html#naive-bayes定义一个MultinomialNB类"""import numpy as npclass MultinomialNB(object):def __init__(self,alpha=1.0,fit_prior=True,class_prior=None):"""多项式模型的朴素贝叶斯分类器。多项式朴素贝叶斯分类器适用于具有离散特征的分类。参数----------alpha : 平滑参数(float类型),默认为1.0;如果alpha=0则不平滑。如果 0 < alpha < 1 则为Lidstone平滑如果 alpha = 1 则为Laplace 平滑 fit_prior : 布尔型是否学习类别先验概率。如果设置为False,将使用统一的优先权。class_prior : array-like, size (n_classes,)类别的先验概率。如果指定,则不会根据数据调整优先级。"""self.alpha = alphaself.fit_prior = fit_priorself.class_prior = class_priorself.classes = Noneself.conditional_prob = Nonedef _calculate_feature_prob(self,feature):values = np.unique(feature)total_num = float(len(feature))value_prob = {}for v in values:value_prob[v] = (( np.sum(np.equal(feature,v)) + self.alpha ) /( total_num + len(values)*self.alpha))return value_probdef fit(self,X,y):#TODO: check X,yself.classes = np.unique(y)#计算类别先验概率: P(y=ck)if self.class_prior == None:class_num = len(self.classes)if not self.fit_prior:self.class_prior = [1.0/class_num for _ in range(class_num)] #uniform priorelse:self.class_prior = []sample_num = float(len(y))for c in self.classes:c_num = np.sum(np.equal(y,c))self.class_prior.append((c_num+self.alpha)/(sample_num+class_num*self.alpha))#计算条件概率 P( xj | y=ck )self.conditional_prob = {} # like { c0:{ x0:{ value0:0.2, value1:0.8 }, x1:{} }, c1:{...} }for c in self.classes:self.conditional_prob[c] = {}for i in range(len(X[0])): #for each featurefeature = X[np.equal(y,c)][:,i]self.conditional_prob[c][i] = self._calculate_feature_prob(feature)return self#给定values_prob {value0:0.2,value1:0.1,value3:0.3,.. } and target_value#返回target_value的概率def _get_xj_prob(self,values_prob,target_value):return values_prob[target_value]#基于(class_prior,conditional_prob)预测单个样本def _predict_single_sample(self,x):label = -1max_posterior_prob = 0#对于每个类别,计算其后验概率: class_prior * conditional_probfor c_index in range(len(self.classes)):current_class_prior = self.class_prior[c_index]current_conditional_prob = 1.0feature_prob = self.conditional_prob[self.classes[c_index]]j = 0for feature_i in feature_prob.keys():current_conditional_prob *= self._get_xj_prob(feature_prob[feature_i],x[j])j += 1#比较后验概率并更新最大后验概率,标签if current_class_prior * current_conditional_prob > max_posterior_prob:max_posterior_prob = current_class_prior * current_conditional_problabel = self.classes[c_index]return label#样本预测(也可以是单样本预测) def predict(self,X):#TODO1:check and raise NoFitError #ToDO2:check Xif X.ndim == 1:return self._predict_single_sample(X)else:#为每个样本进行分类 labels = []for i in range(X.shape[0]):label = self._predict_single_sample(X[i])labels.append(label)return labels

多项式模型下的朴素贝叶斯分类算法测试:

import numpy as npX = np.array([[1,1,1,1,1,2,2,2,2,2,3,3,3,3,3],[4,5,5,4,4,4,5,5,6,6,6,5,5,6,6]])X = X.Ty = np.array([-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1])nb = MultinomialNB(alpha=1.0,fit_prior=True)nb.fit(X,y)print(nb.predict(np.array([2,4])))#输出-1

高斯模型的朴素贝叶斯分类器实现代码

高斯模型与多项式模型唯一不同的地方就在于计算 P(xi|yk),高斯模型假设各维特征服从正态分布,需要计算的是各维特征的均值与方差。所以我们定义GaussianNB类,继承自MultinomialNB并且重载相应的方法即可。

#GaussianNB differ from MultinomialNB in these two method:# _calculate_feature_prob, _get_xj_probclass GaussianNB(MultinomialNB):#计算给定特征的平均值(mu)和标准偏差(sigma)def _calculate_feature_prob(self,feature):mu = np.mean(feature)sigma = np.std(feature)return (mu,sigma)#高斯分布的概率密度 def _prob_gaussian(self,mu,sigma,x):return ( 1.0/(sigma * np.sqrt(2 * np.pi)) *np.exp( - (x - mu)**2 / (2 * sigma**2)) )#给定mu和sigma,目标值返回高斯分布概率def _get_xj_prob(self,mu_sigma,target_value):return self._prob_gaussian(mu_sigma[0],mu_sigma[1],target_value)

代码案例地址

案例代码已上传:Github地址

参考资料:

[1] 《统计学习方法》

[2]: 朴素贝叶斯算法实现

Github地址/Vambooo/lihang-dl

更多技术干货在公众号:深度学习学研社

如果觉得《统计学习方法笔记(三)-朴素贝叶斯原理及python实现》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。