首页 > 代码库 > 朴素贝叶斯
朴素贝叶斯
声明:
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]>
朴素贝叶斯