声明:
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