天天看点

朴素贝叶斯条件概率联合概率曲奇饼问题贝叶斯定理贝叶斯分类器朴素贝叶斯分配器代码演示样例:

声明:

         1,本篇为个人对《2012.李航.统计学习方法.pdf》的学习总结,不得用作商用,欢迎转载,但请注明出处(即:本帖地址)。

         2,因为本人在学习初始时有非常多数学知识都已忘记,所以为了弄懂当中的内容查阅了非常多资料,所以里面应该会有引用其它帖子的小部分内容。假设原作者看到能够私信我。我会将您的帖子的地址付到以下。

         3,假设有内容错误或不准确欢迎大家指正。

         4。假设能帮到你,那真是太好了。

条件概率

         其记号为P(A|B)。表示在给定条件B下A事件发生的概率。

                  eg:

                           P(第二次投硬币是正面|第一次投硬币是正面):就是在“第一次投硬币是正面”时“第二次投硬币是正面”的概率。

                            只是。既然举了这个样例,那么就顺带问一下:你以为P(第二次投硬币是正面|第一次投硬币是正面)的结果是多少呢?

                            1/4?错。

                           答案是1/2,是不是非常意外?看完以下的两种情况你就明确了。

         条件概率的两种情况:

                   1,B事件的结果不会影响到A事件的发生。

                            如上面的样例。两次投币正面向上的概率不会相互干扰。所以A事件发生的概率=A事件单独发生的概率。

                            记为:P(A|B) =P(A)

                   2。B事件的结果会影响A事件的发生。

                            如:若头天下雨,则第二天下雨的可能性会增大。

                            即:A事件在B事件之后发生的概率> A事件单独发生的概率。

                            记为:P(A|B)> P(A)

联合概率

         联合概率为两个事件同一时候发生的概率。

         记为:P(A and B)

         然后。由于两个事件的发生会有先后,所以联合概率能够进一步描写叙述为:“事件A发生的概率”和“事件A发生后,事件B发生的概率”。

         于是:P(A and B)= P(A)P(B|A)

                   ps:结合刚才“条件概率的两种情况”。能够得出:

                            P(A and B) 依据不同的情况有例如以下两种结果:

                                     P(Aand B) = P(A)P(B)        --       A和B的结果互不影响。即:P(B|A)   = P(B)

                                     P(Aand B) = P(A)P(B|A)   --       反之

曲奇饼问题

         总结自《贝叶斯思维:统计建模的Python学习法》

         条件:

                   碗1中有30个香草曲奇饼干和10个巧克力饼干,碗2中有上述饼干个20个。

         问:

                   闭上眼随机拿一块,从碗1中拿到香草曲奇的概率是多少?

         解:

                   首先,我们将“问”的内容用数学符号表示出来。即:P(碗1|香草)。

                            PS1:这里我对为什么是“P(碗1|香草)”而不是“P(香草|碗1)”有点疑惑。个人感觉将问题描写叙述成“得到的是香草饼干,并且该饼干是从碗1中拿到的”会更好。

                            PS2:顺便一提P(香草|碗1) = 3/4。嗯?为什么?从碗1出拿出一块饼干是香草饼干的概率这不是显而易见的 3/4 么,这个和碗2全然没关系。

                   然后,我们计算P(碗1|香草)。

                            。。

。。这怎么算?

                            嗯。

香草饼干一共50块,巧克力饼干一共30块,所以取出一块饼干是香草的概率是5/8。

                           然后。

然后。。

饼干从碗1中取出的概率是1/2。

                            。

。。

                            不行我编不下去了,还是看看书上怎么说的吧(事实上上面这两个概率就是贝叶斯公式中的两个必求的概率)。

                            (翻书翻书)

                            书上说的求这个要用贝叶斯定理。

                            那我们先把这个问题暂停到这里,看一下贝叶斯定理。

贝叶斯定理

         介绍        

                   贝叶斯定理是一种“依据数据集内容的变化而更新如果概率”的方法。

                           ps:上面引號中的内容用还有一种方式表达就是:如果的概率随看到的数据而变化。

                  于是对于事件A和B,贝叶斯定理的表达式可写成:

                           P(A|B) = P(A)P(B|A) / P(B)

                  在这样的解释里,每项的意义例如以下:

                           P(A)           :先验概率。         即:在的得到新数据前某一如果的概率。

                            P(A|B)      :后验概率。

         即:在看到新数据后,要计算的该如果的概率。

                            P(B|A)      :似然度。              即:在该如果下,得到这一数据的概率。

                           P(B)           :标准化常亮。     即:在不论什么如果下得到这一数据的概率。

                  唔….不太好理解啊。

                  那我们还用香草饼干的样例来说明下。

                            我们求得是P(碗1|香草),所以上面的A相应的事件是“取出饼干的碗是碗1”,B相应的事件是“取出的饼干是香草饼干”。

                            于是:

                                     先验概率P(A)          :取出饼干的碗是碗1的概率。

