【统计学习方法】第四章 朴素贝叶斯

模型定位:朴素贝叶斯属于分类模型、生成模型
GitHub地址

基本概念

  • 条件概率: P ( A ∣ B ) = P ( A B ) P ( B ) P(A|B)=\frac{P(AB)}{P(B)} P(AB)=P(B)P(AB)
  • 乘法公式: P ( A B ) = P ( A ∣ B ) ∗ P ( B ) P(AB)=P(A|B)*P(B) P(AB)=P(AB)P(B)
  • 贝叶斯公式: P ( Y ∣ X ) = P ( X ∣ Y ) ∗ P ( Y ) P ( X ) P(Y|X)=\frac{P(X|Y)*P(Y)}{P(X)} P(YX)=P(X)P(XY)P(Y)
  • 后验概率【指定了条件的条件概率】:
    • 概念: P ( Y = y i ∣ X = x ) P(Y=y_i|X=x) P(Y=yiX=x),已知X=x,求Y=yi发生的概率
    • 计算公式: P ( Y = y i ∣ X = x ) = P ( X = x ∣ Y = y i ) ∗ P ( Y = y i ) ∑ y i P ( X = x ∣ Y = y i ) ∗ P ( Y = y i ) P(Y=y_i|X=x)=\frac{P(X=x|Y=y_i)*P(Y=y_i)}{\sum{y_i}P(X=x|Y=y_i)*P(Y=y_i)} P(Y=yiX=x)=yiP(X=xY=yi)P(Y=yi)P(X=xY=yi)P(Y=yi)
    • 推导: P ( Y = y i ∣ X = x ) = P ( X = x ∣ Y = y i ) ∗ P ( Y = y i ) P ( X = x ) P(Y=y_i|X=x)=\frac{P(X=x|Y=y_i)*P(Y=y_i)}{P(X=x)} P(Y=yiX=x)=P(X=x)P(X=xY=yi)P(Y=yi) [贝叶斯公式] = P ( X = x ∣ Y = y i ) ∗ P ( Y = y i ) ∑ y i P ( X = x ∣ Y = y i ) ∗ P ( Y = y i ) =\frac{P(X=x|Y=y_i)*P(Y=y_i)}{\sum_{y_i}P(X=x|Y=y_i)*P(Y=y_i)} =yiP(X=xY=yi)P(Y=yi)P(X=xY=yi)P(Y=yi)[全概率公式]

算法原理

思路:在分类问题中,给定特征x,想知道x对应的类别y是什么。根据前述基本概念可知,后验概率计算的结果就是给定条件x,Y=yi的概率。假设有k个类别: y i , i = 1 , . . . , k y_i,i=1,...,k yi,i=1,...,k,计算每个yi对应的后验概率 P ( Y = y i ∣ X = x ) P(Y=y_i|X=x) P(Y=yiX=x),后验概率最大的yi就是我们求得的结果。

X ⊆ R n , n > 1 X\subseteq{R^n},n>1 XRn,n>1时,条件概率 P ( X = ( x 1 , x 2 , . . . , x n ) ∣ Y = y i ) P(X=(x_1,x_2,...,x_n)|Y=y_i) P(X=(x1,x2,...,xn)Y=yi)将随着n指数增长。因此,朴素贝叶斯对条件概率分布做了条件独立性假设: P ( X = ( x 1 , x 2 , . . . , x n ) ∣ Y = y i ) = ∏ j = 1 n P ( X j = x i j Y = y i ) P(X=(x_1,x_2,...,x_n)|Y=y_i)=\prod_{j=1}^{n}P(X_j=x_ijY=y_i) P(X=(x1,x2,...,xn)Y=yi)=j=1nP(Xj=xijY=yi),这也是朴素贝叶斯名称的由来。

所以,朴素贝叶斯分类器可以表示为: y = f ( x ) = arg max ⁡ y i P ( Y = y i ) ∗ ∏ i = j = 1 n P ( X j = x j ∣ Y = y j ) ∑ i = 1 k P ( Y = y i ) ∗ ∏ i = j = 1 n P ( X j = x j ∣ Y = y i ) y=f(x)=\argmax_{y_i}\frac{P(Y=y_i)*\prod_{i=j=1}^{n}P(X_j=x_j|Y=y_j)}{\sum_{i=1}^kP(Y=y_i)*\prod_{i=j=1}^{n}P(X_j=x_j|Y=y_i)} y=f(x)=yiargmaxi=1kP(Y=yi)i=j=1nP(Xj=xjY=yi)P(Y=yi)i=j=1nP(Xj=xjY=yj)

