贝叶斯推断简介

你是一名程序员,今天你实现了一个非常复杂的算法。你不知道这段代码有没有 bug。根据你以往的经验,写出 bug 是在所难免的,毕竟你不是 Jeff Dean。你先拿一些简单的测试用例 run 了一下,通过了。你又试了一些复杂的测试用例,也通过了。接下来,你连续试了一大堆用例,都通过了。于是你松了一口气,开始觉得这段程序可能没有 bug 了。

如果你这样思考问题,那么恭喜你,你是一个贝叶斯主义者。所谓贝叶斯推断,说白了,就是在观察到新的证据之后,更新你的信念。贝叶斯主义者往往不会对某件事确信无疑,但他可以对某件事很有信心。拿上面的例子来说,我们无法保证代码 100% 没有 bug(除非穷尽所有可能的情况)。但当代码通过了大量的测试用例之后,我们对它更有信心了。

我们经常用到“概率”这个词,但对什么是“概率”,其实是有不同看法的。

  • 贝叶斯学派看来,一个事件的概率是人们根据已有的知识和经验对该事件发生的可能性所给出的个人信念[1],这种信念用区间 [0,1] 中的一个数来表示,可能性大的对应较大的数。
  • 与之相对的,在频率学派看来,一个事件在独立重复实验中发生的频率会趋于一个极限,这个极限就是该事件的概率。

乍一看,频率学派的观点好像更严谨。举例来说,你想知道抛一枚硬币国徽朝上的概率,你就不停地抛这枚硬币,统计国徽朝上的次数的占比,随着你抛的次数的增多,你会发现这个占比渐渐趋于稳定,这个极限值就是国徽朝上的概率。问题是,有些情形下,你是无法做独立重复实验的。比如老板问你目前负责的某个项目有多大的概率能拿到业务成果。这个项目只能做一次,要么成功,要么失败,怎么计算成功的频率呢?对此,频率学派可能会告诉你,假设有很多个平行世界,这个项目在一些平行世界里成功了,而在另一些平行世界里失败了。这个项目成功的概率就是在平行世界里成功的频率的极限。但作为贝叶斯主义者,我们不需要诉诸虚无缥缈的平行世界。基于以往的工作经验和对这个项目现状的分析,我们依然能够给出我们的信念,“老板,我有 7 成把握,这个项目能成。”

我们把对事件 A 发生的可能性的信念记为 P(A),称作事件 A先验概率(prior probability)。当观察到证据 E 之后,我们更新了对事件 A 的信念。更新后的信念记为 P(A|E),称作事件 A后验概率(posterior probability)[2]。那么,在观察到证据 E 之后,我们怎么才能更新先验概率来得到后验概率呢?很简单,我们使用贝叶斯定理[3]
\begin{aligned} P(A|E) &= \frac{P(E|A)P(A)}{P(E)} \\ &\propto P(E|A)P(A) \end{aligned}
P(E|A) 是当事件 A 发生时,我们观察到证据 E 的概率。它是关于证据 E 的函数,称作证据 E似然函数(likelihood)

例 1:2020 年 12 月 23 日,你看完勇士 VS 篮网的比赛,库里三分球 10 投 2 中。你想预测一下库里在本赛季的三分球命中率。因为这是库里本赛季的第一场比赛,直接用 2/10=20\% 显然是不合理的。那么该怎么做呢?

查阅资料,我发现库里在最近的两个赛季三分球一共是 859 投 366 中。用 \Theta 表示库里本赛季三分球的命中率。根据历史数据,我认为 \Theta 服从参数为 \alpha=366\beta=859-366=493 的 Beta 分布。即我对库里本赛季三分球命中率 \Theta=\theta 的信念为
P(\Theta=\theta)=\mathrm{Beta}(\theta;\alpha=366, \beta=493)
Beta 分布的期望为
\mathbb E(\Theta)=\frac{\alpha}{\alpha+\beta}
所以,在开始的时候,我觉得库里本赛季的三分球命中率会在 366/(366+493)\approx42.61\% 附近波动。

