朴素贝叶斯

1. 朴素贝叶斯介绍

朴素贝叶斯法是基于贝叶斯定理(P(A|B)=\frac{P(B|A)\cdot P(A)}{P(B)})与特征条件独立假设的分类方法。对于给定的训练数据集,首先基于特征条件独立假设学习输入/输出的联合概率分布;然后基于此模型,对给定的输入x, 利用贝叶斯定理求出后验概率最大的输出y。

2. 朴素贝叶斯特点

优点:在数据较少的情况下仍然有效,可以处理多类别问题

缺点:对于输入数据的准备方式较为敏感。

使用数据类型:标称型数据

3. 朴素贝叶斯法的学习与分类

3.1.1基本方法

       设输入空间X \in R^{n}为n维向量的集合,输出空间为类标记集合Y=\left \{ c_{1},c_{2},...,c_{k} \right \}。输入特征为特征向量x\in X,输出为类标记y\in Yx是定义在输入空间X上面的随机变量,y是定义在输出空间Y上面的随机变量。p\left ( x,y \right )是x和y的联合概率分布,训练集                                                            

                                                        \large T=\left \{ (x_{1},y_{1}),(x_{2},y_{2}),...,(x_{N},y_{N}) \right \}

p\left ( x,y \right )独立同分布产生。

        朴素贝叶斯法通过训练数据集学习联合概率分布p\left ( x,y \right )。具体地,学习以下先验概率分布和条件概率分布。先验概率分布:

                                                        p(Y=c_{k}),\quad \quad k=1,2,...,K \quad \quad \quad (3.1)

条件概率分布

                                                        p(X=x|Y=c_{k})=p(X^{(1)}=x^{(1)},...,X^{(n)}=x^{(n)}|Y=c_{k}),\quadk=1,2,...K \quad \quad (3.2)

于是就学到了联合概率分布p\left ( x,y \right )

         条件概率有指数级数量的参数,其估计实际是不可行的。事实上,假设,假设x^{(j)}可取值有S_{j}个,j=1,2,...,n,Y可取值有K个,那么参数个数为    K\prod_{j=1}^{n}S_{j}.

\LARGE \Rightarrowx^{(j)}可取值有S_{j}个,可知

                                                                     x^{(1)}\rightarrow S_{1} 个取值;

                                                                      x^{(2)}\rightarrow S_{2} 个取值

                                                                      ......

                                                                      x^{(j)}\rightarrow S_{j} 个取值

又由于 

                                 p(X=x|Y=c_{k})=p(X^{(1)}=x^{(1)},...,X^{(n)}=x^{(n)}|Y=c_{k})

\LARGE \Rightarrow                         p(X=x|Y=c_{k})=p(X^{(1)}=x^{(1)},...,X^{(n)}=x^{(n)}|Y=c_{k}) \vspace{=p(X^{(1)}=x^{(1)}|Y=c_{k})\cdot p(X^{(2)}=x^{(2)}|Y=c_{k})\cdot ....\cdot p(X^{(n)}=x^{(n)}|Y=c_{k})} \vspace{=\prod_{j=1}^{n} p(X^{(j)}=x^{(j)}|Y=c_{k}) \quad\quad \quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad(3.3)}

 

\LARGE \Rightarrow参数个数为

                                           S_{1} \cdot S_{2} \cdot S_{3}\cdot ... \cdot S_{j} \cdot K =K\prod_{j=1}^{n}s_{j}

 

关于朴素贝叶斯的条件独立性假设的理解:

朴素贝叶斯分类时,对于给定的输入x的,通过学习到的模型计算后验概率 分布p(Y=c_{k}|X=x),将后验概率最大的类作为x的类输出。后验概率计算根据贝叶斯定理可知:

                                     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})} \quad \quad \quad \quad(3.4)

推导过程如下:

由贝叶斯定理得 

                                      p(Y=c_{k}|X=x)=\frac{p(X=x|Y=c_{k})p(Y=c_{k})}{p(X=x)}

根据全概率公式可知

                                      p(X=x)=\sum_{k}^{ }p(X=x|Y=c_{k})p(Y=c_{k}),k=1,2,...,K

