写在前面:
库文件链接: thinkbayes.py
假设我有5颗骰子,分别为4面,6面,8面,12面,20面。
现在我从里面随机选取一个,投掷以后得到6,问我最有可能取出的是哪个骰子?
我们通过一下3个步骤来解决这个问题:
现在我们用[4,6,8,12,20]来表示假设:
suite = Dice([4,6,8,12,20])
似然函数:
def Likelihood(self,data,hypo):#data为得到的投掷结果,hypo是我们的假设
if hypo < data:
#意味着骰子的投掷值要大于骰子的面数,显然这不可能
return 0
else
#可能情况下得到投掷值的概率自然就是1/hypo
return 1.0/hypo
随着投掷数据的变动,我们可以进一步得到每一个假设的后验概率分布,
先验实际上也能看成没有任何事件发生情况下的假设的可能性。
贝叶斯公式:P(hopy|data)=P(hopy)P(data|hopy)P(data)后验概率和为1:∑i=1nP(hopyi|data)=1
class Dice(suite):
def __init__(self,hypos):#对每个假设赋值先验概率,等可能性
for hypo in hypos:
self.Set(hypo,1)
#数据归一化
self.Normalize()
def Update(self,data):
for hypo in self.Values():
#我们得到了hypo假设下,数据data发生的概率,也就是我们说的该假设下的似然度(至少数值上是相等的)
like = self.Likelihood(data,hypo)
#事实上,我们在不断得更新假设的概率,这里我们没有取计算P(data)的概率。事实上,在确定假设之前P(data)是未知的,我么直接计算的P(hopy)P(data|hopy),因为我们在接下来进行了归一化,避免了P(data)的计算
self.Mult(hypo,like)
self.Normalize()
所以此时,我们投掷得到6,就相当于:
suite.Update(6)
得到:
铁路上以1到N命名火车,有一天你看到一个标号为60的火车头,估计铁路上有多少火车头?
解:可以肯定的是铁路上至少有60个火车头,但这个数字到底是多少?
我们可以把问题分成两个步骤:
hypos = range(1,1000)#假设
其实到这里,应该已经看出来了,我们进入到了跟投掷骰子一样的情况里面。
这里我们可以得到的是:
可能性最大化的解是60
不过,这还不是我们的目标,另一个可选的方案是计算后验概率的平均值分布:
听得莫名其妙,简单点说,就是期望。
E(火车数量)=∑i=1nhopy火车数量iP(火车数量i)
可以得到在取假设1——1000的情况下,我们能得到期望为333
如果细看上面的火车头问题的话,会发现我们的假设是非常武断的
有两种方法可以进一步减小我们误差:
假设,我们还看到了火车头30和90,我们就能向骰子一样更新分布。
采用数据后,期望值是:
如果没有更多的数据,我们就需要是通过收集背景资料来优化先验。
事实上,公司规模的分布往往遵循幂律,这项规律表明,如果少于10个火车头的公司有1000家,100个火车头的公司可能有100家,1000个火车头的公司有10家,10000个火车头的公司可能只有1家。
数学上,幂律表示公司数量与公司规模成反比,或:
class train():
def __init__(self, hypos, alpha = 1.0):
for hypo in hypos:
self.Set(hypo, hypo**(-alpha))
self.Normalize()
再次说明,上限是任意的,但对于幂律分布的先验概率,后验概率对这一选择的敏感度较小。
如果基于这种先验概率,在观察到列车30,60,90时,期望分别是:
一旦计算出了后验分布,通过单点估计或区间对后验分布进行总结通常是有用的。
点估计:
1. 平均数
2. 中位数
3. 最大似然值
区间,我们通常需要计算两个值,使得未知量有90%的可能落在两个值之间。这些值定义了一个置信区间。
计算置信区间的简单做法是在后验概率分布中累加其中的概率,并记录对应与概率5%和95%的值。
def Percentile(pmf,percentage):
p = percentage / 100.0
total = 0
for val, prob in pmf.Items():
total += prob
if total >= p:
return val
代码应用:
interval = Percentile(suite,5),Percentile(suite,95)
print interval
前面示例中,出现三个火车头,且先验概率呈现幂律分布的火车头问题中90%置信区间为(91,243)。如此大的区间确切表明,(尽管期望值已经收敛了)我们任然相当不确定究竟有多少个火车头的存在。