概率论只不过是把常识用数学公式表达了出来。
——拉普拉斯
这个内容算是一个番外吧。原本写完了逻辑回归就想写神经网络了,但是看到一个朴素贝叶斯分类的例子,所以自己也就写了一些程序来尝试,结果发现这个算法看似简单,实际的应用效果却出其意料的好,所就写一个章节。
背景知识 - 贝叶斯定理(Bayesian Theorem)
贝叶斯定理是关于随机事件A和B的条件概率的一则定理。
P ( A ∣ B ) = P ( A ) ∗ P ( B ∣ A ) P ( B ) P(A|B) = \frac{P(A)*P(B|A)}{P(B)} P(A∣B)=P(B)P(A)∗P(B∣A)
其中 P ( A ∣ B ) P(A|B) P(A∣B)是指在事件B发生的情况下事件A发生的概率。
在贝叶斯定理中,每个名词都有约定俗成的名称:
- P ( A ∣ B ) P(A|B) P(A∣B)是已知 B B B发生后 A A A的条件概率,也由于得自B的取值而被称作 A A A的后验概率。
- P ( A ) P(A) P(A)是 A A A的先验概率(或边缘概率)。之所以称为"先验"是因为它不考虑任何 B B B方面的因素。
- P ( B ∣ A ) P(B|A) P(B∣A)是已知 A A A发生后 B B B的条件概率,也由于得自 A A A的取值而被称作 B B B的后验概率。
- P ( B ) P(B) P(B)是B的先验概率或边缘概率。
按这些术语,贝叶斯定理可表述为:- 后验概率 = (似然性*先验概率)/标准化常量
也就是说,后验概率与先验概率和相似度的乘积成正比。
另外,比例P(B|A)/P(B)也有时被称作标准似然度(standardised likelihood),贝叶斯定理可表述为:
- 后验概率 = 标准似然度*先验概率
–维基百科
维基百科对贝叶斯定理的描述已经非常详尽了,如果我们已经知道事件A和B各自的发生概率,已经当事件A发生情况下事件B也发生的条件概率,那么就可以用上述公式求得已知事件B发生,则事件A发生的概率。
举个栗子,假设某天你观察到你女友心情不错,你想知道她是否会去同意和你约会这件事情的概率有多大。我们来假设,女朋友在心情愉快地情况下,同意来赴约的概率可表示为:
P
(
赴
约
∣
愉
快
)
=
P
(
赴
约
)
∗
P
(
愉
快
∣
赴
约
)
P
(
愉
快
)
P(赴约 | 愉快)= \frac{P(赴约)*P(愉快|赴约)}{P(愉快)}
P(赴约∣愉快)=P(愉快)P(赴约)∗P(愉快∣赴约)
而她心情愉快却不来赴约的概率为:
P
(
不
赴
约
∣
愉
快
)
=
P
(
不
赴
约
)
∗
P
(
愉
快
∣
不
赴
约
)
P
(
愉
快
)
P(不赴约 | 愉快)= \frac{P(不赴约)*P(愉快|不赴约)}{P(愉快)}
P(不赴约∣愉快)=P(愉快)P(不赴约)∗P(愉快∣不赴约)
P(赴约), 即她来赴约的概率其实你可以统计一下你总共约过她几次,而她同意和你出去的次数的历史数据就可以得出。
P(愉快|赴约),即她同意赴约,而随后你注意到她同意的时候心情不错。 只要你每次约她的时候细心观察并记录,就可以获得该数据。
P(愉快|不赴约),即她拒绝了你的邀请,而随后你观察到她其实心情不错的,假设你也获得了这个数据。
P(愉快), 假设你已经获得了上述所有数据,那么这个概率是可以求得的。
因为 P(赴约 | 愉快) 和 P(不赴约 | 愉快) 构成了一个完全事件,那么他们的和应该为1。由此得到
P
(
赴
约
)
∗
P
(
愉
快
∣
赴
约
)
P
(
愉
快
)
+
P
(
不
赴
约
)
∗
P
(
愉
快
∣
不
赴
约
)
P
(
愉
快
)
=
1
\frac{P(赴约)*P(愉快|赴约)}{P(愉快)}+\frac{P(不赴约)*P(愉快|不赴约)}{P(愉快)}=1
P(愉快)P(赴约)∗P(愉快∣赴约)+P(愉快)P(不赴约)∗P(愉快∣不赴约)=1
P
(
愉
快
)
=
P
(
赴
约
)
∗
P
(
愉
快
∣
赴
约
)
+
P
(
不
赴
约
)
∗
P
(
愉
快
∣
不
赴
约
)
P(愉快) = P(赴约)*P(愉快|赴约)+P(不赴约)*P(愉快|不赴约)
P(愉快)=P(赴约)∗P(愉快∣赴约)+P(不赴约)∗P(愉快∣不赴约)
由此,你就可以通过你的历史统计数据来计算出,当你女朋友心情愉快的时候,你约她出来成功的概率了。
然而这又有什么用了?对于有一些事件我们无法直接测量获得,但是我们可以通过大量的试验,得到一系列的统计数据,由此做出预测。 实际上这正是机器学习的核心思想之一。
朴素贝叶斯(Naive Bayes)
所谓朴素贝叶斯分类器,其“朴素”之处在它简单的假设了各个属性条件是独立的。
已经引用女朋友的例子,假设她是否接受你的约会邀请不仅和她的心情有关,还和她今天工作的劳累程度有关。实际上劳累程度往往会影响她的心情,但是在朴素贝叶斯中我们愚钝的假设这两个事件是完全独立的。
P
(
赴
约
∣
愉
快
,
劳
累
)
=
P
(
赴
约
)
∗
P
(
愉
快
,
劳
累
∣
赴
约
)
P
(
愉
快
,
劳
累
)
P(赴约 | 愉快, 劳累) = \frac{P(赴约)*P(愉快, 劳累|赴约) }{P(愉快, 劳累)}
P(赴约∣愉快,劳累)=P(愉快,劳累)P(赴约)∗P(愉快,劳累∣赴约)
=
P
(
赴
约
)
∗
P
(
愉
快
∣
赴
约
)
P
(
劳
累
∣
赴
约
)
P
(
愉
快
,
劳
累
)
=\frac{P(赴约)*P(愉快|赴约)P(劳累|赴约) }{P(愉快, 劳累)}
=P(愉快,劳累)P(赴约)∗P(愉快∣赴约)P(劳累∣赴约)
此处,由于假设女友的心情愉快和劳累是独立事件,因此我们可以使用乘法原则
P
(
愉
快
,
劳
累
∣
赴
约
)
=
P
(
愉
快
∣
赴
约
)
P
(
劳
累
∣
赴
约
)
P(愉快, 劳累|赴约)=P(愉快|赴约)P(劳累|赴约)
P(愉快,劳累∣赴约)=P(愉快∣赴约)P(劳累∣赴约)
虽然,在现实生活中,这个假设有多么的不靠谱,但朴素贝叶斯分类器在实际应用中却取得了非常不错的效果。
朴素贝叶斯分类器
了解了朴素贝叶斯的基本思想,贝叶斯分类器的算法也就呼之欲出了。
继续以你要你女友约会为例,此处的分类就可以理解为你女友赴约和不赴约两种,你使用朴素贝叶斯公式分别算出它们各自的概率,然后挑选一个概率值大的作为你的预测结果。
用数学的语言来描述,我们假设一个
A
1
,
A
2
.
.
.
A
M
A_1, A_2...A_M
A1,A2...AM构成A的一个完全事件,而
B
1
,
B
2
.
.
.
B
N
B_1, B_2...B_N
B1,B2...BN则是影响A事件的一系列事件。在已知B事件的发生情况下,我们可以根据朴素贝叶斯公式来推断
A
1
,
A
2
.
.
.
A
M
A_1, A_2...A_M
A1,A2...AM各自的的发生概率
P
(
A
1
)
,
P
(
A
2
)
.
.
.
P
(
A
M
)
P(A_1), P(A_2)...P(A_M)
P(A1),P(A2)...P(AM),从中选出一个概率值最大的分类,这就是我们最终输出的分类。
对连续函数的处理
以上所有的例子中我们说的事件都是离散的,那么对于连续的数据,比如年龄,体重等该如何来处理呢?我们可以使用概率密度函数密度函数,以最为常见的高斯分布(又名正态分布)为例,其分布密度函数如下:
f
(
x
)
=
1
σ
2
π
e
−
(
x
−
μ
)
2
2
σ
2
f(x) = \frac{1}{\sigma\sqrt{2\pi}}e^{-\frac{(x-\mu)^2}{2\sigma^2}}
f(x)=σ2π1e−2σ2(x−μ)2
σ
2
\sigma^2
σ2 为方差,
μ
\mu
μ为期望
那么对于事件
A
i
A_i
Ai连续变量
x
x
x其条件概率分布可以表示为:
P
(
x
∣
A
i
)
=
1
σ
i
2
π
e
−
(
x
−
μ
i
)
2
2
σ
i
2
P(x|A_i)=\frac{1}{\sigma_i\sqrt{2\pi}}e^{-\frac{(x-\mu_i)^2}{2\sigma_i^2}}
P(x∣Ai)=σi2π1e−2σi2(x−μi)2
其中的
σ
i
2
\sigma_i^2
σi2和
μ
i
\mu_i
μi是该连续变量在
A
i
A_i
Ai发生的情况下,
x
x
x的方差和期望。
举个栗子,比如我们的A事件定义为是否有心脏病(
A
1
A_1
A1为有,
A
2
A_2
A2为没有,这两个分类已经涵盖了所有的情况,构成一个完全事件),而
x
x
x作为年龄,是一个连续变量。我们可以对
A
1
A_1
A1和
A
2
A_2
A2分别做出两条关于年龄的正态分布曲线。
此处,有两点需要说明的。
- 这里只有一个连续变量 x x x, 作为分类A必然是离散的事件。我第一次看这个算法时曾经在这里掉坑里了,因为一说到连续变量的密度函数,满脑子的联合概率密度函数,实际上根本不需要那么复杂。
- 此处我们说 x x x服从正态分布,更精确的表达是“ x x x在每一个分类里都是服从正态分布的”。
在大多数的算法库里,朴素贝叶斯分类对于连续变量基本上默认使用高斯分布,比如ntlk库。在sklean库中除了提供高斯分布以外,还提供了多项式分布和伯努利分布可选。
应用实例
下面这组数据显示了年龄、雇主、教育程度、职位、性别、每周工时和收入是否超过5万的关系。年龄和每周工时是连续性数据,其他各项为离散型。
我们利用以下10条数据来训练一个朴素贝叶斯分类器,用于判断收入是否超过5万。这是个二分类问题,仅两个类别:收入超过5万和不超过5万。
以下这条是需要预测的数据
训练过程
通过以上10条数据我们可以生产以下一系列概率值:
- P(收入<= 50K)= 60%
P(收入> 50K)= 40% - 对于连续变量年龄服从
N
(
σ
,
μ
)
N(\sigma, \mu)
N(σ,μ)。根据伯努利的大数定律(Law of Large Numbers),当样本数据量足够大的时候,我们从统计数据中可以求得其方差和期望。此处为了更好展示计算过程,仅采用了10条数据。
收入<= 50K: σ 2 = 96.92 , μ = 35 \sigma^2=96.92, \mu =35 σ2=96.92,μ=35
收入<= 50K: σ 2 = 24.19 , μ = 37 \sigma^2=24.19, \mu =37 σ2=24.19,μ=37 - 对于雇主我们分别求得以下概率值:
雇主 | 收入<= 50K | 收入>50K |
---|---|---|
私营企业 | 83% | 25% |
政府 | 0% | 50% |
自由职业 | 17% | 25% |
此处需要说明一点,表格中表示的是条件概率而非联合概率。比如第二行第二格表示的为P(雇主=私营企业|收入<= 50K) =83%,即在收入小于5万的人群中有多少是受雇与私营企业。以下同上。
- 教育程度
教育程度 | 收入<= 50K | 收入>50K |
---|---|---|
博士以上 | 0% | 25% |
硕士 | 17% | 0% |
学士 | 33% | 25% |
其他 | 50% | 50% |
- 职位
职位 | 收入<= 50K | 收入>50K |
---|---|---|
服务业 | 17% | 25% |
技术专员 | 0% | 25% |
技术专员 | 17% | 0% |
清洁工 | 33% | 0% |
专业人士 | 17% | 25% |
农场工人 | 17% | 25% |
- 性别
性别 | 收入<= 50K | 收入>50K |
---|---|---|
男 | 100% | 75% |
女 | 0% | 25% |
- 每周工时
收入<= 50K: σ 2 = 447.14 , μ = 52 \sigma^2=447.14, \mu =52 σ2=447.14,μ=52
收入<= 50K: σ 2 = 44.75 , μ = 46 \sigma^2=44.75, \mu =46 σ2=44.75,μ=46
预测过程
我们使用朴素贝叶斯分类的计算公式,分别计算此人收入大于5万和不大于5万的概率。
P
(
收
入
<
=
50
K
∣
年
龄
=
28
,
雇
主
=
私
营
企
业
,
教
育
程
度
=
学
士
,
职
位
=
专
业
人
士
,
性
别
=
男
,
每
周
工
时
=
40
)
P(收入<=50K|年龄=28,雇主=私营企业, 教育程度=学士,职位=专业人士,性别=男,每周工时=40)
P(收入<=50K∣年龄=28,雇主=私营企业,教育程度=学士,职位=专业人士,性别=男,每周工时=40)
=
P
(
收
入
<
=
50
K
)
P
(
年
龄
=
28
∣
收
入
<
=
50
K
)
.
.
.
P
(
每
周
工
时
=
40
∣
收
入
<
=
50
K
)
P
(
雇
主
=
私
营
企
业
,
教
育
程
度
=
学
士
,
职
位
=
专
业
人
士
,
性
别
=
男
,
每
周
工
时
=
40
)
=\frac{P(收入<=50K) P(年龄=28|收入<=50K)...P(每周工时=40|收入<=50K)}{P(雇主=私营企业, 教育程度=学士,职位=专业人士,性别=男,每周工时=40)}
=P(雇主=私营企业,教育程度=学士,职位=专业人士,性别=男,每周工时=40)P(收入<=50K)P(年龄=28∣收入<=50K)...P(每周工时=40∣收入<=50K)
对于分母,实际上可以不求,因为对于每个分类,这个分母是一样的,因此只要比较分子的数值大小,就可以知道哪一个的概率较大。
我们查询之前训练得到的数据,就可以求得上式的分子为 0.001004%。
同样的我们可以求得此人收入大于5万时,分子的值为0.000034%。
比较两者大小,结果输出收入不大于5万的分类结果。
拉普拉斯修正(Laplacian correction)
我们再来看另外一个预测。
在做此处预测时,你会发现在计算
P
(
收
入
<
=
50
K
∣
年
龄
=
28
,
雇
主
=
政
府
,
.
.
.
)
P(收入<=50K|年龄=28,雇主=政府, ...)
P(收入<=50K∣年龄=28,雇主=政府,...)时始终为0。其关键之处就在于我们的样本数据中没有涵盖雇主=政府且收入<=50K的数据,导致
P
(
雇
主
=
政
府
∣
收
入
<
=
50
K
)
=
0
P(雇主=政府|收入<=50K)=0
P(雇主=政府∣收入<=50K)=0。
虽然理论上说,样本数据足够大,这个问题应该可以被解决,然而在实际应用中不可避免的会遇到此类情况。为了改善这种情况,我们可以采用“平滑”操作来修正这个数据,这种技术也被称为拉普拉斯修正(Laplacian correction)。
具体操作是对分子加上1,而分母加上该属性的种类数。以我们的例子来说
P
(
雇
主
=
政
府
∣
收
入
<
=
50
K
)
=
0
+
1
7
+
3
=
11
%
P(雇主=政府|收入<=50K)=\frac{0+1}{7+3}=11\%
P(雇主=政府∣收入<=50K)=7+30+1=11%
- 分子上在收入不超过5万的人群中没有雇主是政府的,应该为0,而根据拉普拉斯修正则要再加上1。
- 分母是全部训练数据中收入不超过5万的人数,而根据拉普拉斯修正要加上一个该属性的种类数,此处为3种不同的雇主。
使用拉普拉斯修正,我们就可以求得 P ( 雇 主 = 政 府 ∣ 收 入 < = 50 K ) P(雇主=政府|收入<=50K) P(雇主=政府∣收入<=50K)的一个修正值,从而不会使得某一种组合的概率为0。
朴素贝叶斯分类的使用条件
- 分类数是确定的,且构成一个完整事件。也就是说除了你定义的分类之外,不存在其他的可能性。我在实际应用中遇到过的情况是只对特定的几类的问题,我的处理方式是对于其他类别的数据放在一个类别中。
- 各类别在总体数据中分布是固定的。由之前的算法介绍可知,训练数据中该类别占据的比例是会引入到预测计算中的,因此在准备训练数据时需要确保其分布情况和实际应用时的数据是一致的。