Professional Documents
Culture Documents
贝叶斯思维:统计
贝叶斯思维:统计
贝叶斯思维:统计
录
息
内 要
荐
1章
贝
1.1
条件概率
1.2
合概率
1.3
饼问题
1.4
贝
1.5
历时
1.6
M&M 问题
1.7
Monty
Hall 题
1.8
讨
2章
统
2.1
分
2.2
饼问题
2.3
贝 架
2.4
Monty
Hall 题
2.5
封 架
2.6
M&M 问题
2.7
讨
2.8
练习
3章
3.1
骰子问题
3.2
问题
3.3
怎 看待先 概率?
3.4
其他先 概率
3.5
3.6
积分
3.7
德军 克问题
3.8
讨
3.9
练习
4章
进
4.1
欧元问题
4.2
后 概率的概
4.3
先 概率的 没
4.4
优
4.5
Beta分
4.6
讨
4.7
练习
5章
率和
5.1
率
5.2
贝 的 率形式
5.3
奥利 的 迹
5.4
5.5
最大
5.6
合分
5.7
讨
6章
决 分
6.1
“ 的 格”问题
6.2
先 概率
6.3
概率密度
6.4
PDF的 示
6.5
选手
6.6
然度
6.7
更新
6.8
最优出
6.9
讨
7章
7.1
波 顿 熊 问题
7.2
松过
7.3
后
7.4
入球分
7.5
的概率
7.6
然 法则
7.7
讨
7.8
练习
8章
察 的 差
8.1
红线问题
8.2
型
8.3
待时
8.4
待时
8.5
到达率
8.6
消除不
8.7
决 分
8.8
讨
8.9
练习
9章
维问题
9.1
9.2
Suite对象
9.3
三 学
9.4
然度
9.5
合分
9.6
条件分
9.7
9.8
讨
9.9
练习
10章
贝 近
10.1
变异 说
10.2
均 和 准差
10.3
更新
10.4
CV的后 分
10.5
据下溢
10.6
对 然
10.7
一个小的优
10.8
ABC(近 贝 )
10.9
的可靠
10.10
谁的变异 更大?
10.11
讨
10.12
练习
11章
11.1
到欧元问题
11.2
来一个 平的对
11.3
三
11.4
讨
11.5
练习
12章
证据
12.1
读SAT成
12.2
例得分SAT
12.3
先
12.4
后
12.5
一个更好的 型
12.6
准
12.7
效率的后 分
12.8
分
12.9
讨
13章
真
13.1
肾 的问题
13.2
一个 型
13.3
更普 的 型
13.4
现
13.5
缓 合分
13.6
条件分
13.7
13.8
讨
14章
型
14.1
器问题
14.2
的开始
14.3
分 型
14.4
一个小优
14.5
抽取后
14.6
讨
14.7
练习
15章
多维问题
15.1
部细菌
15.2
狮子, 和熊
15.3
分
15.4
抽
15.5
优
15.6
的 结构
15.7
一个问题
15.8
还有工 要做
15.9
肚 据
15.10
分
15.11
合后
15.12
15.13
讨
译
封
译后记
迎来到异步社 !
信
:贝 维:统 的Python学习法
ISBN:978-7-115-38428-7
本 人 电出 社发行 字 所有
我们愿 读 有这 的良 和 , 我们共 护 产 。
购买 有 为,我们可能对 用户 施 不 闭 维 措施,并可能 究法
责 。
•
着
[美]
Allen
B.
Downey
译
许
责 编 王峰松
• 人 出 社出 发 北 台 成 路11
编 100164 子 件 315@ptpress.com.cn
址 http://www.ptpress.com.cn
• 读 服 热线:(010)81055410
反盗 热线:(010)81055315
明
Copyright
©2013
by
O’Reilly
Media,
Inc.
Simplified
Chinese
Edition,
jointly
published
by
O’Reilly
Media,
Inc.
and
Posts
&
Telecom
Press,
2014.
Authorized
translation
of
the
English
edition,
2013
O’Reilly
Media,
Inc.,
the
owner
of
all
rights
to
publish
and
sell
the
same.
All rights reserved including the rights of reproduction in whole or in part in any form.
所有
要
这 在帮助那 希望用 学工 决 问题的人们, 有的要 可能就是 一点概率 和
。贝 法是一 常 的利用概率学 去 决不 问题的 学 法,对 一个 专业
人 ,应 悉其在诸 器翻译、语 、 件 常 的 领域的应用。
更 能可 的是, 用 对 的Python语 ,对 涉 的 例进 了编 。对 有一
基础的人来说,通过 ,可以进一步 贝 法的应用,真 握并 可以利用这 达到
一反三的效 。
酷我 雷鸣①
学习之道
这 以 Think 其他 籍的一个 是:只要 得编 ,你就能用这个 能去学习其他的内
。
大多 贝 统 的 用 学符 并以 学概念的形式 示 学 想, 微积分。 用
了Python 不是 学, 散近 不是 续 学。结 就是原 要积分的地 变成了 和,概率分
的大多 操 变成了 的 环。
建模和 似
中多 章 的灵感都是由真 界里的问题 激发的, 以涉 了一 ,在应用贝
法( 其他的分 法) ,我们必须决 真 界中的 部分可以 进 型, 细 可
以 抽象 。
总的来说,我 荐这 步 的一个通用流 下。
1. 研究问题时,以一个 型开始,并以清晰、好 、 证无误的 现 。 集中
在好的 决 不是优 上。
指
中 的 很 多 例 子 用 了 在 thinkbayes.py 中 的 类 和 , 可 以
http://thinkbayes.com/thinkbayes.py下载这个 。
预备
还有 个出色的能在Python中进 贝 统 的 , pymc和OpenBUGS,由 读 要有
多的 景 能开始 用这 , 此 中我没有 用 们, 我想 读 的 条件最
小。 你了 Python和一点点概率 ,就可以开始 读 。
中 用的惯 写
中 用了下 的印刷 例。
体(Italic)
宽(Constant width)
命 其他由用户 入的 字。
应 由用户 入 由上下 决 的 。
这个图 示这是一个 示、 一般 的 记。
这个图 示这是 醒 示。
我们的联 方式
你想就 发 有 问,敬请 出 社。
美国:
O’Reilly Media Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
中国:
奥 利 术咨询(北 )有 司
的 术 问题 ,请发 件到:bookquestions@oreilly.com。
我们的其他 式 下。
Facebook:http://facebook.com/oreilly
Twitter:http://twitter.com/oreillymedia
YouTube:http://www.youtube.com/oreillymedia
列
你发现 有 要更 的地 其他 ,请发 子 件至downey@allendowney.com。一
根据你的反 进 了修 ,我会 你 入 (除了要 不 的情况)。
第1
贝 斯定理
1.1
有贝 统 的 法都基 贝 , 有条件概率的学习基础, 到这一点很自然。 此
我们会 概率、条件概率开始,然后到贝 ,最后讨 贝 统 的内 。
1.2
联
合概率:是指 个事件 时发生的概率。p(A和B)是A和B事件的发生都为真的概率。
你 了 骰例子和 的 景,我们开始学习下 的 式:
p(A和B)= p(A)p(B) 醒: 达式并非总是成 。
通常 下, 合概率 为
p(A and B) = p(A) p(B|A)
1.3
曲奇
我们 开始讨 到贝 , 我还想通过一个 称为“ 饼问题”的例子来 。 有
饼, 1 含30个香草 饼和10个 克 饼, 2有上 饼干 20个。
p(香草| 1)= 3/4
不 的是,p(A|B)并不和p(B|A) , 有 法 一个 出 一个:贝 。
1.4
贝 斯定理
现在,我们准 好进 贝 导 要的 有条件了。首先,我们 到, 合概率是 积可交
( 法交 )的, :
p(A and B) = p(B and A)
对 A,B 示的事件都成 。
p(A and B) = p(A)p(B|A)
交 们的位 :
p(B and A) = p(B)p(A|B)
这 达式 接起来,我们得到下 的 达式:
p(B)p(A|B)= p(A)p(B|A)
最后, 上式除以p(B),得到:
这 是贝 !看起来不起眼,不过 会显示出 人吃惊的强大 。
例 ,我们可以用 来 决 饼问题。
带入贝 我们得到:
式的右 示:
们 在一起,我们得到:
这 略在 决类 “ 饼问题”的情况下是有用的, 贝 式的右 要 的情
况下。
1.5
历时
还有 外一 贝 的 路: 给我们 的是一 根据 据集D的内 变 更新 概率
H的 法。
这 对贝 的 称为“历时 ”。
在 H和D的情况下,贝 的 达式可以改写成:
在这 里, 项 下:
有 情况,我们可以基 现有 景 息进 。 在 饼问题中,我们就 选中 1 2
的概率 为均 。
最常 的,我们可以指 一 下的 集来 。
的:集合中,至多一个 为真。
备的:集合中,至少一个 必为真, 集合 含了 有的 。
我 用suite这个词来 示 上 的 集。
p(D) = p(B1)p(D|B1) + p(B2)p(D|B2)
入饼干问题中的 ,得到:
p(D) = (1/2)(3/4) + (1/2)(1/2) = 5/8
1.6
M&M豆
M&M 是有 颜色的 克 。 M&M 的Mars 司会不时变更不 颜色 克
的 合 例。
A: 1是1994年的, 2是1996年的。
B: 1是1996年的, 2是1994年的。
接着我们 一个 格, 示 个 , 示贝 中的 一项:
先验 p(H ) 似然 p(D|H ) p(H)
p(D|H ) 后验 p(H|D )
A 1/2 (20)
(20) 200 20/27
B 1/2 (10)
(14) 70 7/27
一 示先 。基 问题的 ,选择p(A)=p(B)= 1/2是合 的。
就是这 。 吧?
的 是互 和穷 的,你可以 然度 以 子, 便, 一个 子应用到整
上。
1.7
Monty
Hall
大 (Monty
Hall
problem) 题可能是历 上最有 的概率问题。问题看 ,
案 此有悖常 以 很多人不能接受,很多聪 人都 堪 自己搞 了反 据 , 是 开的。
然度 要一 ,在充分合 的 后,我们 的 然度 下:
1.8
讨
对 涉 条件概率的很多问题,贝 了一个分 的 略。 p(A|B) 以 ,
以用 量,可以 查 贝 中的其他项是 更 , p(B|A),p(A)和p(B)。
2.1
分布
在统 上,分布是一 其对应的概率。
要 用Pmf,可 下导入:
from thinkbayes.py import Pmf
下 的 创 一个Pmf来 示 骰子的结 分 :
pmf = Pmf()
for x in [1,2,3,4,5,6] :
,
pmf.Set(x 1/6.0)
一 有一个Pmf对象,你可以像下 这 得到 一个 的概率:
print pmf.Prob('the')
这会 印 出 词“the”在词 中出现的 率。
2.2
曲奇
在贝 的语境下,可以很自然地 用一个Pmf 射 个 和对应的概率。
pmf = Pmf()
,
pmf.Set('Bowl1' 0.5)
,
pmf.Set('Bowl2' 0.5)
最后,我们可以得到 1的后 概率 下:
print pmf.Prob('Bowl 1')
2.3
贝 斯
在 续讨 其他的问题 ,我想在上一 的基础上重写 以 其更通用。首先我 一个类来封
此 的
:
class Cookie(Pmf) :
def __init__(self,hypos) :
Pmf.__init__(self)
for hypo in hypos :
self.Set(hypo,1)
self.Normalize()
Cookie对象是一个 射 到概率的Pmf对象。__init__ 法给 个 的先 概率。 上
一 中就有 :
,
hypos= ['Bowl1' 'Bowl2']
pmf =Cookie(hypos)
def Likelihood(self, data, hypo):
mix = self.mixes[hypo]
like = mix[data]
return like
下 这 进 更新:
pmf.Update('vanilla')
然后我们就可以 印 出 个 的后 概率:
for hypo , prob in pmf.Items() :
,
print hypo prob
其结 是
Bowl 1 0.6
Bowl 2 0.4
中的 可以 http://thinkbayes.com/cookie2.py 得。 了 更多 息,请参 的“ 指
南”。
2.4
Monty
Hall
为了 决 大 (Monty
Hall)问题,我 一个新的类:
class monty(Pmf) :
,
def __init__(self hypos) :
Pmf.__init__(self)
for hypo in hypos :
self.Set(hypo 1) ,
self.Normalize()
对Update的调用 是 的:
data='B'
pmf.Update(data)
Update的 现也是 一 的:
,
def Update (self data) :
for hypo in self.Values () :
like = self.Likelihood(data hypo) ,
self.Mult(hypo,like)
self.Normalize()
唯一 要 额外工 的是Likelihood:
def Likelihood (self,data,hypo) :
if hypo==data :
return 0
elif hypo=='A' :
return 0.5
:
else
return 1
最后, 印 出的结 是一 的:
,
for hypo prob in pmf.Items() :
print hypo,prob
案是
A 0.333333333333
B 0.0
Ç 0.666666666667
在 例中,Likelihood的编写有一点点 杂, 贝 架的Update很 。 中的 可以
http://thinkbayes.com/monty.py 得。 了 更多 息,请参 的“ 指南”。
2.5
现在,我们看看 架的 元 是 的,这 我们就可以 们封 进一个Suite对象, 一个
__init__,Update和Print 法的pmf对象:
class Suite(Pmf)
“代表一套假设及其概率。”
def __init__(self,hypo=tuple()):
“初始化分配。”
def Update(self,data):
“更新基于该数据的每个假设。”
def Print (self):
“打印出假设和它们的概率。”
下 是一个 用这个类的 :
suite=Monty('ABC')
suite.Update('B')
suite.Print()
2.6
M&M豆
我们可以 用Suite 架来 决M&M 的问题。除了编写Likelihood有点 手,其他一切都很 。
mix96=dict(blue= 24 ,
green= 20 ,
orange= 16 ,
yellow= 14 ,
red= 13 ,
brown= 13)
然后,封 :
,
hypoA =dict(bag1 = mix94 bag2 = mix96)
,
hypoB =dict(bag1 = mix96 bag2 = mix94)
hypoA 示 1是1994年, 2是1996年。hypoB是 反的 合。
接下来, 的 称来 射其含 :
,
hypotheses=dict(A=hypoA B=hypoB)
下 是创 suite对象并进 更新的 :
suite = M_and_M('AB')
suite.Update(('bag1', 'yellow'))
suite.Update(('bag2', 'green'))
suite.Print()
结 下:
A 0.740740740741
B 0.259259259259
中的 可以 http://thinkbayes.com/m_and_m.py 得。 了 更多 息,请参 的“ 指
南”。
2.7
讨
章 了Suite类, 封 了贝 update 架。
2.8
习
练习2-1。
在 11 的“贝 架”里 ,我 到了 饼问题的 法是 的,是 饼有 充的取多个饼的
情况(有 的情况)。
3.1
子
我有一盒骰子,里 有4 的骰子、6 的骰子、8 的骰子、12 的骰子和20 的骰子 1个。
玩过游戏《龙 地下 》,你 然会 白我的 指。
我通过一个三步 略来 决这个问题。
1.选择 的 示 法。
2.选择 据的 示 法。
3.编写 然度 。
在 的例子中我用字符 来 示 和 据, 骰子问题中我 用 字。
切地说我 用整 4、6、8、12和20来 示 :
, ,8,12,20 ])
suite=Dice([ 4 6
案是1/hypo无 据是什么。
下 是 用update( 转动得到6)的语 :
suite.Update (6)
后 分 的结 下:
4 0.0
6 0.392156862745
8 0.294117647059
12 0.196078431373
20 0.117647058824
,,,,,
for roll in [ 6 8 7 7 5 4 ] :
suite.Update (roll)
结 下:
4 0.0
6 0.0
8 0.943248453672
12 0.0552061280613
20 0.0015454182665
现在有94%的可能我们转动了一个8 骰, 时还有1%可能是一个20 骰。
3.2
车头
我是在 雷德里克·莫 勒的《 十个概率 题的 法》(多 出 社,1987)一 中发现
问题的:
然度 下:
class Train(Suite) :
,
def Likelihood(self data ,hypo) :
if hypo<data :
return 0
else:
return 1.0/hypo
看起来很 悉, 然 在 问题和骰子问题上是 的。
Update
下:
suite=Train (hypos)
suite.Update (60)
图3-1 问题的后 分 ,基 均 分 的先
def Mean(suite):
total= 0
, :
for hypo prob in suite.Items ()
total + = hypo*prob
return total
print Mean(suite)
你可以用由Pmf 的非常类 的 法:
print suite.Mean ()
后 的平均 是333, 以要是你想最大 度地减少 误,这也许是一个很好的猜 结 。
3.3
样看 先验 ?
为了进一步 决 问题,我们必须进 一 。
一个 着1000个 的 路 司 不上 , 一个 点的人可能会对这一问题做出更多
更少的猜 。
以结 很 (猜 结 对上界敏感)。有 法 续进 分 :
取更多的 据。
更多的 景 息。
用这 据时,后 概率的均 是
上限 后验 值
500 152
1000 164
2000 171
这 差异就较小了。
3.4
他先验
没有更多的 据, 一个 法是通过收集 景 料优 先 。
事 上, 司 的分 往往 ,参 伯 ·阿克 在《科学》杂志上的报道
(http://www.sciencemag.org/content/293/5536/1818.full.pdf)。
在 学上, 示 司的 量 司 成反 ,
我们可以构 一个服 分 的先 下:
class Train (Dice) :
, ,
def__init__ (self hypos alpha = 1.0) :
Pmf.__init__ (self)
for hypo in hypos :
,
self.Set (hypo hypo** (-alpha))
self.Normalize ()
下 是生成 概率的 :
hypos=range(1,1001)
suite=Train(hypos)
了 分 为 景 料后。我们可以消除大 700的N 了。
上限 后验 值
500 131
1000 133
2000 134
以基 分 的先 概率是 较现 的, 为 基 司 的一般情况,并 在 中 现得
更好。
3.5
置信区间
一 出的后 分 ,通过 点 对后 分 进 总结通常是有用的。
对 点 ,通常 用平均 、中位 最大 然 。
thinkbayes 了一个 分位 :
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
3.6
分布
在上一 中,我们通过 出 分 和Pmf的概率。 我们 要 多个 分位 ,更有
效 法是 用 积分 , Cdf。
3.7
德军 克
界大 期 ,在伦敦的美国大 部门 用统 分 来 德国生产的 克和其他
①。
这
记 的分 , 为 克类型分 了以100为一个 的 , 个 内的 都是
成 的, 并不是 个 内的 字都用到了。 此一来,在 个100的 内, 德军 克问题的
围就可以 的 问题来缩小了。
3.8
讨
贝 中,有 径选择先 分 。一 人 选择最能 问题 景 料的先 概率,在
这 情况下,先 为是“信 ”。问题是,人们可能会 用不 的 景 息( 进 不 的 )。
以基 息的先 往往显得 。
3.9
习
练习3-1。
案取决 我们 察到 时, 用的取 过 。
在 章中,我通过指 只有一个 司( 只有一个我们 心) 决了这个 可的问题。
是 有很多家 用不 编 的 司, 看到 司 的 的可能
。在这 情况下, 然 是不 的, 为你更有可能看到一 由大型 司 的 。
为练习, 现 然 的这 变 ,并 较结 。
4.1
在《 息 : 和学习 法》一 中,大 ·麦凯 出了这 一个问题:
那么,这一结 是 对‘ 币 心 非均 ’ 了证据呢?
class Euro(Suite) :
,
def likelihood (self data hypo) , :
x =hypo
if data== 'H' :
return x/100.0
else :
return 1 - x/100.0
下 是 现suite和update的 :
suite=Euro (xrange (0 101)),
dataset = 'H' * 140 + 'T' * 110
for data in dataset :
suite.Update (data)
其结 图4-1 示。
图4-1
为均 分 的 下,欧元问题的后 分
4.2
后验 的 述
总结一下,有 式来概 后 分 的 征。一 选择是找到后 分 的最大 然 。
thinkbayes 了一个 现:
:
def MaximumLikelihood(pmf)
返回具有最高概率的值。
“ ”
, ,
prob val = max((prob val)for val,prob in pmf.Items ())
return val
均 为55.95,中位 为56。
最后,我们可以 出一个 :
print 'CI', thinkbayes.CredibleInterval(Suite, 90)
其结 是(51,61)。
4.3
先验 的 没
章开始,我们 先 是均 的, 这可能不是一个好选择。 币是 心的,可以 x会大
幅 50%, 心到 得x是10% 90%就太不可能了。
下 的 构成了 三 状的先 :
:
def TrianglePrior ()
suite = Euro()
,
for x in range(0 51) :
,
suite.Set (x x)
,
for x in range(51 101) :
,
suite.Set (x 100 - x)
suite.Normalize ()
4.4
优
到目 为 ,我 展示的 都是为了 便 , 效率不 。通常,我先开发 证无误的 ,
然后 查对 达到目的是 快。 是, 就没有进 优 的必要。
在这个例子中, 我们 时 ,有 法可以 速 。
for data in dataset:
suite.Update(data)
下 是Update 法:
def Update(self, data):
for hypo in self.Values():
like = self.Likelihood(data, hypo)
self.Mult(hypo, like)
return self.Normalize()
下 是我们怎么调用 :
dataset = 'H' * heads + 'T' * tails
suite.UpdateSet(dataset)
在最 的 中, 据编写为 反 的字符 :
def Likelihood(self, data, hypo):
x = hypo / 100.0
if data == 'H':
return x
else:
return 1-x
有一 法,我们可以 据集 有 个整 的元 来进 编 : 和反 的 量。
在这 情况下的Likelihood 下:
def Likelihood(self, data, hypo):
x = hypo / 100.0
heads, tails = data
like = x**heads * (1-x)**tails
return like
然后我们就可以像下 这 调用Update:
heads, tails = 140, 110
suite.Update((heads, tails))
4.5
Beta分布
还有一个进一步的优 让 法更快。
def __init__(self, alpha=1, beta=1):
self.alpha = alpha
self.beta = beta
data是一对 和反 量的整 。
此,我们有 一 法来 决欧元问题:
beta = thinkbayes.Beta()
beta.Update((140, 110))
print beta.Mean()
4.6
讨
在 章中,我们用 个不 的先 一个问题,发现在较大 据集的条件下,先 的
掩 了。 个人开始 对 先 有不 ,他们通常会发现, 着得到更多的 据,后 分 收
了。在一 点上,分 的差异 小到没有 。
4.7
习
练习4-1。
练习4-2。
5.1
示概率的 法 一是用0和1 的 字,不过这并非唯一的 法。 你玩过 球博 ,可
能 到概率的 一 示,称为 (odds) 。
我的 的反向赔率是5:1,那么就是 分 的人 为 会 , 以 的概率是1/6。
5.2
贝 斯定理的 形式
在 1章我写出了贝 的概率形式:
这 形式 合在 上 脑海中进 贝 。
例 ,我们 到 饼问题:
5.3
的血
下 是来自麦凯的《 息 、 和学习》的 一个问题。
贝 的 率形式 了一 法, 这 直 更准 。
顾一下 式
除以o(A):
式 是后 率和 率的 。右 是 然 ,也称为贝 斯因子。
贝 子的 大 1,则 着 据更可能支 A 不是 B,也 着 更大,
率 也大 1, 着 着 据的出现 率也 了。
5.4
加
贝 统 的基 操 是Update,这 要先 概率和一 据,并产生一个后 分 。 是, 决
问题通常涉 许多其他操 , 缩 、 法和其他 术 、最大 和最小 ,还有 合 。
真:
枚 :
def __init__(self, sides):
thinkbayes.Pmf.__init__(self)
for x in xrange(1, sides+1):
self.Set(x, 1)
self.Normalize()
然后 用thinkbayes.SampleSum产生1000 转动3个骰子的 。
dice = [d6] * 3
three = thinkbayes.SampleSum(dice, 1000)
SampleSum 用RandomSum,也在thinkbayes.py中:
def RandomSum(dists):
total = sum(dist.Random() for dist in dists)
return total
def __add__(self, other):
pmf = Pmf()
for v1, p1 in self.Items():
for v2, p2 in other.Items():
pmf.Incr(v1+v2, p1*p2)
return pmf
下 是 用 :
three_exact = d6 + d6 + d6
Pmf.__add__是基
这 的 ,来自 个Pmf的 选择是独 的。在 多个骰子的例子中,这个
不 。其他情况下我们则必须扩展这个 法以 用条件概率。
5.5
最大
你生成一个《龙 地下 》的 色,会对人物的最佳 有兴 , 以你可能想 道 分
的最大 。
有三 法来 一个最大 的分 。
真:
枚 :
指 :
我们 一个Pmf转 为Cdf,有一个 有效的 法查找最大的Cdf(看后 )。
真最大 的 真 和的 :
def RandomMax(dists):
total = max(dist.Random() for dist in dists)
return total
def SampleMax(dists, n):
pmf = MakePmfFromList(RandomMax(dists) for i in xrange(n))
return pmf
我 做的只是用“max” “sum”。 对 枚 部分 是 的:
def PmfMax(pmf1, pmf2):
res = thinkbayes.Pmf()
for v1, p1 in pmf1.Items():
for v2, p2 in pmf2.Items():
res.Incr(max(v1, v2), p1*p2)
return res
事 上,你可以 操 符 为参 来一般 这个 。
选择X和Y是独 为,
def Max(self, k):
cdf = self.Copy()
cdf.ps = [p**k for p in cdf.ps]
return cdf
Max法接受选取的 k,然后 一个新的 示进 k 选择最大 的Cdf。此 法的 时
Cdf中的条目个 m。
最后,这里有一个 色的最佳 的分 的 例:
best_attr_cdf = three_exact.Max (6)
best_attr_pmf = best_attr_cdf.MakePmf ()
图5-2显示了分 。
5.6
分布
让我们 一个来自《龙 地下 》的例子。 我有一盒骰子,清 下:
5 个 4 面骰子
4 个 6 面骰子
3 个 8 面骰子
2 个 12 面骰子
1 个 20 面骰子
盒子中选择一个骰子转动,结 会呈现什么分 呢?
接下来,我们 要 合分 法的一个更通用的 :
mix = thinkbayes.Pmf()
for die, weight in pmf_dice.Items():
for outcome, prob in die.Items():
mix.Incr(outcome, weight*prob)
我们 在 7章和 8章 用MakeMixture。
5.7
讨
除了贝 的赔率形式,这一章不是专门 贝 的。 贝 分 的一切都和分 有 ,
以了 分 的概念很重要。以 的 点来看,分 就是可以 示 一 (一个 过 的可能结
)和其概率的 据结构。
6.1
“ 确的 ”
2007年11月1日,选手 希 和纳 参 《 的 格》这个美国 游戏 目。他们在 为
showcase的游戏环 中 ,游戏 题是猜展示 的 格。猜 到最接近展示 格的选手 得
。
希 的展 球 、 游戏、台球 和一 去巴 的 。 出 21500美元。
纳 展 的 格为25347美元。由 出 太 他 了 。
希 的展 的 格为21578美元。 起 格 只少猜了78美元 以 得了 。 为
的出 差少 250美元, 还 得了纳 的展 。
2.看到 后,选手应 修 这 期?
6.2
先验
为了选择 格的先 分 ,我们可以利用先 的 据。 的是,这个 目的 详细记 了这
据。 我 戴维 - 隆先生就 通 时,他 了 ·吉收集的 据http://tpirsummaries.8m.com。
了 2011年到2012年的 目中 个展 环 的 格,还有参 选手就展 的出 。
这 分 基 的 据, 用 内 密度 进 了平滑(KDE)。在我们 续 ,我想绕道
先去 概率密度 和KDE。
6.3
到目 为 ,我们 和概率 量 PMF 了很多交道。PMF是 一个可能 到其概率的
射。在我的 现中,Pmf对象 一个Prob 法 得 和概率,也 称为概率 量。
6.4
PDF的 示
要在Python中 示PDF,thinkbayes.py 一个 为PDF的类。PDF是一个抽象类,这 着 了
PDF接口, 不 一个 整的 现。PDF接口 法,Density和MakePmf:
class Pdf(object):
def Density(self, x):
raise UnimplementedMethodException()
def MakePmf(self, xs):
pmf = Pmf()
for x in xs:
pmf.Set(x, self.Density(x))
pmf.Normalize()
return pmf
Density取一个x ,并 应的密度。Makepmf生成PDF的近 散 。
def __init__(self, mu, sigma):
self.mu = mu
self.sigma = sigma
def Density(self, x):
return scipy.stats.norm.pdf(x, self.mu, self.sigma)
示例 以下 ( 顺 ):
28800, 28868, 28941, 28957, 28958
def __init__(self, sample):
self.kde = scipy.stats.gaussian_kde(sample)
def Density(self, x):
return self.kde.evaluate(x)
最后,这是生成的 干:
prices = ReadData()
pdf = thinkbayes.EstimatedPdf(prices)
low, high = 0, 75000
n = 101
xs = numpy.linspace(low, high, n)
pmf = pdf.MakePmf(xs)
示“线
linspace ”的 。 接收一个由low和high界 的 ,以 内的n个 据点,并
一个新的numpy , 含了n个low和high 的 距元 。
现在 到“ 的 格”问题。
6.5
手建模
图6-1的PDF 了展 可能的 格分 。 你是一个参 目的选手,你可以 用这个分 来量
展 环 中的先 念(在看到 )。
1.怎么看待 据以 量 据?
为了 这 问题,我 选手 为一 误差 的 格猜 来 。 说, 选手看到
展 猜 个 的 格时——不 是展 一部分这一事 (也就是不 总量)—— 这
格 起来,得到的总和称为猜 格guess。
我们 :
error = price – guess (猜测误差 = 展品价格 – 猜测价格)
然后,我们可以 出问题“选手的 格 猜 误差error的 然度是什么?”
出 差diff的 是:
diff = price – bid (出价差=奖品价格 – 选手出价)
diff的
是负的,出 就太 。 一 ,我们可以 用这个分 参 出 过 的概率:
一 选手 中出 的 例是25%; 选手 中出 的 例是29%。
def __init__(self, prices, bids, diffs):
self.pdf_price = thinkbayes.EstimatedPdf(prices)
self.cdf_diff = thinkbayes.MakeCdfFromList(diffs)
mu = 0
sigma = numpy.std(diffs)
self.pdf_error = thinkbayes.GaussianPdf(mu, sigma)
6.6
似然
现在我们准 好编写 然 了。像通常那 , 一个新类:
class Price(thinkbayes.Suite):
def __init__(self, pmf, player):
thinkbayes.Suite.__init__(self, pmf)
self.player = player
error = price - guess
like = self.player.ErrorDensity(error)
return like
ErrorDensity在Player中 :
# class Player:
def ErrorDensity(self, error):
return self.pdf_error.Density(error)
以说概率密度是一个 好的 然度 法。
6.7
更新
Player 了一个 法以选手的猜 来 后 分 :
# class Player
def MakeBeliefs(self, guess):
pmf = self.PmfPrice()
self.prior = Price(pmf, self)
self.posterior = self.prior.Copy()
self.posterior.Update(guess)
n = 101
price_xs = numpy.linspace(0, 75000, n)
def PmfPrice(self):
return self.pdf_price.MakePmf(self.price_xs)
一个 度上,你可能会发现这个结 的悖 , 为 你 为 格是20000美元,那么
在 猜 误差的情况下,你应 格是24000美元。
为 最优报 ,我写了一个类称为GainCalculator:
class GainCalculator(object):
def __init__(self, player, opponent):
self.player = player
self.opponent = opponent
Player和opponent都是Player对象。
GainCalculator ExpectedGains,为 出 和 期收 :
def ExpectedGains(self, low=0, high=75000, n=101):
bids = numpy.linspace(low, high, n)
gains = [self.ExpectedGain(bid) for bid in bids]
return bids, gains
ExpectedGains调用ExpectedGain, 对 一个给 的报 的 期 :
def ExpectedGain(self, bid):
suite = self.player.posterior
total = 0
for price, prob in sorted(suite.Items()):
gain = self.Gain(bid, price)
total += prob * gain
return total
ExpectedGain调用Gain,Gain通过报 和 格 期收 :
def Gain(self, bid, price):
if bid > price:
return 0
diff = price - bid
prob = self.ProbWin(diff)
if diff <= 250:
return 2 * price * prob
else:
return price * prob
def ProbOverbid(self):
return self.cdf_diff.Prob(-1)
def ProbWorseThan(self, diff):
return 1 - self.cdf_diff.Prob(diff)
最后, 最优报 的 :
# class Player:
def OptimalBid(self, guess, opponent):
self.MakeBeliefs(guess)
calc = GainCalculator(self, opponent)
bids, gains = calc.ExpectedGains()
gain, bid = max(zip(gains, bids))
return bid, gain
给 一个对手和guess,OptimalBid 出后 分 , 例 一个GainCalculator 可能
的 期收 报并 最优报 和 期收 。太棒了!
选手1的最优报 是21000美元,产生近16700美元的 期 报。
6.9
讨
贝 的
点 一就是结 来自后 分 这 形式。 的 通常会生成一个 一的点
, 就是过 的最后一步,这是 的。 你想以一个 为后续分 的 入,点
和 隔往往没有多少帮助。
贝 法的 学 常常通过均 最大 然 来描 后 分 ,这 概 是有用的,不过
你 要的 就是这 内 ,也许一开始就不必 贝 法。
在你 要 后 概率带入后续分 进 型决 时,贝 法就 有用了,就 我们在 章做
的一 。 外,进 时,贝 法也很有用,下一章我们会看到案例。
第7
预测
7.1
士 队
在2010—2011的国家冰球 (NHL)总决 中,我 爱的7个 军波 顿 熊 我嗤 以鼻
的 哥华 大人 对决。波 顿以0
:
1和2
:
3 了 场 ,以8
:
1和4
:
0 了后续 场 。那么
在 的这个时 点上, 波 顿 下一场 的可能 是多少? 得总 军的概率是多少?
1. 以 的 统 料,为λ选择一个先 分 。
4. 个 得 军的可能 。
for x in numpy.linspace(low, high, n):
p = scipy.stats.norm.pdf(mu, sigma, x)
pmf.Set(x, p)
pmf.Normalize()
return pmf
到 问题上,下 是一 有 λ 的 。
class Hockey(thinkbayes.Suite):
def __init__(self):
pmf = thinkbayes.MakeGaussianPmf(2.7, 0.3, 4)
thinkbayes.Suite.__init__(self, pmf)
这 的先 分 是均 2.7, 准 差0.3的 分 , 围是上下以均 为中心的4个sigma。
7.2
松过程
在 统 上,过程是一个物 统的 型(“ ”是指 型 含 量)。例 ,一个
伯努利过 是一个事件 的 型,称为试 ,其中 个试 有 可能的结 , 成功和 。
此,对 一 的 币翻转事件, 一 的射击得分事件,伯努利过 是一个天然的 型。 松过
是伯努利过 的 续 ,一个事件在 时 点上发生的概率是 的。 松过 可应用 到达 店的
客户, 交 到站, 冰球 的入球得分上。
得分 隔的分 由指 型PDF给出
:
def EvalExponentialPdf(lam, x):
return lam * math.exp(-lam * x)
7.3
后验
现在,我们可以 一个给 lam 的球 在一场 中进k个球的可能 :
# class Hockey
def Likelihood(self, data, hypo):
lam = hypo
k = data
like = thinkbayes.EvalPoissonPmf(lam, k)
return like
suite2 = Hockey('canucks')
suite2.UpdateSet([1, 3, 1, 0])
图7-1显示了给 lam的后 分 结 。根据 四场 的 据,最有可能的lam 大人 是2.6,
熊 是2.9(译 :冰球 进一球得到一分, 此对“得分”和“入球”结合上下 灵活 用)。
图7-1 场 入球 的后 分
7.4
球分布
要 个团 得下一场 的概率,我们 要 球 得分的分 。
给 lam的后 分 ,下 是 得分分 的 :
def MakeGoalPmf(suite):
metapmf = thinkbayes.Pmf()
for lam, prob in suite.Items():
pmf = thinkbayes.MakePoissonPmf(lam, 10)
metapmf.Set(pmf, prob)
mix = thinkbayes.MakeMixture(metapmf)
return mix
然后我们用MakeMixture 合分 (参 MakeMixture的“ 合分 ”, 45 )。
7.5
获 的
为了得到 的概率,首先我们 入球得分差异的分 :
goal_dist1 = MakeGoalPmf (suite1)
goal_dist2 = MakeGoalPmf (suite2)
diff = goal_dist1 - goal_dist2
由 一 中的得分的分 看,p_win是46%,p_loss是37%,p_tie为17%。
给 lam,我们可以 得分 的时 :
lam= 3.4
time_dist = thinkbayes.MakeExponentialPmf (lam, high = 2 , n = 101)
for lam, prob in suite.Items():
pmf = thinkbayes.MakeExponentialPmf(lam, high=2, n=2001)
metapmf.Set(pmf, prob)
mix = thinkbayes.MakeMixture(metapmf)
return mix
现在我们 熊 首先得分的概率:
time_dist1 = MakeGoalTimePmf (suite1)
time_dist2 = MakeGoalTimePmf (suite2)
p_overtime = thinkbayes.PmfProbLess (time_dist1 , time_dist2)
对 熊 , 得 时 的概率为52%。
以对 熊 , 的下一场 的整体概率是55%。
此 熊 得 总 军的 会是57%。在2011年,他们 做到了。
7.7
讨
往常一 , 章讨 的分 是基 型决 的, 总是一个反 的过 。
在这个例子中,我会 以下选项:
这 的均 为2.8,不过 准差为0.85, 我们 就 支 伍 的更 。
章的 和 据 都 可 以 http://thinkbayes.com/hockey.py 和 http://thinkbayes.com/hockey_data.csv
得。 了 更多 息,请参 的“ 指南”。
7.8
习
练习7-1。
交 到站 隔是20分 ,你到达 交站的时 是 的,那么你 待 交 的时 0到20分
均 分 。 在现 中, 交 达的 隔是有变动的。 你 在 待一 交 , 你 道
交 达时 的历 分 。 你 待时 的分 。
我在下一章 了这个问题的一个 法。
练习7-2。
我下一章 了这个问题的一 法。
练习7-3。
你是一位在新的环境中进 取 的生态学家。
练习7-4。
8.1
在 诸 ,“红线”是 接 桥和波 顿的地 线路。我在 桥工 的时 坐红线地 Kendall
广场到南站, 转 通 路到Needham。上下 峰期,红线 平均 7~8分 一趟。
章内 自Brendan
Ritter和Kai
Austin负责的一个项目,他们和我在欧 学 一个 。 章中
的 可 以 http://thinkbayes.com/redline.py 得 到 。 我 用 来 收 集 据 的 在
http://thinkbayes.com/redline_data.py。 了 更多 息,请参 的“ 指南”。
8.2
模型
在分 ,我们必须决 一 细 。首先,我 客 达 站 松过 ,这 着我
客可能在 时 概率到达, 客有一个未 的到达率λ,以 分 到达的 客 量。 为我在很 的
时 段内 察 客, 是在 天的 一时 , 以我 λ为常 。
为 了 收 集 发 隔 的 据 , 我 编 写 了 下 载 时 据 的 脚
http://www.mbta.com/rider_tools/developers/,选择往南到达Kendall广场的 ,并在 据库中记 其到达
时 。脚 在 个工 日下午4点到下午6点 , 续5天, 天记 了
15 到达。然后我 后
到达 的时 隔,这 分 的差 图8-1
示, 为z。
图8-1
根据收集到的 据绘 的 隔的PMF,以KDE平滑
(z为 分 ;zb是由 客看到 隔的 差分 )
你下午4点到下午6点在站台记 的 隔,这就是你看到 隔时 的分 。 是 你
到达站台(不管 时刻 ),会看到一个 此不 的分 , 到达的 客 看到的 隔的平均
, 的平均 要 一 。
for x, p in pmf.Items():
new_pmf.Mult(x, x)
new_pmf.Normalize()
return new_pmf
8.3
等 时间
待时 称 为y,是 客到达时刻和下一趟 到达时刻 的时 。 过时 称 为x,是 客到
达时刻和上一趟 到达时刻 的时 。这 得zb = x +y。
下 的 zb的分 和y的分 :
def PmfOfWaitTime(pmf_zb):
metapmf = thinkbayes.Pmf()
for gap, prob in pmf_zb.Items():
uniform = MakeUniformPmf(0, gap)
metapmf.Set(uniform, prob)
pmf_y = thinkbayes.MakeMixture(metapmf)
return pmf_y
PmfOfWaitTime还 用了MakeUniformPmf, 为:
def MakeUniformPmf(low, high):
pmf = thinkbayes.Pmf()
for x in MakeRange(low=low, high=high):
pmf.Set(x, 1)
pmf.Normalize()
return pmf
def __init__(self, pmf_z):
self.pmf_z = pmf_z
self.pmf_zb = BiasPmf(pmf)
self.pmf_y = self.PmfOfWaitTime(self.pmf_zb)
self.pmf_x = self.pmf_y
参 pmf_z 是 z 的非
差分 。pmf_zb是 客看到的 隔的 差分 。pmf_y是 待时 的分 。
pmf_x 是
过的时 的分 , 和 待时 分 是一 的。想 道为什么?记得对 一个 zp 的一个
,y的分 是 0到zp均 的, 到x = zp – y, 此x的分 也是 0到zp均 的。
在这 情况下,我们可以:
3.最后,我们 用 y = zp - x可得y的分 。
pmf_z是给 的 隔时 的分 。
ElapsedTimeEstimator的 :
class ElapsedTimeEstimator(object):
def __init__(self, wtc, lam, num_passengers):
self.prior_x = Elapsed(wtc.pmf_x)
self.post_x = self.prior_x.Copy()
self.post_x.Update((lam, num_passengers))
self.pmf_y = PredictWaitTime(wtc.pmf_zb, self.post_x)
prior_x和posterior_x是 过时 的先 和后 分 。pmf_y是 待时 的 分 。
ElapsedTimeEstimator 用Elapsed和PredictWaitTime, 下。
下 是Elapsed的 :
class Elapsed(thinkbayes.Suite):
def Likelihood(self, data, hypo):
x = hypo
lam, k = data
like = thinkbayes.EvalPoissonPmf(lam * x, k)
return like
往常一 ,Likelihood接受一个 和 据,并 下 据的 然度。在这个例子里 hypo
是上一趟 后 过的时 ,data是一个 lam和 客 量的元 。
最后,PredictWaitTime的 是:
def PredictWaitTime(pmf_zb, pmf_x):
pmf_y = pmf_zb - pmf_x
RemoveNegatives(pmf_y)
return pmf_y
8.5
到达
到目 为 的分 基 我们 (1) 隔的分 (2) 客到达率的 。现在,我们 准
好开始 个 。
5天后,你可能得到这 的 据:
k1 y k2
-- --- --
17 4.6 9
22 1.0 0
23 1.4 4
18 5.4 12
4 5.8 11
def Likelihood(self, data, hypo):
lam = hypo
y, k = data
like = thinkbayes.EvalPoissonPmf(lam * y, k)
return like
这一Likelihood看起来很 悉, 和 75 “ 待时 ”里的Elapsed.Likelihood 一 一 。
在 Elapsed.Likelihood里 是 过的时 x,在ArrivalRate.Likelihood里 是lam到达率。
个例子里 , 然度都是在 lam的条件下,一段时 里 到k个到达( 客)的可能 。
def __init__(self, passenger_data):
low, high = 0, 5
n = 51
hypos = numpy.linspace(low, high, n) / 60
self.prior_lam = ArrivalRate(hypos)
self.post_lam = self.prior_lam.Copy()
for k1, y, k2 in passenger_data:
self.post_lam.Update((y, k2))
8.6
消除不确定
无 时,分 中总有一 入量带来的不 ,我们可以通过下 这个步 这一 进
来:
1. 现基 不 参 的 分 (在 例中是λ)。
2. 不 参 的分 。
3.对参 的 个 进 分 ,并生成一 分 。
4. 用参 分 对应的 出 分 的 合分 。
def __init__(self, wtc, are, num_passengers=15):
self.metapmf = thinkbayes.Pmf()
for lam, prob in sorted(are.post_lam.Items()):
ete = ElapsedTimeEstimator(wtc, lam, num_passengers)
self.metapmf.Set(ete.pmf_y, prob)
self.mixture = thinkbayes.MakeMixture(self.metapmf)
wtc是 含zb分 的WaitTimeCalculator 例。are则是 含了lam分 的ArrivalTimeEstimator 例。
一 创 了 一 个 元 Pmf 来 射y的可能分 和其概率。对 lam 的 一个 ,我们用
ElapsedTimeEstimator y的 应分 ,并 其 储在元Pmf。然后我们用MakeMixture来 合分 。
在这 情况下,我们可以用lam的 点 得到一个非常类 的结 。 此就 用 , 的不
含进来不是必 的。
8.7
决 分
现在,我们可以 用站台上 客人 待时 的分 了。让我们 问题的 部分:我应 在
时 待 去 一 出 ?
请记住,在 始的场景中,我会去南站 坐通 路。 我下 早, 以 以 待15分 在南
站 。
8.8
讨
分 到目 为 一直基 一个 , 客的到达率 天是 的,对 峰时段的通 ,这可
能不是一个坏 , 也有一 显的例外。例 , 附近有一个 殊的事件,大量的 客可能 时到
达。在这 情况下,lam的 就会太 , 以x和y的 会太 。
殊事件和重大延误一 常 , 们 进 型就很重要。我们可以通过扩展lam的分 以
进偶 出现的较大 来 现这一点。
8.9
习
练习8-1。
你可以 http://thinkbayes.com/decay.py下载这个练习的 法。
第9
二
9.1
彩
射击 动中,参 伍用 互 射击,用涂料填充的 命中时会 碎。这一 动通常在一个
了障碍和其他可 为掩护物体的 域中进 。
图9-1 问题 图
9.2
Suite对象
首先,我们 要一个Suite对象来 示一 有 对手位 的 。 个 是一对坐 :(alpha,
beta)。
下 是 Suite对象的 :
class Paintball(thinkbayes.Suite, thinkbayes.Joint):
def __init__(self, alphas, betas, locations):
self.locations = locations
pairs = [(alpha, beta)
for alpha in alphas
for beta in betas]
thinkbayes.Suite.__init__(self, pairs)
alphas 是 alpha 有可能 的 , betas 是 beta 的 。 pairs 是 有的( alpha , bata )对的
。locations是沿墙的可能位 , 储在Likelihood中以便后 用。
suite = Paintball(alphas, betas, locations)
9.3
三角学
现在我们 要一个 然 ,这 着我们必须弄清 在 对手的位 后,他击中 一个沿着墙
壁的位 点的 然度。
这个 得到θ
此, 墙上 个位 ,我们可以 出θ。
取 一 对 θ 的导
9.4
似然
现在我们 要一个 然 。在给 对手的坐 的情况下,我们可以 用MakeLocationPmf x
的 然度。
def Likelihood(self, data, hypo):
alpha, beta = hypo
x = data
pmf = MakeLocationPmf(alpha, beta, self.locations)
like = pmf.Prob(x)
return like
大功告成。要更新Suite对象,我们可以 用 承自Suite的UpdateSet。
, ,18 ,21 ])
suite.UpdateSet ([ 15 16
9.5
联 分布
分 的 个 都是一个元 变量时, 称为联 分布。 了多个变量的分 ,这 是“ 合”的
含 。 合分 含了变量的分 以 变量 的 。
thinkbayes.Joint 了 缘分 的 法:
# class Joint:
def Marginal(self, i):
pmf = Pmf()
for vs, prob in self.Items():
pmf.Incr(vs[i], prob)
return pmf
下 是 取 缘分 的 :
marginal_alpha = suite.Marginal (0)
marginal_beta = suite.Marginal (1)
给 的后 的 缘,我们可以分 为 个坐 :
,
print 'alpha CI ' marginal_alpha.CredibleInterval(50)
,
print 'beta CI ' marginal_beta.CredibleInterval(50)
对 alpha,50% ,
为(14 21),beta是(5 31)。 以 据 , 的证据 射手 在 内的近
侧。 这还不是强证据, 为
90% 了 的大部分 域!
9.6
分布
分 示了有 变量 自的 息, 没有捕捉变量 的依 。
pmf.Normalize()
return pmf
的,i是我们想要的变量的 ;j是调 变量的 ,val是有条件 。
for beta in betas:
cond = suite.Conditional(0, 1, beta)
9.7
置信区间
一 可 后 合分 的 式是 。 我们在 23 讨 “ ”的时 ,我略过
了一个微 息点:对 给 的分 ,有很多 度的 。例 , 你想有一个50%的可
,你可以选择 一 的 起来是50%的概率 。
thinkbayes.Joint 了 最大 然 的 法:
# class Joint:
def MaxLikeInterval(self, percentage=90):
interval = []
total = 0
t = [(prob, val) for val, prob in self.Items()]
t.sort(reverse=True)
for prob, val in t:
interval.append(val)
total += prob
if total >= percentage/100.0:
break
return interval
percentages = [75, 50, 25]
for p in percentages:
interval = suite.MaxLikeInterval(p)
for pair in interval:
d[pair] += 1
return d
9.8
讨
章的内 说 了 章里 到的贝 架可扩展到 维参 。唯一的 在 , 个
由参 元 来 示。
联 分布
缘分布
9.9
习
练习9-1。
10.1
假说
我对古 科学有 爱。最近我访问了Norumbega ,这是一个 ·诺顿· 福德 的不
纪念 , 是双效发 和赝 的发 。不过这不是 章要讨 的。
章是 变异 说,
来自http://en.wikipedia.org/wiki/Variability_hypothesis。
我以下 个步 进 :
10.2
值和标准差
在
9
章我们通过 合分 时 了 个参 。在 章中,我们用 的 法来 分 的参
:均 mu, 准差sigma。
def __init__(self, mus, sigmas):
thinkbayes.Suite.__init__(self)
pairs = [(mu, sigma)
for mu in mus
for sigma in sigmas]
thinkbayes.Suite.__init__(self, pairs)
def Likelihood(self, data, hypo):
x = data
mu, sigma = hypo
like = thinkbayes.EvalGaussianPdf(x, mu, sigma)
return like
σ的 量是 的 准 差,s。
下 就是 有 的 :
def FindPriorRanges(xs, num_points, num_stderrs=3.0):
# compute m and s
n = len(xs)
m = numpy.mean(xs)
s = numpy.std(xs)
# compute ranges for m and s
stderr_m = s / math.sqrt(n)
mus = MakeRange(m, stderr_m)
stderr_s = s / math.sqrt(2 * (n-1))
sigmas = MakeRange(s, stderr_s)
return mus, sigmas
xs是据集。num_points是取 围内 的 的个 。num_stderrs是 量 侧 围的宽度,以
准误差 。
是mu和sigma 对构成的一个 。
MakeRange 下:
def MakeRange(estimate, stderr):
spread = stderr * num_stderrs
array = numpy.linspace(estimate-spread,
estimate+spread,
num_points)
return array
10.3
更新
最后,下 是创 和更新Suite对象的 :
mus, sigmas = FindPriorRanges(xs, num_points)
suite = Height(mus, sigmas)
suite.UpdateSet(xs)
print suite.MaximumLikelihood()
10.4
CV的后验分布
一 有了mu和sigma的后 合分 ,我们就可以 出男女的CV分 ,自然地,其中一个的概率会
超过 外一个的概率。
分 很 , 还有 个额外的我们必须 的问题。
以下 这 问题 其 决 案。
10.5
据下
BRFSS 据集选择 100个 进 我 说的分 , 会 常, 得到看起来合 的
后 分 。
Log Pmf中概率的对 :
# class Pmf
def Log(self):
m = self.MaxLike()
for x, p in self.d.iteritems():
if p:
self.Set(x, math.log(p/m))
else:
self.Remove(x)
下 是LogUpdateSet的 现:
# class Suite
def LogUpdateSet(self, dataset):
for data in dataset:
self.LogUpdate(data)
LogUpdateSet 历 据并调用LogUpdate:
# class Suite
def LogUpdate(self, data):
for hypo in self.Values():
like = self.LogLikelihood(data, hypo)
self.Incr(hypo, like)
def Exp(self):
m = self.MaxLike()
for x, p in self.d.iteritems():
self.Set(x, math.exp(p-m))
10.6
对 似然
现在我们 要的是Loglikelihood。
# class Height
def LogLikelihood(self, data, hypo):
x = data
mu, sigma = hypo
loglike = scipy.stats.norm.logpdf(x, mu, sigma)
return loglike
norm.logpdf PDF的对 然 。
下 是整个更新过 :
suite.Log ()
suite.LogUpdateSet (xs)
suite.Exp ()
suite.Normalize ()
10.7
一个小的优
通过 学和 的优 倍地 快了速度。 下一 了一 还要更快的 法。 以, 你
想直接得到好 法,那么可以 过这一 。
我们 开始 的PDF:
并 对 log(去 了常 项):
对 给 的 xi,总对 然是
去 不 i的项,得到
这一过 转 为Python 下:
# class Height
def LogUpdateSetFast(self, data):
xs = tuple(data)
n = len(xs)
for hypo in self.Values():
mu, sigma = hypo
total = Summation(xs, mu)
loglike = -n * math.log(sigma) - total / 2 / sigma**2
self.Incr(hypo, loglike)
储先
cache 的总和。 可能try语 cache中 一个结 , 则 总和, 缓 并
结 。
唯一美中不 的是,我们不能用 为缓 中的一个key, 为 不是一个哈希类型。这就是为什
么LogUpdateSetFast 据集转 为一个元 。
10.8
ABC( 似贝 斯 )
是,也许你耗不起这 的时 。这时 ,近 贝 (ABC)就是合 的 法了。ABC 后的
动 是, 据集的 然度有以下 点。
2. 开销大, 以我们不得不做这么多的优 。
3. 并非我们 要 的。
地, 的 准差分 s,也是为参 和 的 分 。
# compute sample statistics
m = numpy.mean(xs)
s = numpy.std(xs)
for hypo in sorted(self.Values()):
mu, sigma = hypo
# compute log likelihood of m, given hypo
stderr_m = sigma / math.sqrt(n)
loglike = EvalGaussianLogPdf(m, mu, stderr_m)
#compute log likelihood of s, given hypo
stderr_s = sigma / math.sqrt(2 * (n-1))
loglike += EvalGaussianLogPdf(s, sigma, stderr_s)
self.Incr(hypo, loglike)
在我的 脑这个 整个 据集用时大约1 ,得到的结 有5位 的 度 结 一 。
10.9
的可
我们 差不多可以看到结 了, 还有一个问题要 。 据集中有一 是 误的异常
据 。例 ,有3个男人 为61
米,也就是说他们是 界上最 的成年人了。 外,有四个 229
米的女 ,这个 据 界上最 的女人 一点。
alpha = (1-p) / 2
ipr = cdf.Value(1-alpha) - cdf.Value(alpha)
return median, ipr
median, ipr = MedianIPR(xs, half_p * 2)
s = ipr / 2 / num_sigmas
return median, s
10.10
的 更大?
我们 可以 开 的问题了:男 的变异 女 更大 ?
对 一个 合分 ,我 了CV的后 分 。图10-3显示了男 和女 的这 分 结 。男 平
均 为0.0410;女 的平均 为0.0429。由 没有重 ,我们可以 较 地得出女 在
男 变异 更大的结 。
图10-3
男 和女 变异 CV的后 分 CDF 线,基 可靠型
10.11
讨
还有 对ABC的看法。一 是, 称 指的,和 用 的 ,近 法 起来
更快。
请记住,贝 分 总是基 型决 的,这 着不 在“ ”的 决 案。 人 的物
统都可能 在许多 型, 个 型产生不 的结 。要对结 进 ,就必须 型。
10.12
习
练习10-1。
“ 效 应 量 ( effect
size ) ” 是 一 个 在 量 的 差 异 的 统 量 (
http://en.wikipedia.org/wiki/Effect_size)。
无量 的效应量就是
示: 枚 个分 有 对的时 太 ,应 。
第11
假设 验
11.1
回到
27
的“欧元问题”中,我 了来自麦凯《 息、 、 和学习 法》中的一个问题:
那么,这一结 是 为“ 币 心 非均 ” 了证据呢?
在欧元问题的例子中,我们 个 : 用F 示 币是 心的 ,B 示 币是均 的
。
我们可以创 一个调用Likelihood的Euro
suite对象:
suite = Euro()
likelihood = suite.Likelihood(data, 50)
11.2
来一个公 的对
为了 现一个 的对 ,我们必须在无 据的情况下先 B。那么我们来尝试一个不 的
。 查 利时欧元 币,你可能会 到“ ” “反 ”更 出。可以猜想,形状对x有一 的
, 不能 是 就是这一 让 多 少一点。 以,你可能会想:“我 为 币 心, 以x
是0.6 0.4, 不 道究竟是多还是少。”
Normalize 下:
def Normalize(self):
total = self.Total()
factor = 1.0 / total
for x in self.d:
self.d[x] *= factor
return total
Normalize的 是Suite对象中以先 的概率 的总概率 , 子 的平均 然度。Update
续 这个 , 以不用对SuiteLikelihood进 ,我们就可以像下 这 b_uniform的 然度:
likelihood= b_uniform.Update(data)
11.3
三角前验
在 4章中,我们还讨 了形 三 的 分 ,其在50%附近的 有更 的概率。 子 的
先 分 为三 ,可以这 的 然度:
b_triangle = TrianglePrior()
likelihood= b_triangle.Update(data)
11.4
讨
对 B_uniform,贝 子为0.47,和F对 ,这 着 据 的证据反对这一 。在 的部
分中,我 这一证据描 为“弱”, 没有说 原 。
1~3 不 一
3~10 可 的
10~30 强
30~100 很强
>100 决 的
11.5
习
练习11-1。
练习11-2。
12.1
读SAT成
你是 诸 一个工 学 的 生 , 在 个 选人爱丽 和 ,他们在许多
的 历都差不多,只是爱丽 在SAT 学部分的得分更 。SAT是 在 量大学 平 学准 情况的 准
试。
12.2
得分SAT
为了 SAT成 ,我们要了 得分和 例分 的 过 。 个 试 基 对题和 题的 量会得
到一个原始分 。原始得分 转 为200~800 的 例分 。
12.3
先验
美国大学 事会还发 了 有 试 例分 的分 。 我们 一个 例分 转 为原始分 ,
并除以题目 量,那么结 就是p_correct的 。 以我们可以 用原始分 的分 为p_correct的先
分 。
下 是读取并 据的 :
class Exam(object):
def __init__(self):
self.scale = ReadScale()
scores = ReadRanks()
score_pmf = thinkbayes.MakePmfFromDict(dict(scores))
self.raw = self.ReverseScale(score_pmf)
self.prior = DivideValues(raw, 54)
def __init__(self, exam, score):
thinkbayes.Suite.__init__(self)
self.exam = exam
self.score = score
# start with the prior distribution
for p_correct, prob in exam.prior.Items():
self.Set(p_correct, prob)
# update based on an exam score
self.Update(score)
k = self.exam.Reverse(score)
n = self.exam.max_score
like = thinkbayes.EvalBinomialPmf(k, n, p_correct)
return like
hypo是p_correct的一个 ,data为 例分 。
12.4
后验
图12-2显示了在爱丽 和 分 基础上得到的p_correct的后 分 。我们可以看到, 们重 在
一起,有可能 的p_correct更 , 不可能。
图12-2
爱丽 和 的p_correct的后 分
A:p_correct上,爱丽 。
B:p_correct上, 爱丽 。
a_like = thinkbayes.PmfProbGreater(a_sat, b_sat)
b_like = thinkbayes.PmfProbLess(a_sat, b_sat)
c_like = thinkbayes.PmfProbEqual(a_sat, b_sat)
a_like += c_like / 2
b_like += c_like / 2
self.Mult('A', a_like)
self.Mult('B', b_like)
self.Normalize()
下 的 创 了TopLevel并更新 :
exam = Exam()
a_sat = Sat(exam, 780)
b_sat = Sat(exam, 740)
top = TopLevel('AB')
top.Update((a_sat, b_sat))
top.Print()
12.5
一个更好的模型
请记住,我们 今 做的分 都是基 有SAT问题是 度的 下的。 上,有 题 其他
题要 ,这 着爱丽 和 的差异可能会更小。
此 是 项 响 理 的 线 的 一 个 , 你 可 以 参
http://en.wikipedia.org/wiki/Item_response_theory。 题效率和 度 平基 一刻度 平,得到 案
的概率就只取决 们 的差异。
ps = [ProbCorrect(efficacy, diff) for diff in difficulties]
pmfs = [BinaryPmf(p) for p in ps]
dist = sum(pmfs, pmf0)
return dist
def MakeRawScoreDist(self, efficacies):
pmfs = thinkbayes.Pmf()
for efficacy, prob in efficacies.Items():
scores = PmfCorrect(efficacy, self.difficulties)
pmfs.Set(scores, prob)
mix = thinkbayes.MakeMixture(pmfs)
return mix
12.6
校准
我们 度的分 情况,我们就可以 用 MakeRawScoreDist 原始分 的分 。 对 我们来
说,问题是类 的其他 法:有原始分 的分 ,要 断 度的分 。
度的分 是带有参 center
和width的均 分 ,MakeDifficulties可以得到这 参 下试题 度的 。
def MakeDifficulties(center, width, n):
low, high = center-width, center+width
return numpy.linspace(low, high, n)
通过尝试了 个 合,我发现,center=
−0.05和width=
1.8得到的原始分 分 类 据,
图12-3 示。
图12-3
原始分 的 分 和一个拟合 的 型
下 显示了不 效率 的 试 ProbCorrect的 围:
(Difficulty)
答 效 (Efficacy)
−1.85 −0.05 1.75
3.00 0.99 0.95 0.78
1.50 0.97 0.82 0.44
0.00 0.86 0.51 0.15
−1.50 0.59 0.19 0.04
−3.00 0.24 0.05 0.01
12.7
效 的后验分布
现在, 型 准了,我们可以为爱丽 和 题效率的后 分 。下 是一个 用
型的Sat类的新 :
class Sat2(thinkbayes.Suite):
def __init__(self, exam, score):
self.exam = exam
self.score = score
# start with the Gaussian prior
efficacies = thinkbayes.MakeGaussianPmf(0, 1.5, 3)
thinkbayes.Suite.__init__(self, efficacies)
# update based on an exam score
self.Update(score)
pmf = self.exam.PmfCorrect(efficacy)
like = pmf.Prob(raw)
return like
12.8
预测分布
到目 为 我们 做的分 了爱丽 和 的效率, 由 效率是无法直接 察到的 以 以
证结 。
我们 通 个步 这个问题:
a_pred = exam.MakeRawScoreDist(a_sat)
b_pred = exam.MakeRawScoreDist(b_sat)
,
a_like = thinkbayes.PmfProbGreater(a_pred b_pred)
,
b_like = thinkbayes.PmfProbLess(a_pred b_pred)
,
c_like = thinkbayes.PmfProbEqual(a_pred b_pred)
12.9
讨
我们以问题“爱丽 准 更充分的证据有多强”为 章的开始,这个问题 上 起来像我们想
试 个 :要么爱丽 ,要么 准 得更好。
此 个分 是独 的。
13.1
的
我是在线统 http://reddit.com/r/statistics的忠 用户,也偶 内 。2011年11月,我在那儿
读到了以下消息:
13.2
一个简 模型
在尝试更有挑 的东西 , 用 型一般是不 的。对 手 的一 问题 型有时就
了, 不是,你还可以用 型来 证更 杂的 型。
我的 型是: 为 的生 有 的倍 时 , 是三维的, 一维 度 量
翻倍,体积就是 倍(2×2×2=8)。
# doubling time in linear measure is doubling time in volume * 3
dt = 811.0 * 3
# number of doublings since discharge
doublings = interval / dt
# how big was the tumor at time of discharge (diameter in cm)
d1 = 15.5
d0 = d1 / 2.0 ** doublings
# how many doublings would it take to get from d0 to d1
doublings = log2(d1 / d0)
# what linear doubling time does that imply?
dt = interval / doublings
# compute the volumetric doubling time and RDT
vdt = dt / 3
rdt = 365 / vdt
以, 一 ,我得出的结 是“较有可能” 形成 伍 。
13.3
更 遍的模型
在 断时的大小, 道 在 一个给 时 形成的概率, 年龄(生 时 )
的分 是最有用的。
真以一个小 开始,并以下 这 步 :
1. RDT的分 中选取一个 率;
2.在 个 的结 的 寸;
3.记 在 个时 隔里 的 寸;
4.重 ,直到 超过最大的 应 寸。
图13-2
的 真时 和大小
我用线 度展示出结 , 上是依据体积进 的。 ,为了 一个转 到 一个,我以
给 的直径来 示球体的体积。
13.4
实现
下 是这一 真的 心 :
def MakeSequence(rdt_seq, v0=0.01, interval=0.67, vmax=Volume(20.0)):
seq = v0,
age = 0
for rdt in rdt_seq:
age += interval
final, seq = ExtendSequence(age, seq, rdt, interval)
if final > vmax:
break
return seq
return final, new_seq
13.5
存联 分布
以下是cache的功能。
class Cache(object):
def __init__(self):
self.joint = thinkbayes.Joint()
def Add(self, age, seq):
final = seq[-1]
cm = Diameter(final)
bucket = round(CmToBucket(cm))
self.joint.Incr((age, bucket))
图13-3显示了1000 真后的 合分 。
图13-3
大小和年龄的 合分
13.6
分布
通过 合分 取垂直切 ,我们可以得到对 给 年龄的 寸大小分 。通过做一 平切
,我们可以得到给 寸的年龄分 。
def ConditionalCdf(self, bucket):
pmf = self.joint.Conditional(0, 1, bucket)
cdf = pmf.MakeCdf()
return cdf
bucket是对应 大小的整 。Joint.Conditional 给 bucket 下年龄的PMF。其结 是给
bucket下年龄的CDF。
percentiles = [95, 75, 50, 25, 5]
for bucket in cache.GetBuckets():
cdf = ConditionalCdf(bucket)
ps = [cdf.Percentile(p) for p in percentiles]
13.7
序列
到目 为 ,得到的结 都是基 多项 决 的;让我们 顾一下这 ,看看 是误差最有
可能的来 。
下:
def CorrelatedGenerator(cdf, rho):
x = random.gauss(0, 1)
yield Transform(x)
sigma = math.sqrt(1 - rho**2);
while True:
x = random.gauss(x * rho, sigma)
yield Transform(x)
x的
一个 是均 为0, 准 差为1
的 。对 后续 ,平均 和 准 差依 先 的 。
给 上一个x,下一个 的平均 为x * rho, 差为1
-
rho**
2
。
def Transform(x):
p = thinkbayes.GaussianCdf(x)
y = cdf.Value(p)
return y
iterator = CorrelatedGenerator(cdf, rho)
seq2 = MakeSequence(iterator)
下 是 :
# class Cache
def ProbOlder(self, cm, age):
bucket = CmToBucket(cm)
cdf = self.ConditionalCdf(bucket)
p = cdf.Prob(age)
return 1-p
生 没有 后 的条件下,一个15.5 米 的年龄是8岁以上的概率是0.999
, 切无
了。 为0.4的 下, 一个更快生 的 ,概率 然是0.995。 为0.8,概率还是0.978。
此, 到 误差,这么大的 形成不到8年也是不可能的。
13.8
讨
好了,我们一整章都没有 用贝 封 了贝 更新的Suite类。怎么 事?
以,我们是绕过了贝 , 我们 他 在。
③译 :bucket直译不恰 , 原 。
14.1
器
我是 姆· 贝 -里基 那儿 道下 这个问题的,他是“最大熵”博客http://maximum-entropy-
blog.blogspot.com的 。 他是 的《概率 :科学的 》的 E.T. 恩 那儿 道这个问题
的:
1. 射 以平均速率r发射 子。
2.在 给 的1 内, 射 向 器发射了n个 子。
现在,我们希望用 一个 法: 据, 得参 的分 。这就是 的 。 能 决
向问题,你就可以 用贝 法来 决 向问题。
14.2
简 的开
让我们 问题的一个 的 —— r ——开始。给 f的 , 以要做的就是 n。
我 了一个 为Detector的Suite对象,对 器 并 n。
class Detector(thinkbayes.Suite):
def __init__(self, r, f, high=500, step=1):
pmf = thinkbayes.MakePoissonPmf(r, high, step=step)
thinkbayes.Suite.__init__(self, pmf, name=r)
self.r = r
self.f = f
现在我们 要一个 然 :
# class Detector
def Likelihood(self, data, hypo):
k = data
n = hypo
p = self.f
return thinkbayes.EvalBinomialPmf(k, n, p)
data是 到的 子 量,hypo是发射出的 子的 量。
这就是 器对象了。我们可以试着 出r 的 围:
f = 0.1
k = 15
for r in [100, 250, 400]:
suite = Detector(r, f, step=1)
suite.Update(k)
print suite.MaximumLikelihood()
图14-1显示了n对 个给 r 的后 分 。
14.3
分层模型
在上一 中,我们 r为 的。现在,让我们 松这一 。我 了 一个Suite对象,称为
Emitter, 对发射器 并 r的 围:
class Emitter(thinkbayes.Suite):
def __init__(self, rs, f=0.1):
detectors = [Detector(r, f) for r in rs]
thinkbayes.Suite.__init__(self, detectors)
# class Detector
def SuiteLikelihood(self, data):
total = 0
for hypo, prob in self.Items():
like = self.Likelihood(data, hypo)
total += prob * like
return total
现在我们可以写出发射器的 然 :
# class Detector
def Likelihood(self, data, hypo):
detector = hypo
like = detector.SuiteLikelihood(data)
return like
更新了发射器后,我们也必须更新 个探 器。
# class Detector
def Update(self, data):
thinkbayes.Suite.Update(self, data)
for detector in self.Values():
detector.Update()
像这 有多 Suite对象的 型 称为分层模型。
14.4
一个小优
你也许对SuiteLikelihood有印象;我们在 110 “来一个 平的对 ”中 过 。 时我指出我们并
不真的 要 , 为由SuiteLikelihood 的总概率是由Update 并 的归一 常 。
下 是Emitter.Likelihood的 :
# class Emitter
def Likelihood(self, data, hypo):
return hypo.Update(data)
以这个 的Likelihood,我们就可以 用Update的默 。 此 更少, 为 不用
归一 常量 , 以 得更快。
14.5
抽 后验
更新了发射器后,我们可以通过 环探 器和其概率得到r的后 分 :
# class Emitter
def DistOfR(self):
items = [(detector.r, prob) for detector, prob in self.Items()]
return thinkbayes.MakePmfFromItems(items)
def DistOfN(self):
return thinkbayes.MakeMixture(self)
图14-2
n和r的后 分
150个 子在1 内 发射,r的最可能的 是 150个 子。 此r的后 分 也集中在150附
近。
14.6
讨
器问题 和分 型 的 。在 示例中,发射率r对 子 n有 效应,
n对 子 量k有 效应。
14.7
习
练习14-1。
要 这个问题,必须做出一 的决 。这里有一 下:
个星期有大量蚊子N在你家附近的 地生 。
一 内,N中一部分f1进入你的 子里,f1中一部分f2 入 。
在你的 法中,要 到“N 可能的变 量”的先 点,可以通过在分 型中 一个 来
对N变 的 分 。
第15
理多
15.1
细
肚 生物多 2.0(BBB2)项目是一个 国 的 科学项目, 在 可以在人类肚 上找到的
细菌 类(http://bbdata.yourwildlife.org)。 项目 异想天开, 是人们越来越 人体微生物的
势的一部分,人体微生物就是那 生活在人体 体 部分的微生物的集合。
我们可以利用这 据来 个 问题:
这 问题构成了 的 知 种 。
15.2
子 老 和
我 这个问题的一个 开始。在这个 中,我们 物 的情况, 称 为狮子、
和熊。 我们参 生动物 护 ,看到了3只狮子、2只 和1 熊。
这里有 个问题:
thinkbayes.py中,有一个 了狄 的类 下
:
class Dirichlet(object):
def __init__(self, n):
self.n = n
self.params = numpy.ones(n, dtype=numpy.int)
在 示例中, 个物 的 缘分 ,
为Beta(1 2)。我们可以 平均 下:
dirichlet = thinkbayes.Dirichlet(3)
for i in range(3):
beta = dirichlet.MarginalBeta(i)
print beta.Mean()
期的那 , 个物 群 例的 均 是1/3。
要更新狄利克雷分 ,我们 这一 察结 到参 :
def Update(self, data):
m = len(data)
self.params[:m] += data
下 是以 察到的 据更新dirichlet并 后 缘分 的 。
data = [3, 2, 1]
dirichlet.Update(data)
for i in range(3):
beta = dirichlet.MarginalBeta(i)
pmf = beta.MakePmf()
print i, pmf.Mean()
图15-1显示了结 。平均 群 例的后 是44%、33%和22%。
15.3
分层 本
我们 决了这个问题的一个 : 我们 道有多少物 ,我们可以 一个的 群
例。
类 下:
class Species(thinkbayes.Suite):
def __init__(self, ns):
hypos = [thinkbayes.Dirichlet(n) for n in ns]
thinkbayes.Suite.__init__(self, hypos)
下 是创 Suite对象的 :
ns = range(3, 30)
suite = Species(ns)
ns 是 n 的可能 的 。由 看到3个物 , 以必须为至少3个。我选择了一个 合 的上
,稍后会 查得 超过这个界 的概率很 。并 至少在最 段,我们 在此 围内的 都是
可能的。
def Update(self, data):
thinkbayes.Suite.Update(self, data)
for hypo in self.Values():
hypo.Update(data)
Species.Update调用父类中的Update,然后 历子 并更新 们。
现在,我们 要一个 然 :
# class Species
def Likelihood(self, data, hypo):
dirichlet = hypo
like = 0
for i in range(1000):
like += dirichlet.Likelihood(data)
return like
下 是 例:
# class Dirichlet
def Likelihood(self, data):
m = len(data)
if self.n < m:
return 0
x = data
p = self.Random()
q = p[:m]**x
return q.prod()
def Random(self):
p = numpy.random.gamma(self.params)
return p / p.sum()
DistOfN通过在 中 ,并 个n的概率。
图15-2
n的后 分
请记住,这个结 基 n的先 是均 分 的。 我们 道物 在环境中 量的 景 息,我们可
以选择一个不 的先
。
15.5
优
必须承 ,我对 这个例子中的 法很自豪。未 物 问题并不 , 这个 法 了,只用了
少的 以 (约50 )。
15.6
的层次
有底 的狄利克雷分 以 的 据更新, 以对 们来说, m个参 。我们可以通过 参
合并入 Suite对象来消除这一重 过 。Species2 现了这一优 :
class Species2(object):
def __init__(self, ns):
self.ns = ns
self.probs = numpy.ones(len(ns), dtype=numpy.double)
self.params = numpy.ones(self.high, dtype=numpy.int)
def Update(self, data):
like = numpy.zeros(len(self.ns), dtype=numpy.double)
for i in range(1000):
like += self.SampleLikelihood(data)
self.probs *= like
self.probs /= self.probs.sum()
m = len(data)
self.params[:m] += data
现在,让我们来看看SampleLikelihood,这里有 个可优 的地 。
, 多项式的PMF是
以对 然度是
def SampleLikelihood(self, data):
gammas = numpy.random.gamma(self.params)
m = len(data)
row = gammas[:m]
col = numpy.cumsum(gammas)
log_likes = []
for n in self.ns:
ps = row / col[n-1]
terms = data * numpy.log(ps)
log_like = terms.sum()
log_likes.append(log_like)
log_likes -= numpy.max(log_likes)
likes = numpy.exp(log_likes)
coefs = [thinkbayes.BinomialCoef(n, m) for n in self.ns]
likes *= coefs
return likes
15.7
另一个
我们还可以做得更多来优 这一 , 有 外一个 要首先 的问题。 着 察到的物 目的
,这个 的 法变得让人心 , 要更多的 能收 到一个好的结 。
下 是 更新一个物 的新 :
class Species4(Species):
def Update(self, data):
m = len(data)
for i in range(m):
one = numpy.zeros(i+1)
one[i] = data[i]
Species.Update(self, one)
下 是 然度的新 :
# class Species4
def Likelihood(self, data, hypo):
dirichlet = hypo
like = 0
for i in range(self.iterations):
like += dirichlet.Likelihood(data)
# correct for the number of unseen species the new one
# could have been
m = len(data)
num_unseen = dirichlet.n - m + 1
like *= num_unseen
return like
15.8
还有 作要做
一个物 的更新 决了一个问题, 也带来了 一个问题。 更新 要的时
km,其中k是 的 目,m是 察到的物 的 量。 此, 我们做m 更新,总 时
km2。
def Update(self, data):
m = len(data)
for i in range(m):
self.UpdateOne(i+1, data[i])
self.params[i] += data[i]
def UpdateOne(self, i, count):
likes = numpy.zeros(len(self.ns), dtype=numpy.double)
for i in range(self.iterations):
likes += self.SampleLikelihood(i, count)
unseen_species = [n-i+1 for n in self.ns]
likes *= unseen_species
self.probs *= likes
self.probs /= self.probs.sum()
此 类 Species2.Update, 有 个变 。
最后,SampleLikelihood 下
:
# class Species5
def SampleLikelihood(self, i, count):
gammas = numpy.random.gamma(self.params)
sums = numpy.cumsum(gammas)[self.ns[0]-1:]
ps = gammas[i-1] / sums
log_likes = numpy.log(ps) * count
log_likes -= numpy.max(log_likes)
likes = numpy.exp(log_likes)
return likes
15.9
据
狮子、 和熊的问题讨 得 了。现在让我们 到肚 问题。为了得到 据的含 ,
B1242 题,其400个 记 产生了 下 的61个物 :
92, 53, 47, 38, 15, 14, 12, 10, 8, 7, 7, 5, 5,
4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
def __init__(self, code):
self.code = code
self.species = []
def DistN(self):
items = zip(self.ns, self.probs)
pmf = thinkbayes.MakePmfFromItems(items)
return pmf
图15-3 题B1242中n的分
def DistOfPrevalence(self, index):
metapmf = thinkbayes.Pmf()
for n, prob in zip(self.ns, self.probs):
beta = self.MarginalBeta(n, index)
pmf = beta.MakePmf()
metapmf.Set(pmf, prob)
mix = thinkbayes.MakeMixture(metapmf)
return metapmf, mix
15.10
预测分布
在4个 问题中,我 了 物 的问题。通过 n和 个物 群 例的后 分 ,我们
了 个。
外 个问题是:
这 真过 的 心是:
1. 后 分 选取n ;
3.生成未来 的 ;
4. 新物 的 量,num_new, 为额外 k的 ;
5.重 的步 , num_new和k的 合分 。
下 的 RunSimulation 了一个 真:
# class Subject
def RunSimulation(self, num_reads):
m, seen = self.GetSeenSpecies()
n, observations = self.GenerateObservations(num_reads)
curve = []
for k, obs in enumerate(observations):
seen.add(obs)
num_new = len(seen) - m
curve.append((k+1, num_new))
return curve
查结 ,我们来看看GetSeenSpecies和GenerateObservations。
#class Subject
def GetSeenSpecies(self):
names = self.GetNames()
m = len(names)
seen = set(SpeciesGenerator(names, m))
return m, seen
while i < num:
yield 'unseen-%d' % i
i += 1
GenerateObservations 下:
# class Subject
def GenerateObservations(self, num_reads):
n, prevalences = self.suite.SamplePosterior()
names = self.GetNames()
name_iter = SpeciesGenerator(names, n)
d = dict(zip(name_iter, prevalences))
cdf = thinkbayes.MakeCdfFromDict(d)
observations = cdf.Sample(num_reads)
return n, observations
的,num_reads是要生成的额外 。n和prevalences是后 分 的 。
最后,Species2.SamplePosterior 下:
def SamplePosterior(self):
pmf = self.DistOfN()
n = pmf.Random()
prevalences = self.SamplePrevalence(n)
return n, prevalances
SamplePrevalences生成 群 例在条件为n时的 :
# class Species2
def SamplePrevalences(self, n):
params = self.params[:n]
gammas = numpy.random.gamma(params)
gammas /= gammas.sum()
return gammas
15.11
联 后验
我们可以利用这 真来 num_new和k的 合分 ,由此,我们还可以得到num_new在k为 条
件下的分 。
def MakeJointPredictive(curves):
joint = thinkbayes.Joint()
for curve in curves:
for k, num_new in curve:
joint.Incr((k, num_new))
joint.Normalize()
return joint
cdfs = []
for k in ks:
pmf = joint.Conditional(1, 0, k)
pmf.name = 'k=%d' % k
cdf = pmf.MakeCdf()
cdfs.append(cdf)
return cdfs
15.12
我们要 最后一个问题:“ 要 多少额外的 记 , 能 察到物 例 到一个给
的阈 ”?
def RunSimulation(self, num_reads):
m, seen = self.GetSeenSpecies()
n, observations = self.GenerateObservations(num_reads)
curve = []
for k, obs in enumerate(observations):
seen.add(obs)
frac_seen = len(seen) / float(n)
curve.append((k+1, frac_seen))
return curve
接下来, 环 一条 线并创 一个字 d, 射额外 量k到一个fracs ,也就是在取得k个
后得到的 率 的 。
def MakeFracCdfs(self, curves):
d = {}
for curve in curves:
for k, frac in curve:
d.setdefault(k, []).append(frac)
cdfs = {}
for k, fracs in d.iteritems():
cdf = thinkbayes.MakeCdfFromList(fracs)
cdfs[k] = cdf
return cdfs
15.13
讨
未 物 问题是一个活跃的研究领域,我 章中的 法为此 了一 新 。在不到200 的篇
幅里,我们 概率 基础扩展到了研究的 沿,这 我感到 兴。
中,我的目的是 达出3个 的 念。
封 图 来自迈 •克 词 。
后
的翻译其 来自和编 开过的一个玩 ,我 时戏说这 的 Think
Bayes不妨译成《纪念贝
先生》, 上托 ·贝 先生也的 是一个 大的 得我们纪念的人,科学的历 是由
这 一 大的人们 动的。贝 发展并 出了我们现在 悉的贝 , 后人们也利用这一工
发展出了 的“贝 法”。读 这 ,我 读 对此会有 刻的 。
总 ,这 不到200 的 对 得一读 读。
译 许
2014年8月 颐和 北
欢迎来到 步社区
步社区的来历
异步社 (www.epubit.com.cn)是人 出 社旗下IT专业图 旗舰社 , 2015年8月上线 。
异步社 依托 人 出 社20余年的IT专业优 出 和编 团 , 统出 子
出 和自出 结合、 子 结合、 统印刷 POD 印刷结合的出 平台, 最新 术
息,为 和读 交流互动的平台。
社区里都有什么?
购
下 资
社 内 附 的 , 中的案例 。
灵活优 的购
可以 便地下 购买 图 子图 , 图 直接 人 出 社 库发货, 子
多 读格式。
别优
电 组 购
社区里还可以做什么?
会议活动 知道
加 步
描 维 都能找到我们:
异步社
微 订
微 服
官 微博
QQ群:368449889
社区网 www.epubit.com.cn
官方微信 异步社
& contact@epubit.com.cn