此外,给定x,分母 P ( X = x ) = ∑ i = 1 k P ( Y = y i ) ∗ ∏ i = j = 1 n P ( X j = x j ∣ Y = y i ) P(X=x)=\sum_{i=1}^kP(Y=y_i)*\prod_{i=j=1}^{n}P(X_j=x_j|Y=y_i) P(X=x)=i=1kP(Y=yi)i=j=1nP(Xj=xjY=yi)对所有yi都是一样的,因此,在计算时,只需求解 y ~ = arg max ⁡ y i P ( Y = y i ) ∗ ∏ i = j = 1 n P ( X j = x j ∣ Y = y j ) \widetilde{y}=\argmax_{y_i}P(Y=y_i)*\prod_{i=j=1}^{n}P(X_j=x_j|Y=y_j) y =yiargmaxP(Y=yi)i=j=1nP(Xj=xjY=yj)即可。

!!后验概率最大化 等于 期望风险最小化【证明略】
!!本质是学习了X和Y的联合分布

朴素贝叶斯的参数估计——极大似然估计

极大似然估计的通俗解释:当样本数趋于无穷时,频率趋近于概率

算法步骤

  1. 先计算先验概率 P ( Y = y i ) = ∑ c = 1 m I ( y c = y i ) m P(Y=y_i)=\frac{\sum_{c=1}^mI(y_c=yi)}{m} P(Y=yi)=mc=1mI(yc=yi),m为样本个数,yc表示第c个样本的y值;【本质:计算频率】
  2. 在计算条件概率【公式暂略】
  3. 求解 y ~ = arg max ⁡ y i P ( Y = y i ) ∗ ∏ i = j = 1 n P ( X j = x j ∣ Y = y j ) \widetilde{y}=\argmax_{y_i}P(Y=y_i)*\prod_{i=j=1}^{n}P(X_j=x_j|Y=y_j) y =yiargmaxP(Y=yi)i=j=1nP(Xj=xjY=yj)确定分类

python实现

这里使用pandas的Dataframe格式,目的是避免for循环

'''
author : superpig99
date : 2021/12/11
'''
import pandas as pd
class naiveBayes:
    def __init__(self):
        pass
    def fit(self,data,label='y'): ## 学习联合分布
        # 还没实现异常处理
        # if not isinstance(data, pd.DataFrame):
        #     print('please input DataFrame')
        #     return
        # if not label in data.columns:
        #     print('please set name of label')
        #     return
        y_tmp = data.groupby(label).count() # 聚合,得到每个类别的频数
        self.prob_y = (y_tmp.iloc[:,0]).to_dict() ## 将dataframe转换为dict
        self.prob_x = {} # 初始化特征的频数
        # 对每一维特征xi
        for xi in data.columns:
            if xi!=label: # 排除y
                xi_tmp = data.groupby([label,xi]).count() # 按照y和xi进行聚类求和,得到对应频数
                val = xi_tmp.iloc[:,0].to_dict() ## 将dataframe转换为dict,该字典为该维的频数
                self.prob_x[xi] = val # 将该字典加入到prob_x中
        print(self.prob_x)
        return

    def predict(self,X): ## 预测
        n,res = len(X.columns),[] # n为特征维数,res为返回结果
        for x in X.values: # 对每个样本
            y_prob, cls = 0,None # 初始化该样本对应的后验概率和输出类别
            for c in self.prob_y.keys(): # 对每个类别,计算后验概率
                prob = 1 # 初始化后验概率为1
                for i in range(n): # 对每一维特征,开始连乘
                    prob *= self.prob_x[X.columns[i]][(c,x[i])]/self.prob_y[c] # 频数相除,得到频率,即条件概率P(X=xi|Y=c)
                tmp = prob*self.prob_y[c]
                if tmp>y_prob: # 取最值
                    y_prob = tmp
                    cls = c
            res.append(cls)
        return res

if __name__ == '__main__':
    ## 测试样例来自《统计学习方法》P63
    trainSet = pd.DataFrame({'x1':[1,1,1,1,1,2,2,2,2,2,3,3,3,3,3],\
                             'x2':['S','M','M','S','S','S','M','M','L','L','L','M','M','L','L'],\
                             'y':[-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1]})
    testSet = pd.DataFrame({'x1':[2],'x2':['S'],'y':[-1]})
    mod = naiveBayes()
    mod.fit(trainSet)
    print('res: ', mod.predict(testSet.iloc[:,:-1]))

prob_x长这样:
在这里插入图片描述
结果:
在这里插入图片描述
*btw:这里,我采用的是dataframe避免了for循环,如果有更好的写法,请指教!

你可能感兴趣的:(统计学习方法,机器学习,分类,算法)