已知库里的三分命中率为 \theta ,那么他投 n 次三分球命中的次数 X 应该服从参数为 n\theta 的二项分布,即似然为
P(X=x|\Theta=\theta)=\mathrm{Binomial}(x;n,\theta)
在看到本场比赛库里 10 投 2 中的结果后,我就可以更新我的信念了。我们有
\mathrm{Beta}(\theta;\alpha,\beta) = \frac{1}{\mathrm{B}(\alpha, \beta)}\theta^{\alpha-1}(1-\theta)^{\beta-1}
其中
\mathrm B(\alpha, \beta) = \int_0^1\theta^{\alpha-1}(1-\theta)^{\beta-1}\mathrm d\theta
又有
\mathrm{Binomial}(x;n,\theta) = \frac{\Gamma(n+1)}{\Gamma(x+1)\Gamma(n-x+1)} \theta^x(1-\theta)^{n-x}
因此
\begin{aligned} P(\Theta=\theta|X=x) &= \frac{P(X=x|\Theta=\theta)P(\Theta=\theta)}{P(X=x)} \\ &= \frac{P(X=x|\Theta=\theta)P(\Theta=\theta)}{\int_0^1 P(X=x|\Theta=\theta)P(\Theta=\theta)\mathrm d\theta} \\ &= \frac{\mathrm{Binomial}(x;n,\theta)\mathrm{Beta}(\theta;\alpha,\beta)}{\int_0^1 \mathrm{Binomial}(x;n,\theta)\mathrm{Beta}(\theta;\alpha,\beta)\mathrm d\theta} \\ &=\frac{\frac{1}{\mathrm B(\alpha,\beta)}\theta^{\alpha-1}(1-\theta)^{\beta-1}\cdot\frac{\Gamma(n+1)}{\Gamma(x+1)\Gamma(n-x+1)} \theta^x(1-\theta)^{n-x}}{\int_0^1 \frac{1}{\mathrm B(\alpha,\beta)}\theta^{\alpha-1}(1-\theta)^{\beta-1}\cdot\frac{\Gamma(n+1)}{\Gamma(x+1)\Gamma(n-x+1)} \theta^x(1-\theta)^{n-x} \mathrm d\theta }\\ &=\frac{\theta^{\alpha+x-1}(1-\theta)^{\beta+n-x-1}}{\int_0^1 \theta^{\alpha+x-1}(1-\theta)^{\beta+n-x-1}\mathrm d\theta} \\ &=\frac{1}{\mathrm B(\alpha+x, \beta+n-x)}\theta^{\alpha+x-1}(1-\theta)^{\beta+n-x-1}\\ &\equiv \mathrm{Beta}(\theta;\alpha+x,\beta+n -x) \end{aligned}
于是,我的信念更新为
\begin{aligned} P(\Theta=\theta|X=2) &= \mathrm{Beta}(\theta;\alpha=366+2,\beta=493+10-2)\\ &= \mathrm{Beta}(\theta;\alpha=368,\beta=501) \end{aligned}
也就是说,在观察到库里首场比赛三分球 10 投 2 中之后,我更新了我的信念,认为他本赛季的三分球命中率将会在 368/(368+501)\approx42.35\% 附近波动。

看到这些计算过程,有些读者可能已经崩溃了。然而这已经算是最简单的情形之一了。但是别着急,我们并不一定要把后验分布计算出来!我们所关心的无非是后验分布的期望、方差、偏度、峰度之类的统计量,如果我们能够设法从后验分布中采样,就可以利用这些样本来估计这些统计量。那么,有什么方法可以从一个复杂的概率分布中采样呢?非常幸运的是,马尔可夫链蒙特卡洛(Markov chain Monte Carlo, MCMC)方法可以做到这一点。关于这个方法,后续我会专门介绍。这里我们只讲一下实际操作。

在 Python 下,我们可以使用 PyMC3 轻松实现 MCMC 采样。拿上面的例子来说,

import pymc3 as pm
import seaborn as sns

with pm.Model() as model:
    # theta 的先验分布为 Beta 分布
    theta = pm.Beta(
        name='theta', 
        alpha=366, 
        beta=493
    )
    # 似然函数为二项分布
    likelihood = pm.Binomial(
        name='likelihood', 
        p=theta,
        n=10,
        observed=[2]
    )
    # 利用 MCMC 方法从后验分布中采样
    posterior = pm.sample()

# 利用后验分布的样本估计后验分布的期望
print(posterior.theta.mean())
# 0.4234174176263356

# 样本的直方图
sns.distplot(posterior.theta)
采样结果