所以可知

                                     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})},\quad k=1,2,...,K (3.5)

将式(3.3)带入式(3.4)得

                       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}) }

这是朴素贝叶斯分类的基本公式,于是有朴素贝叶斯分类器可表示为

                      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}) },\quad \quad (3.6)

又因为,在式中(3.7)分母对所有的c_{k}都是相同的,所以

                        y=\arg \max_{c_{k}}p(Y=c_{k})\prod_{j}p(X^{(j)}=x^{(j)}|Y=c_{k}),\quad \quad (3.6)

4.1.2后验概率最大化的含义

     假设选择0-1损失函数:

                                           L(Y,f(X))=\left\{\begin{matrix} 1, \quad Y\neq f(X)\\ 0, \quad Y=f(X) \end{matrix}\right.

式中f(X)是分类决策函数。这时,期望风险函数为

                                           R_{exp}(f)=E\left [ L(Y,f(X)) \right ]

期望是对联合分布p(X,Y)取的,由此条件期望为

                                           R_{exp}(f)=E_{X}\sum_{k=1}^{K}\left [ L(c_{k},f(X)) \right ]p(c_{k}|X)

具体这一步是怎么来的呢,如下所示:

                                   

      要是期望风险最小,也就是这个图中的积分最小,那么对于任意的一个X=x在P(X=x)为常数条件下内层积分最小,即期望风险最小等价于条件期望最小。

而为了使得期望风险最小化,只需对X=x逐个极小化,则有:

                                       

 \huge \Rightarrow由期望风险最小化就可以得到后验概率最大化准则:

                                                                \large f(x)=\arg \max_{c_{k}}p(c_{k}|X=x)

也就是朴素贝叶斯所采用的原理。

 

4. 朴素贝叶斯法的参数估计

4.1 极大似然估计

在朴素贝叶斯学习中,学习意味着估计\large p(Y=c_{k})\large p(x^{(j)}=x^{(j)}|Y=c_{k})。可以应用极大似然估计法估计相应的概率。先验概率\large p(Y=c_{k})的极大似然估计是

                                                              \large p(Y=c_{k})=\frac{\sum_{i=1}^{N}I(y_{i}=c_{k})}{N},\quad k=1,2,...,K \quad \quad \quad (4.1)

设第j个特征\large x^{(j)}可能取值的集合为\large \left \{ a_{j1},a_{j2},...,a_{js_{j}} \right \},条件概率\large p(X^{(j)}=a_{jl}|Y=c_{k})的极大似然估计是

                                                \large p(X^{(j)}=a_{jl}|Y=c_{k})=\frac{\sum_{i=1}^{N}I(x^{(j)}=a_{jl},y_{i}=c_{k})}{\sum_{i=1}^{N}I(y_{i}=c_{k})}

                                                \large j=1,2,...,n;\quad l=1,2,...,S_{j};\quad k=1,2,...,K \quad \quad \quad (4.2)                           

式中,\large x_{i}^{(j)}是第i个样本的第j个特征;\large a_{jl}是第j个特征可能取的第\large l个值;\large I为指示函数。

4.2 学习与分类算法

输入:训练数据

                                               \large T=\left \{ (x_{1},y_{1}),(x_{2},y_{2}),...,(x_{N},y_{N}) \right \}

其中\large x_{i}=(x_{1}^{(1)},x_{2}^{(2)},...,x_{i}^{(n)})^{\mathrm{T}}\large x_{i}^{(j)}是第i个样本的第j个特征,\large x_{i}^{(j)}\in \left \{ a_{j1},a_{j2},...,a_{jS_{j}} \right \}\large a_{jl}是第j个特征可能取的第\large l个值,\large j=1,2,...,n,l=1,2,...,S_{j},\quad y_{i}\in \left \{ c_{1},c_{2},...,c_{k} \right \};实例\large x

输出:实例\large x的分类。

(1)计算先验概率及条件概率

                   先验概率:         \large p(Y=c_{k})=\frac{\sum_{i=1}^{N}I(y_{i}=c_{k})}{N},\quad k=1,2,...,K

                  条件概率:          \large p(X^{(j)}=a_{jl}|Y=c_{k})=\frac{\sum_{i=1}^{N}I(x^{(j)}=a_{jl},y_{i}=c_{k})}{\sum_{i=1}^{N}I(y_{i}=c_{k})}

                                            \large j=1,2,...,n;\quad l=1,2,...,S_{j};\quad k=1,2,...,K

(2)对于给定的实例\large x=(x^{(1)},x^{(2)},...,x^{(n)})^{\mathrm{T}},计算

                                           \large p(Y=c_{k})\prod _{j=1}^{n}p(X^{(j)}=x^{(j)}|Y=c_{k}),\quad \quad k=1,2,...,K

(3)确定实例\large x的类

                                          \large y=\arg\max_{c_{k}}p(Y=c_{k})\prod_{j=1}^{n}p(X^{(j)}=x^{(j)}|Y=c_{k})

例1.试由表1的训练数据学习朴素贝叶斯分类器并确定\large x=(2,S)^{\mathrm{T}}的类标记\large y,表中\large X^{(1)},X^{(2)}为特征,取值的集合分别为

\large A_{1}={1,2,3},A_{2}=\left \{ S,M,L \right \},Y 为类标记,\large Y\in C=\left \{ 1, -1 \right \}

                                                                                       表1   训练数据

解答如下:

 

代码如下:

#!/usr/bin/env python3
#coding=utf-8

import numpy as np

class NaiveBeyes(object):
    #获取训练数据
    def getTrainSet(self):
        dataSet=np.array([[1,'S'],[1,'M'],[1,'M'],[1,'S'],[1,'S'],[2,'S'],[2,'M'],[2,'M'],[2,'L'],[2,'L'],[3,'L'],        [3,'M'],[3,'M'],[3,'L'],[3,'L']])
        labels=[-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1]
        return dataSet,labels

    def classify(self,trainData,labels,features):
        #先计算先验概率
        #用于存放不同类别的先验概率
        labelProb={}
        for label in labels:
            labelProb[label]=labels.count(label)/float(len(labels))

        #计算特征和标签同时发生的概率
        # 用来存放特征和标签同时发生时的概率
        p_xy = {}
        for tagvalue in labelProb.keys():

            #获取Labels中出现tagvalue值的所有数值的下标索引
            tagvalueIndex=[index for index,label in enumerate(labels) if label==tagvalue]
            for i in range(len(features)):
                #获取features中的值在训练集中出现的所有下标索引
                x_index=[index for index,feature in enumerate(trainData[:,i]) if feature==features[i]]
                xy_count=len(set(tagvalueIndex) & set(x_index)) #如果它们索引相同,说明它们特征和标签同时发生
                key=str(features[i])+'*'+str(tagvalue)
                p_xy[key]=xy_count/float(len(labels))

        #计算条件概率
        #创建空字典,并将条件概率存入其中
        prob={}
        for tagvalue in labelProb.keys():
            for feature in features:
                pkey=str(feature)+'|'+str(tagvalue)
                prob[pkey]=p_xy[str(feature)+'*'+str(tagvalue)]/float(labelProb[tagvalue])

        #计算[2,S]所属类别
        #创建空字典用于存放[2,S]所属不同类别的概率
        resultProb={}
        for tagvalue in labelProb.keys():
            resultProb[tagvalue]=labelProb[tagvalue]
            for x in features:
                resultProb[tagvalue]=resultProb[tagvalue]*prob[str(x)+'|'+str(tagvalue)]
        #max(dict,key=dict.get)表示获取字典中值最大所对应的键
        result_feature=max(resultProb,key=resultProb.get)
        return result_feature

if __name__=='__main__':
    NB=NaiveBeyes()
    #训练数据
    trainData,labels=NB.getTrainSet()
    features=np.array([2,'S'])
    result=NB.classify(trainData,labels,features)
    print("[2,'S']的类别标记为:{}".format(result))


4.3贝叶斯估计

用极大似然估计可能会出现所要估计的概率值为0的情况,这时会影响到后验概率的计算结果,使分类产生偏差。解决这一问题的方法是采用朴素贝叶斯估计。具体的是如下所示:

                          \large p_{\lambda }(X^{(j)}=a_{jl}|Y=c_{k})=\frac{\sum_{i=1}^{N}I(x_{i}^{(j)}=a_{jl},y_{i}=c_{k})+\lambda }{\sum_{i=1}^{N}I(y_{i}=c_{k})+S_{j} \lambda } \quad (4.3)

式中\large \lambda \geq 0。等价于在随机变量各个取值的频数上赋值一个正数\large \lambda >0。当\large \lambda =0时就是极大似然估计。常取\large \lambda =1,这时称为拉普拉斯平滑。显然,对于任何l=1,2,...,S_{j},\quad k=1,2,...,K,有

                                                                  \large p_{\lambda }(X^{(j)}=a_{jl}|Y=c_{k})> 0

                                                                \large \sum _{l=1}^{S_{j}}p(X^{(j)}=a_{jl}|Y=c_{k})= 1

表明式(4.3)确实是一个概率分布,同时,先验概率的贝叶斯估计为

                                                            \large p_{\lambda }(Y=c_{k})=\frac{\sum_{i=1}^{N}I(y_{i}=c_{k})+\lambda }{N+K\lambda } \quad \quad(4.4)

这里的K应该是指类别数

例2. 同例1,按照拉普拉斯平滑估计概率,即取\large \lambda =1

 解答过程如下:

           

代码如下:

#!/usr/bin/env python3
#coding=utf-8

import numpy as np

class NaiveBeyes(object):
    #初始化K,j,λ值
    def __init__(self):
        self.D=1 #表示λ=1
        self.K=2
        self.S=3
    #获取训练数据
    def getTrainSet(self):
        dataSet=np.array([[1,'S'],[1,'M'],[1,'M'],[1,'S'],[1,'S'],[2,'S'],[2,'M'],[2,'M'],[2,'L'],[2,'L'],[3,'L'],[3,'M'],[3,'M'],[3,'L'],[3,'L']])
        labels=[-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1]
        return dataSet,labels

    def classify(self,trainData,labels,features):
        #先计算先验概率
        #用于存放不同类别的先验概率
        labelProb={}
        for label in labels:
            labelProb[label]=(labels.count(label)+self.D)/float(len(labels)+self.K*self.D)

        #计算条件概率
        # 用来存放特征和标签同时发生时的概率
        prob = {}
        for tagvalue in labelProb.keys():
            #获取labels中出现tagvalue值的所有数值的下标索引
            tagvalueIndex=[index for index,label in enumerate(labels) if label==tagvalue]
            #获取labels中每个标签出现的个数
            tagvalueCount=labels.count(tagvalue)
            for i in range(len(features)):
                #获取features中的值在训练集中出现的所有下标索引
                x_index=[index for index,feature in enumerate(trainData[:,i]) if feature==features[i]]
                xy_count=len(set(tagvalueIndex) & set(x_index)) #如果它们索引相同,说明它们特征和标签同时发生
                key=str(features[i])+'|'+str(tagvalue)
                prob[key]=(xy_count+self.D)/float(tagvalueCount+self.S*self.D)


        #计算[2,S]所属类别
        #创建空字典用于存放[2,S]所属不同类别的概率
        resultProb={}
        for tagvalue in labelProb.keys():
            resultProb[tagvalue]=labelProb[tagvalue]
            for x in features:
                resultProb[tagvalue]=resultProb[tagvalue]*prob[str(x)+'|'+str(tagvalue)]
        #max(dict,key=dict.get)表示获取字典中值最大所对应的键
        result_feature=max(resultProb,key=resultProb.get)
        return result_feature

if __name__=='__main__':
    NB=NaiveBeyes()
    #训练数据
    trainData,labels=NB.getTrainSet()
    features=np.array([2,'S'])
    result=NB.classify(trainData,labels,features)
    print("[2,'S']的类别标记为:{}".format(result))

 

 

 

 

                                                              

                                                      

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值