2.4 獨立性與貝氏定理#
本節目標#
- 分清楚「獨立」與「互斥」——兩個常被混為一談、實際上幾乎相反的概念
- 認識 Bayes 1763 年遺稿與其引發的千年難題(逆機率問題)
- 推導貝氏定理,掌握先驗、概似、後驗三個角色
- 用百萬人模擬重現「疾病篩檢悖論」,解釋基率謬誤
獨立 vs 互斥:兩個相反的概念#
互斥#
\(A \cap B = \varnothing\) :兩件事不能同時發生。 \(A\) 的發生排除了 \(B\) ——這是一種強烈的依賴。若兩事件都非零機率,互斥時 \(P(A \mid B) = 0 \ne P(A)\) 。
獨立#
\(A\) 的發生不提供任何關於 \(B\) 的資訊:
$$ P(A \mid B) = P(A) \quad \Longleftrightarrow \quad P(A \cap B) = P(A)\, P(B)
$$ (右式是左式代入條件機率定義的結果,也是定義上更常用的形式,因為它不要求 \(P(B) > 0\) 。)
動手:用模擬分清兩者#
import rstatistics as r
g = r.set_seed(3)
N = 1_000_000
d = g.sample_from(list(range(1, 7)), size=N, replace=True)
# 事件 A:偶數 {2,4,6};事件 B:奇數 {1,3,5}(兩事件互斥)
A = [x % 2 == 0 for x in d]
B = [x % 2 == 1 for x in d]
AB = [a and b for a, b in zip(A, B)]
pA, pB, pAB = sum(A)/N, sum(B)/N, sum(AB)/N
print(f"P(A)={pA:.4f} P(B)={pB:.4f} P(A∩B)={pAB:.4f}")
print(f"互斥:P(A∩B) = {pAB:.4f} ≈ 0")
print(f"若獨立應有 P(A)P(B) = {pA*pB:.4f} ≠ 0 → 互斥但絕不獨立!")
# 事件 C:{2,3}。P(C)=1/3, P(A∩C)=P({2})=1/6 = P(A)P(C)
C = [x in (2, 3) for x in d]
AC = sum(1 for a, c in zip(A, C) if a and c)/N
pC = sum(C)/N
print(f"\nA 與 C:P(A)P(C) = {pA*pC:.4f}, P(A∩C) = {AC:.4f} → 相等,獨立")
輸出:
P(A)=0.4997 P(B)=0.5003 P(A∩B)=0.0000
互斥:P(A∩B) = 0.0000 ≈ 0
若獨立應有 P(A)P(B) = 0.2500 ≠ 0 → 互斥但絕不獨立!
A 與 C:P(A)P(C) = 0.1667, P(A∩C) = 0.1663 → 相等,獨立
口訣:互斥 = 互相排斥(依賴得很徹底);獨立 = 互不告知(毫無關係)。 兩個正機率事件不可能既互斥又獨立。
歷史:1763 年 Bayes 的遺稿與「逆機率問題」#
18 世紀的機率論很會「正向」算:知道袋子裡紅白球比例,算抽到紅的機率。但科學真正要問的是逆向:看到數據之後,原因的機率該怎麼更新?
- John Canton 與望遠鏡時代的難題:天文學家觀測到一系列數據,「如果某假說為真,出現這些數據的機會有多大」會算,但「看到這些數據後假說有多可信」不會算。這個逆機率問題(inverse probability problem)困擾了整個世紀。
- Thomas Bayes(約 1701–1761),英國長老教會牧師、業餘數學家,生前默默無聞。他解出逆問題的核心公式,但論文未曾發表。1763 年,友人 Richard Price 在他的遺物中發現手稿,整理為 An Essay towards solving a Problem in the Doctrine of Chances 投稿到倫敦皇家學會哲學學報,並親自附上應用(用牛頓力學未知參數說明上帝存在之論證,今日看來別有時代趣味)。
- 諷刺的是,我們今天寫的「貝氏定理」的乾淨形式,更多歸功於Laplace(1774 年起)的獨立推導與大力推廣;「貝氏」之名是後人追認。而貝氏方法成為主流要等到 20 世紀電腦出現——先驗分布、積分、馬可夫鏈蒙地卡羅(MCMC),樣樣都吃算力。今天從垃圾郵件過濾到 AlphaGo,全是這封遺稿的後代。
貝氏定理:機率的「換向」工具#
從條件機率的定義出發, \(P(AB)\) 有兩種寫法:
$$ P(AB) = P(A \mid B)\, P(B) = P(B \mid A)\, P(A)
$$ 兩邊同除 \(P(B)\) :
$$ P(A \mid B) = \frac{P(B \mid A)\, P(A)}{P(B)}
$$ 再對分母用全機率法則( \(A\) 與 \(A^c\) 是一個分割),得到最常用的形式:
$$ P(A \mid B) = \frac{P(B \mid A)\, P(A)}{P(B \mid A)\, P(A) + P(B \mid A^c)\, P(A^c)}
$$ 三個角色,用診斷問題的語言命名:
| 名稱 | 數學 | 診斷語言 |
|---|---|---|
| 先驗(prior) | \(P(A)\) | 看檢查之前,患病的機率(= 盛行率) |
| 概似(likelihood) | \(P(B \mid A)\) | 若患病,檢查呈陽性的機率(= 靈敏度) |
| 後驗(posterior) | \(P(A \mid B)\) | 檢查陽性後,患病的機率 |
貝氏定理就是學習的數學:後驗 = 先驗被數據(概似)更新後的結果。明天的新資訊來了,今天的後驗就變成明天的先驗,如此迭代。
疾病篩檢悖論#
理論計算#
設定:盛行率 \(P(D) = 1/1000\) ;靈敏度 \(P(+ \mid D) = 0.99\) ;特異度 99%,即健康者誤報率 \(P(+ \mid D^c) = 0.01\) 。代入貝氏定理:
$$ P(D \mid +) = \frac{0.99 \times 0.001}{0.99 \times 0.001 + 0.01 \times 0.999} = \frac{0.00099}{0.01098} \approx 0.0902
$$ 陽性之後,真正患病的機率只有約 9%。 憑直覺答 99% 的人,是把「 \(P(+ \mid D)\) 」(患病時陽性的機率)與「 \(P(D \mid +)\) 」(陽性時患病的機率)搞混了——條件機率的方向不能顛倒,這正是 Bayes 1763 年要解的問題。
直覺解釋:把 100 萬人排出來#
抽象公式記不住?想像替 100 萬人篩檢:
| 人數 | 陽性人數 | |
|---|---|---|
| 患者(0.1%) | 1,000 | 990(靈敏度 99%) |
| 健康(99.9%) | 999,000 | 9,990(誤報 1%) |
| 合計 | 1,000,000 | 10,980 |
陽性共 10,980 人,其中真正的患者只有 990 人:
$$ 990 / 10980 \approx 9\%
$$ 「把母群體換成一個大整數」這個技巧叫自然頻率(natural frequencies),是 Gigerenzer 等人提倡的、對抗基率謬誤最有效的教法——醫生和法官聽得懂頻率,卻常被百分比絆倒。
基率謬誤(base rate fallacy)#
錯誤的根源是忽略先驗(基率):只看「檢查很準(99%)」就貿然回答,忘了患病基率只有千分之一。基率越極端,檢查的「表面準度」與後驗的落差越大。同樣一個 99% 準的檢查:
- 盛行率 1/1000 → 後驗約 9%
- 盛行率 1/100 → 後驗約 50%
- 盛行率 1/10 → 後驗約 91.7%
實務啟示:低盛行率時的單次陽性不足為憑,所以公共衛生上對罕見疾病的陽性要做第二次獨立複檢——用貝氏定理迭代,第一次的後驗 9% 成為先驗,複檢再陽性後驗跳到約 91%。
動手:百萬人模擬驗證#
import rstatistics as r
g = r.set_seed(42)
N = 1_000_000
# 疾病篩檢:盛行率 1/1000,靈敏度 0.99,特異度 0.99
prev, sens, spec = 1/1000, 0.99, 0.99
# 每人先決定是否患病,再決定篩檢結果
u = g.runif(N)
sick = [1 if x < prev else 0 for x in u]
u2 = g.runif(N)
pos = 0
pos_sick = 0
for s, t in zip(sick, u2):
threshold = sens if s == 1 else 1 - spec
if t < threshold:
pos += 1
if s == 1:
pos_sick += 1
print(f"檢測陽性的比例 = {pos/N:.5f}")
print(f"陽性中真正患病的比例 = {pos_sick/pos:.5f}")
print(f"貝氏定理理論值 = {(0.99*0.001)/(0.99*0.001+0.01*0.999):.5f}")
輸出:
檢測陽性的比例 = 0.01122
陽性中真正患病的比例 = 0.08981
貝氏定理理論值 = 0.09016
陽性比例約 1.1%(理論 0.01098),陽性群體中真正的患者只有 8.98%,與貝氏定理的 9.02% 吻合到 \(1/\sqrt{N} \approx 0.001\) 的量級——百萬人實驗重現了悖論。
模擬的做法就是上表的程式版:先給每人擲一次「是否患病」(機率 1/1000),再按身分擲「是否陽性」(患者過門檻 sens、健康者過門檻 1-spec)。最後在陽性子群體裡數患者的比例——又見 2.3 節的條件機率模擬法。模擬與理論的偏差在 \(1/\sqrt{N} \approx 0.001\) 量級內。
與 R 對照#
set.seed(42)
N <- 1000000
sick <- runif(N) < 1/1000
test_pos <- ifelse(sick, runif(N) < 0.99, runif(N) < 0.01)
mean(test_pos) # 陽性比例
mean(sick[test_pos]) # 陽性中真正患病
(0.99 * 0.001) / (0.99 * 0.001 + 0.01 * 0.999) # 貝氏理論值
輸出:
[1] 0.011076
[1] 0.09100758
[1] 0.09016393
mean(sick[test_pos]) 這行就是貝氏定理:在陽性子集合裡求患病的平均——條件機率的向量化寫法。
小結#
- 互斥是「不能同時發生」(強依賴),獨立是「互不提供資訊」( \(P(AB) = P(A)P(B)\) );正機率下兩者不可兼得。
- Bayes(1763 遺稿,Price 整理;Laplace 推廣)解決了逆機率問題: \(P(A \mid B) = \dfrac{P(B \mid A) P(A)}{P(B)}\) 。
- 先驗 × 概似 → 後驗:貝氏定理是資訊更新、也是所有機器學習「從數據學規律」的數學原型。
- 疾病篩檢悖論(靈敏度 99%、盛行率 1/1000 → 陽性後真患病僅約 9%)的教訓:方向不能顛倒、基率不能忽略;自然頻率(100 萬人排表)是最強的解毒劑。
練習#
- 兩事件 \(P(A) = 0.4\) 、 \(P(B) = 0.5\) 。若 \(A\) 、 \(B\) 互斥, \(P(A \cup B)\) 是多少?若獨立呢?並判斷這兩種情形下 \(P(A \mid B)\) 各為何。(提示:互斥給 0,獨立給 0.4。)
- 把篩檢問題的盛行率改成 1/100(高危群體),重算 \(P(D \mid +)\) ;再用程式把盛行率從 0.001 掃到 0.1,畫出(或列表)後驗的變化。(提示:理論約 0.5005;後驗隨基率單調上升。)
- 複檢問題:某人第一次篩檢陽性(後驗 9.02%)。若複檢與初檢條件獨立且同為 99%/99% 的檢查,複檢又陽性,此時患病機率多少?(提示:先驗換成 0.0902, \(\frac{0.99 \times 0.0902}{0.99 \times 0.0902 + 0.01 \times 0.9098} \approx 0.907\) 。)
- 蒙提霍爾問題用貝氏定理證明「換門獲勝機率 2/3」,並模擬 10 萬次驗證兩種策略。(提示:先驗 \(P(\text{車在2}) = 1/3\) ;觀察到「主持人開 3」的概似:車在 2 時為 1,車在 1 時為 1/2。)
- 某測謊器說謊偵測率 95%、誠實誤判率 10%。若一群人中有 5% 說謊,被測出「說謊」的人真說謊的比例是多少?用自然頻率(10 萬人)列表並程式驗證。(提示:約 33%。)