你是一名程序員榕栏,今天你實(shí)現(xiàn)了一個(gè)非常復(fù)雜的算法扒磁。你不知道這段代碼有沒有 bug。根據(jù)你以往的經(jīng)驗(yàn)缸榛,寫出 bug 是在所難免的内颗,畢竟你不是 Jeff Dean。你先拿一些簡單的測(cè)試用例 run 了一下找前,通過了纸厉。你又試了一些復(fù)雜的測(cè)試用例,也通過了沃缘。接下來,你連續(xù)試了一大堆用例水慨,都通過了。于是你松了一口氣朝抖,開始覺得這段程序可能沒有 bug 了。
如果你這樣思考問題砌滞,那么恭喜你绊茧,你是一個(gè)貝葉斯主義者华畏。所謂貝葉斯推斷,說白了胧卤,就是在觀察到新的證據(jù)之后唯绍,更新你的信念。貝葉斯主義者往往不會(huì)對(duì)某件事確信無疑枝誊,但他可以對(duì)某件事很有信心况芒。拿上面的例子來說,我們無法保證代碼 100% 沒有 bug(除非窮盡所有可能的情況)叶撒。但當(dāng)代碼通過了大量的測(cè)試用例之后绝骚,我們對(duì)它更有信心了。
我們經(jīng)常用到“概率”這個(gè)詞,但對(duì)什么是“概率”,其實(shí)是有不同看法的。
- 在貝葉斯學(xué)派看來,一個(gè)事件的概率是人們根據(jù)已有的知識(shí)和經(jīng)驗(yàn)對(duì)該事件發(fā)生的可能性所給出的個(gè)人信念[1]洒宝,這種信念用區(qū)間
中的一個(gè)數(shù)來表示将宪,可能性大的對(duì)應(yīng)較大的數(shù)。
- 與之相對(duì)的,在頻率學(xué)派看來,一個(gè)事件在獨(dú)立重復(fù)實(shí)驗(yàn)中發(fā)生的頻率會(huì)趨于一個(gè)極限,這個(gè)極限就是該事件的概率。
乍一看,頻率學(xué)派的觀點(diǎn)好像更嚴(yán)謹(jǐn)。舉例來說仗谆,你想知道拋一枚硬幣國徽朝上的概率阔涉,你就不停地拋這枚硬幣暖侨,統(tǒng)計(jì)國徽朝上的次數(shù)的占比葫掉,隨著你拋的次數(shù)的增多,你會(huì)發(fā)現(xiàn)這個(gè)占比漸漸趨于穩(wěn)定,這個(gè)極限值就是國徽朝上的概率。問題是,有些情形下,你是無法做獨(dú)立重復(fù)實(shí)驗(yàn)的窍奋。比如老板問你目前負(fù)責(zé)的某個(gè)項(xiàng)目有多大的概率能拿到業(yè)務(wù)成果窖逗。這個(gè)項(xiàng)目只能做一次,要么成功,要么失敗,怎么計(jì)算成功的頻率呢?對(duì)此,頻率學(xué)派可能會(huì)告訴你,假設(shè)有很多個(gè)平行世界,這個(gè)項(xiàng)目在一些平行世界里成功了扯俱,而在另一些平行世界里失敗了为流。這個(gè)項(xiàng)目成功的概率就是在平行世界里成功的頻率的極限莲祸。但作為貝葉斯主義者,我們不需要訴諸虛無縹緲的平行世界∈勇基于以往的工作經(jīng)驗(yàn)和對(duì)這個(gè)項(xiàng)目現(xiàn)狀的分析,我們依然能夠給出我們的信念,“老板鞠评,我有 7 成把握,這個(gè)項(xiàng)目能成÷匦裕”
我們把對(duì)事件 發(fā)生的可能性的信念記為
,稱作事件
的先驗(yàn)概率(prior probability)巩剖。當(dāng)觀察到證據(jù)
之后,我們更新了對(duì)事件
的信念语稠。更新后的信念記為
衣式,稱作事件
的后驗(yàn)概率(posterior probability)[2]。那么,在觀察到證據(jù)
之后,我們?cè)趺床拍芨孪闰?yàn)概率來得到后驗(yàn)概率呢碧绞?很簡單照激,我們使用貝葉斯定理[3]:
是當(dāng)事件
發(fā)生時(shí)六水,我們觀察到證據(jù)
的概率港准。它是關(guān)于證據(jù)
的函數(shù)毛萌,稱作證據(jù)
的似然函數(shù)(likelihood)。
例 1:2020 年 12 月 23 日吨拗,你看完勇士 VS 籃網(wǎng)的比賽哈恰,庫里三分球 10 投 2 中。你想預(yù)測(cè)一下庫里在本賽季的三分球命中率遍希。因?yàn)檫@是庫里本賽季的第一場(chǎng)比賽拥诡,直接用
顯然是不合理的没讲。那么該怎么做呢潘靖?
查閱資料誓军,我發(fā)現(xiàn)庫里在最近的兩個(gè)賽季三分球一共是 859 投 366 中。用 表示庫里本賽季三分球的命中率。根據(jù)歷史數(shù)據(jù)鹰贵,我認(rèn)為
服從參數(shù)為
和
的 Beta 分布。即我對(duì)庫里本賽季三分球命中率
的信念為
Beta 分布的期望為
所以,在開始的時(shí)候电爹,我覺得庫里本賽季的三分球命中率會(huì)在 附近波動(dòng)立哑。
已知庫里的三分命中率為 塞俱,那么他投
次三分球命中的次數(shù)
應(yīng)該服從參數(shù)為
和
的二項(xiàng)分布,即似然為
在看到本場(chǎng)比賽庫里 10 投 2 中的結(jié)果后,我就可以更新我的信念了柔纵。我們有
其中
又有
因此
于是揭蜒,我的信念更新為
也就是說隐轩,在觀察到庫里首場(chǎng)比賽三分球 10 投 2 中之后,我更新了我的信念,認(rèn)為他本賽季的三分球命中率將會(huì)在 附近波動(dòng)。
看到這些計(jì)算過程竣况,有些讀者可能已經(jīng)崩潰了。然而這已經(jīng)算是最簡單的情形之一了悴灵。但是別著急,我們并不一定要把后驗(yàn)分布計(jì)算出來骂蓖!我們所關(guān)心的無非是后驗(yàn)分布的期望积瞒、方差、偏度登下、峰度之類的統(tǒng)計(jì)量茫孔,如果我們能夠設(shè)法從后驗(yàn)分布中采樣,就可以利用這些樣本來估計(jì)這些統(tǒng)計(jì)量被芳。那么缰贝,有什么方法可以從一個(gè)復(fù)雜的概率分布中采樣呢?非常幸運(yùn)的是畔濒,馬爾可夫鏈蒙特卡洛(Markov chain Monte Carlo, MCMC)方法可以做到這一點(diǎn)揩瞪。關(guān)于這個(gè)方法,后續(xù)我會(huì)專門介紹篓冲。這里我們只講一下實(shí)際操作。
在 Python 下宠哄,我們可以使用 PyMC3 輕松實(shí)現(xiàn) MCMC 采樣壹将。拿上面的例子來說,
import pymc3 as pm
import seaborn as sns
with pm.Model() as model:
# theta 的先驗(yàn)分布為 Beta 分布
theta = pm.Beta(
name='theta',
alpha=366,
beta=493
)
# 似然函數(shù)為二項(xiàng)分布
likelihood = pm.Binomial(
name='likelihood',
p=theta,
n=10,
observed=[2]
)
# 利用 MCMC 方法從后驗(yàn)分布中采樣
posterior = pm.sample()
# 利用后驗(yàn)分布的樣本估計(jì)后驗(yàn)分布的期望
print(posterior.theta.mean())
# 0.4234174176263356
# 樣本的直方圖
sns.distplot(posterior.theta)
例 2: 下圖展示了某商品在一段時(shí)間內(nèi)每天的銷量毛嫉。請(qǐng)問在這段時(shí)間內(nèi)銷量的平均水平是否發(fā)生過變化诽俯?
用 表示第
天的銷量,這種計(jì)數(shù)類型的隨機(jī)變量適合用 Poisson 分布來刻畫,即似然為
假設(shè)在第 天暴区,銷量的水平發(fā)生了變化闯团,則
我們只需要給出 、
和
的先驗(yàn)分布仙粱,然后利用 MCMC 方法從他們的后驗(yàn)分布中采樣即可房交。
關(guān)于 和
,我們只知道他們一定是正數(shù)伐割,且和這段時(shí)間的平均銷量應(yīng)該相差不多候味。因此,我們假設(shè)他們的先驗(yàn)分布為指數(shù)分布
其中 為這段時(shí)間的平均銷量隔心。
關(guān)于 白群,我們所知甚少,只能假設(shè)它的先驗(yàn)分布是離散均勻分布
同樣地硬霍,我們使用 PyMC3 從后驗(yàn)分布中采樣
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())
結(jié)果如下:
根據(jù)采樣的結(jié)果帜慢,
這幾乎就是正確答案了唯卖,因?yàn)樗^的“銷量”實(shí)際上是我用下面的代碼隨機(jī)生成的
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)
參考資料
- Probabilistic Programming & Bayesian Methods for Hackers
- Beta distribution - Wikipedia
- Binomial distribution - Wikipedia
- 斯蒂芬-庫里NBA球員虎撲籃球
-
個(gè)人信念粱玲?那豈不是每個(gè)人都不同?的確如此耐床,因?yàn)槊總€(gè)人擁有的知識(shí)和經(jīng)驗(yàn)都不同密幔,對(duì)同一件事的判斷肯定不一樣。舉例來說撩轰,股(jiu)民(cai)和知道內(nèi)部消息的大佬對(duì)某只股票漲跌的可能性就有不同的信念胯甩,正所謂“時(shí)間的朋友不如領(lǐng)導(dǎo)的朋友”。 ?
-
注意到貝葉斯推斷可以迭代使用:后驗(yàn)概率可以當(dāng)作新的先驗(yàn)概率堪嫂,從而在觀察到更新的證據(jù)之后偎箫,再次更新我們的信念。 ?
-
需要說明的是皆串,這個(gè)公式并不是貝葉斯推斷所獨(dú)有的淹办。學(xué)習(xí)過概率論的朋友一眼就能看出來,這個(gè)就是課本上的“逆概公式”恶复。 ?