结果是1/2。

                                     后验概率P(A|B)     :得到的是香草饼干。且该饼干从碗1中拿到。

待求。

                                     似然度P(B|A)          :在碗1中得到香草饼干的概率。结果是3/4。

                                     标准化常亮P(B)     :饼干是香草饼干的概率。结果是5/8。

                           咦?上面这四个除了待求的后验概率外其它的求已经知道了(见曲奇饼问题中的黑体部分)!

那这就好办了,我们代入公式,于是非常easy就得出结果了。

         推导过程

                   依据上面的内容我们能够感觉的出,除了后验概率外,其它的都非常easy计算。那贝叶斯公式究竟是怎么来的呢?以下让我们推导一下。

                   依据之前的内容我们知道以下三个公式:

                            P(Aand B) = p(B and A)

                            P(Aand B) = P(A)P(B|A)

                            P(Band A) = P(B)P(A|B)

                   ∴     P(A)P(B|A) = P(B)P(A|B)

                   ∴     P(A|B) = P(A)P(B|A) / P(B)

                   ∴     这么简单的东西我怎么没想到….(被扇飞)

贝叶斯分类器

         在实际应用中“香草饼干”的问题明显过于简单。并且我们的终于目的是“分类”而不是“单纯的求概率”,那么我们怎样将贝叶斯定理用到实际应用中呢?请看以下的总结。

         原理:

                   定义:

                 输入:

                            待分类项:X = {a1,a2, …, am}                   ps:ai是X的特征属性,且ai必须条件独立。!

                            类别集合:C = {y1,y2, …, yn}

                     而“待分类项中的某个元素是某个类别yi的概率”能够描写叙述为P(yi|X)。

                     于是由贝叶斯定理可得:P(yi|X)= P(yi)P(X|yi) / P(X)

                     又由于上式中的P(X) 和类别全然没关系,即“对于分类”来说P(X) 的存在可有可无。

                     因此。“对于分类”,我们能够将分母去除,剩下的,仅仅需想办法将分子最大化,这样P(yi|X) 就是在某一分类下的最大概率了。

                     所以,对于分子:

                            P(yi)P(X|yi)= P(yi)P(a1|yi) P(a2|yi) P(a3|yi)…P(am|yi)= 

朴素贝叶斯条件概率联合概率曲奇饼问题贝叶斯定理贝叶斯分类器朴素贝叶斯分配器代码演示样例:

                  即,贝叶斯分类器为:

                            P(yi)P(X|yi)= P(yi)P(aj|yi)最大时的yi就是所求的类别。

         流程:

                   朴素贝叶斯分类的流程例如以下:

                            (准备阶段 – 人工)

                                     确定特征属性 -->  获取训练样本 -->

                            (分类器训练阶段 – 机器)

                                     -->  计算P(yi) --> 计算全部的P(aj|yi)  -->

                            (应用阶段 – 机器)

                                     -->  对全部的类别计算 P(yi)P(X|yi)  --> 以P(yi)P(X|yi)最大的类别作为X的所属类别。

                   流程的说明:

                            准备阶段:

                                     唯一须要人工干预的阶段,这一阶段须要人工依据详细情况确定特征属性,然后对每一个特征属性进行适当的划分,最后由人工对每一部分待分类项进行分类,形成样本集合。

                                     这一阶段输入:训练数据

                                     这一阶段输出:特征属性和训练样本。

                            分类器训练阶段:

                                     输入:特征属性和训练样本。

                                     输出:分类器。

                            应用阶段:

                                     输入:分类器和待分类项。

                                     输出:待分类项和类别的映射关系。

         样例:

                   用下表中的数据学习一个朴素贝叶斯分类器,并确定X=(2, S) 的类别标记Y。

                   表中:

                            X(1),X(2)是特征。取值集合是A1 = {1,2。3}。A2 = {S。M,L}。Y为类标记={-1, 1}

                                                                           (训练数据表)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
X(1) 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
X(2) 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

                   解:

                            准备阶段的结果题目中已经给出。即:“训练数据表”

                            分类器训练阶段:

                                     计算P(yi),即:每一个类别的概率:

                                               P(Y = 1 ) = 9/15

                                               P(Y = -1 ) = 6/15

                                     计算P(aj|yi),即:每一个类别条件下各个特征属性划分的概率:

                                               P(x(1)=1 | Y=1 ) = 2/9 。P( x(1)=2 | Y=1 ) = 3/9 。P( x(1)=3 | Y=1 ) = 4/9

                                               P(x(2)=S | Y=1 ) = 1/9 ,P( x(2)=M | Y=1 ) = 4/9 。P( x(2)=L | Y=1 ) = 4/9

                                               P(x(1)=1 | Y=-1 ) = 3/6 ,P( x(1)=2 | Y=-1 ) = 2/6 ,P( x(1)=3 | Y=-1 ) = 1/6

                                               P(x(2)=S | Y=-1 ) = 3/6 ,P( x(2)=M | Y=-1 ) = 2/6 ,P( x(2)=L | Y=-1 ) = 1/6

                            应用阶段:

                                     对给定的X=(2, S) 用分类器进行鉴别:

                                               P(Y = 1 ) P( x(1)=2 | Y=1 ) P( x(2)=S | Y=1 ) = 9/15 · 3/9 · 1/9 = 1/45

                                               P(Y = -1 ) P( x(1)=2 | Y=-1 ) P( x(2)=S | Y=-1 ) = 6/15 · 2/6 · 3/6 = 1/15

                                     ∵P( Y = -1 ) P(x(1)=2 | Y=-1 ) P( x(2)=S | Y=-1 )的概率大。

                                     ∴X=(2, S)属于类 Y = -1。

