zoukankan      html  css  js  c++  java
  • 《统计学习方法》学习笔记(3)-- 朴素贝叶斯

    1. 贝叶斯定理

      英国数学家托马斯·贝叶斯(Thomas Bayes)在1763年发表的一篇论文中,首先提出了这个定理。

      A,B表示在一个样本空间中的两个事件,在事件B发生的情况下,事件A发生的概率用P(A|B)表示,它等于事件A,B同时发生的概率除以事件B发生的概率。

      因为:P(AB) = P(A|B) P(B)      P(BA) = P(B|A) P(A),所以:P(A|B) P(B) = P(B|A) P(A),即

     

           假设样本空间是A与A’的和(A’是A的补集),则P(B) = P(B∩A) + P(B∩A’),代入贝叶斯定理即得全概率公式:P(B) = P(B|A)P(A) + P(B|A’)P(A’),所以

     

    2. 朴素贝叶斯方法

      朴素贝叶斯方法是基于贝叶斯定理与特征条件独立假设的分类方法,之所以被称为朴素的(naive)是因为这种方法假设特征条件独立。对于给定的数据训练集,首先基于特征条件独立假设学习输入/输出的联合概率分布;然后基于此模型,对给定的输入x,求出后验概率最大的输出y。

      训练数据集:

          

      先验概率分布P(Y = ck)   k=1, 2, …, K 的条件概率分布

          

      后验概率根据贝叶斯定理进行:

                     

      由于朴素贝叶斯方法对条件概率分布做了条件独立性的假设,所以有

           

      这就是朴素贝叶斯分类法的基本公式。由于上式中分母对所有ck都是相同的,于是贝叶斯分类器可表示为:

          

           当某个特征项x(j)没有出现划分时,会出现P(X(j)= x(j)|Y=ck)=0的情况,这会影响后验概率的计算结果,解决这一问题的方式是采用贝叶斯估计:

          

           Sj为x(j)的取值个数,常取λ=1,这时称为拉普拉斯平滑。同样,先验概率的贝叶斯估计是:

                  N为样本数量,K为ck的取值个数。

    3. 代码

    #《统计学习方法》,例4.1,4.2代码
    from numpy import *
    
    def trainNB(dataList, labelList):
        dimension = len(dataList[0])
        dataSet = []                        
        for i in range(dimension):
            dataSetIdim = set([])
            for example in dataList:
                dataSetIdim = dataSetIdim | set([example[i]])
            dataSetIdim = list(dataSetIdim)
            dataSet.append(dataSetIdim)
        print(dataSet)
    
        p1Num = []; p0Num = []
        i=0
        for i in range(dimension):
            p0NumIdim = zeros(len(dataSet[i]))
            p1NumIdim = zeros(len(dataSet[i]))
            j=0
            for j in range(len(dataList)):
                flagList = zeros(len(dataSet[i]))
                flagList[dataSet[i].index(dataList[j][i])] = 1
                if labelList[j] == 1:
                    p1NumIdim = p1NumIdim + flagList
                else:
                    p0NumIdim = p0NumIdim + flagList
            p1NumIdim = list(p1NumIdim); p0NumIdim = list(p0NumIdim)
            p1Num.append(p1NumIdim)
            p0Num.append(p0NumIdim)
        print(p1Num, p0Num)
        return dataSet, p1Num, p0Num
    
    def testingNB(testData, dataSet, p1Num, p0Num, num1, num0):
        p1 = num1/(num1+num0)
        p0 = num0/(num1+num0)
        for i in range(len(testData)):
            p1 = p1*(p1Num[i][dataSet[i].index(testData[i])]/num1)
            p0 = p0*(p0Num[i][dataSet[i].index(testData[i])]/num0)
        print("naive bayes: P(1)=",p1," P(0)=",p0)
        if(p1 > p0):
            str = "classefied as 1"
        else:
            str = "classified as 0"
        print(str)
    
    def testingNBwithLS(testData, dataSet, p1Num, p0Num, num1, num0):  #with laplace smoothing
        p1 = (num1+1)/(num1+num0+2)
        p0 = (num0+1)/(num1+num0+2)
        for i in range(len(testData)):
            p1 = p1*((p1Num[i][dataSet[i].index(testData[i])]+1)/(num1+len(dataSet[i])))
            p0 = p0*((p0Num[i][dataSet[i].index(testData[i])]+1)/(num0+len(dataSet[i])))
        print("naive bayes with Laplace smoothing: P(1)=",p1," P(0)=",p0)
        if(p1 > p0):
            str = "classefied as 1"
        else:
            str = "classified as 0"
        print(str)
        
    def test(testData=[2,'S']):
        dataList = [[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']]
        labelList = [0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0]
        
        dataSet, p1Num, p0Num = trainNB(dataList, labelList)
        num1 = labelList.count(1)
        num0 = labelList.count(0)
        testingNB(testData, dataSet, p1Num, p0Num, num1, num0)
        testingNBwithLS(testData, dataSet, p1Num, p0Num, num1, num0)

      代码输出:

      >>> import bayes
      >>> bayes.test()
      [[1, 2, 3], ['S', 'M', 'L']]
      [[2.0, 3.0, 4.0], [1.0, 4.0, 4.0]] [[3.0, 2.0, 1.0], [3.0, 2.0, 1.0]]
      naive bayes: P(1)= 0.0222222222222 P(0)= 0.0666666666667
      classified as 0
      naive bayes with Laplace smoothing: P(1)= 0.0326797385621 P(0)= 0.0610021786492
      classified as 0

    4. 扩展阅读:

    贝叶斯推断及其互联网应用. http://www.ruanyifeng.com/blog/2011/08/bayesian_inference_part_one.html

    数学之美番外篇:平凡而又神奇的贝叶斯方法. http://mindhacks.cn/2008/09/21/the-magical-bayesian-method/

    分类算法之朴素贝叶斯分类. http://www.cnblogs.com/leoo2sk/archive/2010/09/17/1829190.html

  • 相关阅读:
    姿态估计openpose_pytorch_code浅析(待补充)
    姿态估计之Openpose_原理部分
    win10基础上安装linux系统,添加双系统启动项
    mongodb集群部署
    心无旁骛提升自我
    sqlserver2012 数据库差异备份恢复 记录
    pgsql 常用命令
    pgadmin连接 postgresql远程设置
    vmvare使用桥接和NAT方式连接网络
    使用samba 共享Linux文件到Windows
  • 原文地址:https://www.cnblogs.com/thelongroad/p/3150055.html
Copyright © 2011-2022 走看看