首页 > 代码库 > 朴素贝叶斯

朴素贝叶斯

声明:

         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 = http://www.mamicode.com/target_x[num]>

朴素贝叶斯