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

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

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

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

基本概念
  • 条件概率: P ( A ∣ B ) = P ( A B ) P ( B ) P(A|B)=frac{P(AB)}{P(B)} P(A∣B)=P(B)P(AB)​
  • 乘法公式: P ( A B ) = P ( A ∣ B ) ∗ P ( B ) P(AB)=P(A|B)*P(B) P(AB)=P(A∣B)∗P(B)
  • 贝叶斯公式: P ( Y ∣ X ) = P ( X ∣ Y ) ∗ P ( Y ) P ( X ) P(Y|X)=frac{P(X|Y)*P(Y)}{P(X)} P(Y∣X)=P(X)P(X∣Y)∗P(Y)​
  • 后验概率【指定了条件的条件概率】:
    • 概念: P ( Y = y i ∣ X = x ) P(Y=y_i|X=x) P(Y=yi​∣X=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=yi​∣X=x)=∑yi​P(X=x∣Y=yi​)∗P(Y=yi​)P(X=x∣Y=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=yi​∣X=x)=P(X=x)P(X=x∣Y=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)} =∑yi​​P(X=x∣Y=yi​)∗P(Y=yi​)P(X=x∣Y=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=yi​∣X=x),后验概率最大的yi就是我们求得的结果。

当 X ⊆ R n , n > 1 Xsubseteq{R^n},n>1 X⊆Rn,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=1n​P(Xj​=xi​jY=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)=yi​argmax​∑i=1k​P(Y=yi​)∗∏i=j=1n​P(Xj​=xj​∣Y=yi​)P(Y=yi​)∗∏i=j=1n​P(Xj​=xj​∣Y=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=1k​P(Y=yi​)∗∏i=j=1n​P(Xj​=xj​∣Y=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 ​=yi​argmax​P(Y=yi​)∗∏i=j=1n​P(Xj​=xj​∣Y=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​)=m∑c=1m​I(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 ​=yi​argmax​P(Y=yi​)∗∏i=j=1n​P(Xj​=xj​∣Y=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循环,如果有更好的写法,请指教!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5659075.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存