例 2: 下图展示了某商品在一段时间内每天的销量。请问在这段时间内销量的平均水平是否发生过变化?

商品的销量

S_t 表示第 t 天的销量,这种计数类型的随机变量适合用 Poisson 分布来刻画,即似然为
S_t\sim\mathrm{Poisson}(\lambda)
假设在第 \tau 天,销量的水平发生了变化,则
\lambda=\begin{cases} \lambda_1,&t<\tau\\ \lambda_2,&t\geq\tau \end{cases}
我们只需要给出 \lambda_1\lambda_2\tau 的先验分布,然后利用 MCMC 方法从他们的后验分布中采样即可。
关于 \lambda_1\lambda_2,我们只知道他们一定是正数,且和这段时间的平均销量应该相差不多。因此,我们假设他们的先验分布为指数分布
\begin{aligned} \lambda_1&\sim\mathrm{Exp}(\alpha)\\ \lambda_2&\sim\mathrm{Exp}(\alpha) \end{aligned}
其中 \frac{1}{\alpha} 为这段时间的平均销量。
关于 \tau,我们所知甚少,只能假设它的先验分布是离散均匀分布
\tau\sim\mathrm{DiscreteUniform}(0, 89)

同样地,我们使用 PyMC3 从后验分布中采样

with pm.Model() as model:
    alpha = 1.0 / sales.mean()
    lambda_1 = pm.Exponential('lambda_1', alpha)
    lambda_2 = pm.Exponential('lambda_2', alpha)
    
    tau = pm.DiscreteUniform('tau', lower=0, upper=len(sales)-1)
    
    t = np.arange(len(sales))
    lambda_ = pm.math.switch(t < tau, lambda_1, lambda_2)
    
    likelihood = pm.Poisson('likelihood', lambda_, observed=sales)
    
    posterior = pm.sample(20000, tune=8000, step=pm.Metropolis())

结果如下:

采样结果

根据采样的结果, \lambda_1\lambda_2\tau 的均值分别是
\begin{aligned} \lambda_1 &\approx 17.96\\ \lambda_2 &\approx 24.00\\ \tau &\approx 50.40 \end{aligned}
销量的变化

这几乎就是正确答案了,因为所谓的“销量”实际上是我用下面的代码随机生成的

from scipy.stats import poisson
import numpy as np

sales = []

for _ in range(52):
    sales.append(poisson.rvs(mu=18))
for _ in range(38):
    sales.append(poisson.rvs(mu=23))

sales = np.array(sales)

参考资料


  1. 个人信念?那岂不是每个人都不同?的确如此,因为每个人拥有的知识和经验都不同,对同一件事的判断肯定不一样。举例来说,股(jiu)民(cai)和知道内部消息的大佬对某只股票涨跌的可能性就有不同的信念,正所谓“时间的朋友不如领导的朋友”。

  2. 注意到贝叶斯推断可以迭代使用:后验概率可以当作新的先验概率,从而在观察到更新的证据之后,再次更新我们的信念。

  3. 需要说明的是,这个公式并不是贝叶斯推断所独有的。学习过概率论的朋友一眼就能看出来,这个就是课本上的“逆概公式”。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,699评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,124评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,127评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,342评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,356评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,057评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,654评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,572评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,095评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,205评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,343评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,015评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,704评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,196评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,320评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,690评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,348评论 2 358

推荐阅读更多精彩内容

  • 你是一名经验丰富的程序员,但是bug仍然暗藏在你的代码中。实现一个极其困难的算法后,你决定在一个简单的例子上测试自...
    朱小虎XiaohuZhu阅读 7,815评论 0 30
  • 1.贝叶斯定理的图形解释 小张同学每天去食堂吃饭时,有0.8的概率会打牛肉,并在此基础上有0.7的概率会买可乐,如...
    ArronZhang1997阅读 1,956评论 0 3
  • 什么是风险?风险就是导致损失的可能性。有的风险我们可以判断大小,可以规避,但是面对完全陌生风险我们怎么办?贝叶斯推...
    墨一凡阅读 188评论 0 1
  • 贝叶斯推断 贝叶斯推断的基本概念与传统推断的区别 贝叶斯推断作为统计推断的一种,从样本中学习或拟合真实的模型,推断...
    Asica阅读 1,425评论 0 2
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,539评论 28 53