朴素贝叶斯分配器代码演示样例:

#-*-coding:utf-8-*-
# LANG=en_US.UTF-8
# 朴素贝叶斯
# 文件名称:native_bayes.py

import sys
import math

# 以下 3 个列表的数据其坐标是相应的,如:
#   当某个元素 X 其特征值为 (data_x1[0], data_x2[0]) 时,其类别为 data_y[0]
# 事实上就是为了实现(训练数据表):
#    -------------------------------------------------------------------
#    |     1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  |
#    -------------------------------------------------------------------
#    | 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  |
#   -------------------------------------------------------------------

# 特征值 x1
data_x1 = [
        1, 1, 1, 1, 1,
        2, 2, 2, 2, 2,
        3, 3, 3, 3, 3
    ]

# 特征值 x2
data_x2 = [
        'S', 'M', 'M', 'S', 'S',
        'S', 'M', 'M', 'L', 'L',
        'L', 'M', 'M', 'L', 'L'
    ]

# 类别 y
data_y = [
        -1, -1, 1, 1, -1,
        -1, -1, 1, 1, 1,
        1, 1, 1, 1, -1
    ]


# 计算各个类型的总数,返回类型字典
def get_type_sum( type_list ):
    # type_dict 保存类别:
    #   key:类别值
    #   value:类别数量
    # len(type_dict):类别个数
    type_dict = {}
    tmp_item = ''

    # 遍历类型,统计每一个类型的数量。将其保存到字典中
    for item in type_list:
        item = str(item)
        if tmp_item != item:
            if item in type_dict.keys():
                type_dict[item] += 1.0
            else:
                type_dict[item] = 1.0
                tmp_item = item
        else:
            type_dict[item] += 1.0

    return type_dict


# 计算 P(Xj|Yi)
def get_Pxjyi( type_list, type_dict, *data ):
    Pxjyi_dict = {}
    tmp_type = ''
    tmp_key = ''

    # 遍历原始数据,统计每种数据在某个类型下出现的频率
    for num in xrange( len(data[0]) ):
        x_num = 1
        for each_data in data:
            key = 'x%d=%s|y=%s' % ( x_num, str(each_data[num]), type_list[num] )
            if tmp_key != key:
                if key in Pxjyi_dict.keys():
                    Pxjyi_dict[key] += 1
                else:
                    Pxjyi_dict[key] = 1
                    tmp_key = key
            else:
                Pxjyi_dict[key] += 1
            x_num += 1

    for key in Pxjyi_dict:
        Pxjyi_dict[key] = '%.4f' % ( Pxjyi_dict[key] / type_dict[key.split('y=')[1]] )

    return Pxjyi_dict


# 计算 P(Yi), 返回类型字典
def get_Pyi( type_list, type_dict ):
    # 将 type_dict 的值由统计类型的数量改为某个类型占总类型的比例
    for key in type_dict:
        type_dict[key] = type_dict[key] / len( type_list )

    return type_dict


# 推断目标数据的所属类型
def get_result_type( type_dict, Pxjyi_dict, target_x ):
    max_probability = 0.0
    result_type = ''

    # 这里 target_x= (2, 'S')
    # 于是以下就是分别计算 P(Y=1)*P(X1=2|Y=1)*P(X2=S|Y=1) 和 P(Y=-1)*P(X1=2|Y=-1)*P(X2=S|Y=-1)
    # 然后依据哪个值大推断 target_x 属于哪个类型 
    for key in type_dict:
        for num in xrange( len(target_x) ):
            value = target_x[num]
            num += 1
            Pxjyi_key = 'x%d=%s|y=%s' % ( num, value, key )
            type_dict[key] = float(type_dict[key]) * float(Pxjyi_dict[Pxjyi_key])

        if type_dict[key] > max_probability:
            max_probability = type_dict[key]
            result_type = key

    return result_type, max_probability


type_dict = get_type_sum( data_y )
Pxjyi_dict = get_Pxjyi( data_y, type_dict, data_x1, data_x2 )
type_dict = get_Pyi( data_y, type_dict )
target_x= (2, 'S')
result_type, max_probability = get_result_type( type_dict, Pxjyi_dict, target_x )
print 'target type is', result_type