掌握贝叶斯决策论的原理、朴素贝叶斯分类器的推导过程以及实现方法
贝叶斯决策是分类问题中最为常见的方法之一,是在概率框架下实现决策的基本方法,其根本思想就是帮助人们在已知条件下做出一个最佳决策
贝叶斯决策基于一个基本的公式:
p ( x ∣ y ) p(x|y) p(x∣y)= p ( x ) ∗ p ( y ∣ x ) p ( y ) \frac{p(x)*p(y|x)}{p(y)} p(y)p(x)∗p(y∣x)
先验概率:指事情没有发生之前,仅仅凭借自己的主观经验得出的概率,可以将这个概率看作是一个猜测值
如:在没有抛硬币之前,如果问我们硬币正面朝上的概率是多少,都会回答说是0.5,这个概率是我们通过经验学习得到的,就是先验概率
后验概率: 是指事情发生之后,我们去求这个事件发生是由某个原因引起的可能性大小。(即事情已经发生了,我们现在需要找出导致这件事情发生的原因)
设已发生事件为 A A A,可能导致其发生的原因为 B B B,则后验概率为:
P ( A ∣ B ) P(A|B) P(A∣B)
后验概率起了这样一个用途,根据一些发生的事实,分析结果产生的最可能的原因,然后才能有针对性地去解决问题
极大似然估计就是根据结果信息,反推最有可能出现的参数,也就是常说的 "模型已有,参数未知"
对于 P ( x ∣ θ ) P(x|\theta) P(x∣θ)这个函数:
1.若 θ \theta θ已知,x未知:即为求解在特定模型下样本点x出现的概率
2.若 θ \theta θ未知,x已知:即为求解在不同的模型中,样本点x出现的概率,这也就是似然函数(已知结果,求解模型)
最大似然函数就是求 使 P ( x ∣ θ ) P(x|\theta) P(x∣θ)最大的 θ \theta θ
(极大似然的思想是:既然事情已经发生了,我们就使他发生的概率最大)
举个栗子:
硬币上抛的实验,抛了100次之后有70次硬币是向上的,我们需要求硬币正面朝上的概率。
设抛了100次之后有70次硬币是向上为事件 A A A,根据二项分布,可以得到:
P ( A ) = C 100 70 ( P ) 70 ∗ ( 1 − P ) 30 P(A)=C_{100}^{70} (P)^{70}*(1-P)^{30} P(A)=C10070(P)70∗(1−P)30
也就是说目前模型已知,但是参数 P P P未知,这就是一个似然函数,最大似然函数就是求解是 P ( A ) P(A) P(A)达到最大的 P P P
这里使用二项分布,是 “ 基于每一次抛硬币都是独立的" 的假设,即 似然函数的求解要求 " 每一个样本都是相互独立的 "
令 D c D_c Dc 代表第 c c c类的样本集合,则似然函数的定义为:
P ( D c ∣ θ ) P(D_c|\theta) P(Dc∣θ)= ∏ x ∈ D c P ( x ∣ θ ) \prod_{x \in D_c} P(x|\theta) ∏x∈DcP(x∣θ)
我们要求的就是使 P ( D c ∣ θ ) P(D_c|\theta) P(Dc∣θ)最大的 θ \theta θ
设 λ i j \lambda_{ij} λij表示将真实标签为 j j j 类的样本分为 i i i 类的的损失函数, P ( C j ∣ x ) P(C_j|x) P(Cj∣x)表示样本 x x x被分到 C j C_j Cj类的概率
则被最终被分到 C i C_i Ci类条件损失函数为:
R ( C i ∣ x ) R(C_i|x) R(Ci∣x)= ∑ j λ i j ∗ P ( C j ∣ x ) \sum_j\lambda_{ij}*P(C_j|x) ∑jλij∗P(Cj∣x)
对于损失函数 λ i j \lambda_{ij} λij,我们设:
λ i j \lambda_{ij} λij= { 0 , i = j 1 , i ≠ j \begin{cases} 0,i=j\\ 1,i \neq j\\ \end{cases} {0,i=j1,i=j
带入原式可得:
R ( C i ∣ x ) R(C_i|x) R(Ci∣x)= P ( C 1 ∣ x ) + P ( C 2 ∣ x ) + P ( C 3 ∣ x ) + . . . P ( C i − 1 ∣ x ) + P ( C i + 1 ∣ x ) + . . . P ( C n ∣ x ) P(C_1|x)+P(C_2|x)+P(C_3|x)+...P(C_{i-1}|x)+P(C_{i+1}|x)+...P(C_n|x) P(C1∣x)+P(C2∣x)+P(C3∣x)+...P(Ci−1∣x)+P(Ci+1∣x)+...P(Cn∣x)
=1- P ( C i ∣ x ) P(C_{i}|x) P(Ci∣x)
我们需要最小化条件损失函数,即:
a r g m i n C i ∈ y ( 1 − P ( C i ∣ x ) ) argmin_{C_i \in y}(1-P(C_{i}|x)) argminCi∈y(1−P(Ci∣x))
= a r g m a x C i ∈ y P ( C i ∣ x ) argmax_{C_i \in y}P(C_i|x) argmaxCi∈yP(Ci∣x)
也就是说对于样本 x x x,我们可以通过求它的后验概率,那么得到最大后验概率的那个 C i C_i Ci,就是我们最终得分类结果,也就是说我们的目标是最大化后验概率。
目前求解后验概率的方法有两种:
1.判别式模型: 就是我们常用的机器学习算法(根据已有的数据集建立标签之间的联系)
2.生成式模型: 可以通过联合概率,将后验概率进行转化
P ( C ∣ x ) P(C|x) P(C∣x)= P ( x ∣ C ) P ( C ) p ( x ) \frac{P(x|C)P(C)}{p(x)} p(x)P(x∣C)P(C)
P ( C ) P(C) P(C)即为先验概率, P ( x ∣ C ) P(x|C) P(x∣C)可以通过最大似然函数求出, P ( x ) P(x) P(x)即为该样本出现频次,对 P ( C ∣ x ) P(C|x) P(C∣x)的判断无影响,可以忽略.
1.求解 p(c)
根据西瓜数据集可知:
P(好瓜=是)= 8 17 \frac{8}{17} 178
P(好瓜=否)= 9 17 \frac{9}{17} 179
2.求解极大似然概率
对于离散型变量:
P = ∣ D c , x i ∣ ∣ D c ∣ P=\frac{|D_{c,x_i}|}{|D_{c}|} P=∣Dc∣∣Dc,xi∣
对于连续性变量:
p ( x i ∣ c ) = 1 2 p i ∗ σ c , i ∗ e x p ( − ( x i − u c , i ) 2 2 σ c , i 2 ) p(x_i|c)=\frac{1}{\sqrt{2pi}*\sigma_{c,i}}*exp(\frac{-(x_i-u_{c,i})^2}{2\sigma_{c,i}^2}) p(xi∣c)=2pi∗σc,i1∗exp(2σc,i2−(xi−uc,i)2)
因此,对于离散型变量:
P(色泽=青绿|好瓜=是)= 3 8 \frac{3}{8} 83
P(根蒂=蜷缩|好瓜=是)= 5 8 \frac{5}{8} 85
对于连续型变量:
P(密度=0.697|好瓜=是)=
1 2 p i ∗ 0.129 ∗ e x p ( − ( 0.697 − 0.469 ) 2 2 ∗ 0.12 9 2 ) \frac{1}{\sqrt{2pi}*0.129}*exp(\frac{-(0.697-0.469)^2}{2*0.129^2}) 2pi∗0.1291∗exp(2∗0.1292−(0.697−0.469)2)
( u c , i u_{c,i} uc,i和sigma都是根据 D c , x i D_{c,xi} Dc,xi求出)
求出各个特征的极大似然估计后,进行累乘,得到最终的极大似然估计
(因为这里是朴素贝叶斯分类器,所以我们默认各个特征之间是相互独立的,但是样本中的各个特征实际上是很难做到相互独立的,需要考虑使用半朴素贝叶斯进行分类)
P( x i x_i xi|好瓜=是)=P(色泽=”“|好瓜=是)*P(根蒂=”“|好瓜=是)*P(响声=”“|好瓜=是)*P(硬滑=”“|好瓜=是)*P(密度=""|好瓜=是)*P(甜度=""|好瓜=是)
据 P(c)*P( x i x_i xi|好瓜=是)),可以计算得到当好瓜=“是” 时的后验概率
通过比较好瓜=“是”,好瓜="否"的后验概率大小,即可得到最终的分类标签
1.计算 p(c)
def caculate_pc(label): #不支持test]1]这样的索引方式,只支持test['列名']这样的索引方式)
label_number=list(train_set.iloc[:,-1]).count(label) #计算label的个数
return label_number+1/len(train_set)+N
2.计算 p ( x i ∣ c ) p(x_i|c) p(xi∣c)
def MLE(character,flag,label,test):
mle=0
if flag=='false':#如果是离散型的变量
D,Dc,Ni=0,0,0
for col,grap in train_set.groupby(by='好瓜'):
if col==label:
D=len(grap)
break
for col1,grap1 in grap.groupby(by=character):
if col1==test[character]:
Dc=len(grap1)
Ni+=1
mle=(Dc+1)/(D+Ni) #进行拉普拉斯平滑
if flag=='true':
for col,grap in train_set.groupby(by='好瓜'):
if col==label:
break
u=np.mean(grap[character])
sigma2=np.sum(np.square(grap[character]-u))
mle=(1./(np.sqrt(2*math.pi)*np.sqrt(sigma2)))*np.exp(-np.square(test[character]-u)/(2*sigma2))
return mle
def caculate_MLE(label,test): #计算出某一个类别的MLE
character_MLE=1
column_list=list(X_test.columns) #计算列数,['色泽', '根蒂', '敲声', '纹理', '脐部', '触感', '密度', '甜度']
for i in column_list:
if i in continue_list:#如果该变量是连续性变量 continue_list=['甜度','密度']
character_MLE*=MLE(i,'true',label,test)#累乘
else:
character_MLE*=MLE(i,'false',label,test)
return character_MLE
3.计算后验概率
def pcx(test):
final_dic={} #key:类别 value:计算出后验概率的大小
for i in label_list:
pxc=caculate_MLE(i,test) #计算极大似然概率
pc=caculate_pc(i)
final_dic[i]=pxc*pc #计算后验概率
final_label=sorted(final_dic.items(),key=lambda x:x[1],reverse=True)#选择后验概率最大的标签作为预测标签
print('final_label',final_label)
return final_label[0][0]
4.划分数据集,进行预测
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold
from sklearn.metrics import accuracy_score
X_train,X_test,Y_train,Y_test=train_test_split(data.iloc[:,:-1],data.iloc[:,-1],test_size=0.2,random_state=2)
train_set=pd.concat([X_train,Y_train],axis=1)
predict_label=[]
for i in range(0,len(X_test)):
u=X_test.iloc[i,:]
predict_label.append(pcx(u))#计算后验概率
print(accuracy_score(predict_label,list(Y_test)))