統計推論與 A/B 測試¶
前情提要¶
假設你把結帳頁的按鈕從藍色改成橘色。這週看數字,轉換率從 5.0% 變成 5.5%。
老闆問:「所以有效嗎?可以全面上線嗎?」
這個問題比看起來難很多。5.0% → 5.5% 可能是真的變好,也可能只是這週剛好有幾個人多買了——同樣一群人、同樣一個網站,你什麼都不改,兩週的轉換率本來就不會一模一樣。要區分「真的有效」和「剛好而已」,就是統計推論在做的事;而 A/B 測試,是把這件事做得可信的一套流程。
本頁講的就是這一整套:怎麼設計、怎麼算、怎麼判讀,以及那些會讓整個結論悄悄失效的地方。
本頁定位:本區「統計與實驗」軌的唯一一頁。重心放在實務實驗設計——假設檢定只寫到能正確使用的程度,主力在樣本數計算、實驗流程與常見謬誤。 與監督式學習那三軌互補:模型評估(見〈模型評估與 Cross-Validation 實務〉)問的是「模型準不準」,本頁問的是「這個改動有沒有效」。兩者都在做推論,但實驗有隨機分派,因果宣稱的強度完全不同。
摘要¶
一句話:A/B 測試的難處從來不是算 p-value,而是在算之前把實驗設計對、在算之後不要過度解讀。
三個最該記住的:
- 先算樣本數,再決定做不做。 算出來要跑 90 天的實驗,就不該用 A/B 測試回答——這是設計階段就該退回的問題,不是跑到一半才發現。
- 不要偷看。 每天看一次「顯著了沒」,假陽性率會從 5% 膨脹到 20% 上下(本頁附模擬)。
- 統計顯著 ≠ 該上線。 信賴區間下界仍低於「值得做」的門檻時,顯著只代表「有差」,不代表「划算」。
一、假設檢定:夠用就好的最小框架¶
1.1 基本結構¶
| 元件 | 意義 | A/B 測試裡對應什麼 |
|---|---|---|
| H₀(虛無假設) | 「沒有差異」——預設立場 | 新版與舊版轉換率相同 |
| H₁(對立假設) | 「有差異」——你想證明的 | 新版轉換率不同於舊版 |
| α(顯著水準) | 願意承擔的誤判率,慣例 0.05 | 100 次沒效果的實驗,容許 5 次誤判為有效 |
| p-value | 見下方定義 | 由實驗資料算出 |
| 決策 | p < α 就拒絕 H₀ | 「有統計顯著差異」 |
檢定邏輯是反證法:先假設沒差異,再看「如果真的沒差異,我觀察到這麼極端的結果有多不尋常」。夠不尋常,就推翻沒差異的假設。
1.2 p-value 的正確定義(最常被誤解的一個概念)¶
p-value = 假設 H₀ 為真的前提下,觀察到「目前這個結果或更極端結果」的機率。
它是「在沒有差異的世界裡,這筆資料有多罕見」,不是別的。三個常見錯誤說法:
| 錯誤說法 | 錯在哪 |
|---|---|
| ❌「p=0.03 代表 H₀ 為真的機率只有 3%」 | 方向反了。p 是 P(資料 \| H₀),不是 P(H₀ \| 資料)。後者要用貝氏方法才算得出來。 |
| ❌「p=0.03 代表新版有 97% 機率更好」 | 同一個錯誤的變形。p-value 完全沒有告訴你效果的大小或方向的可信度。 |
| ❌「p=0.20 代表兩版沒有差異」 | 不顯著 ≠ 無差異,只是「證據不足以推翻沒差異」。樣本數不夠時,真實存在的差異一樣會不顯著。 |
釐清
p-value 衡量的是資料與虛無假設的相容程度,不是「假設為真的機率」,也不是效果的大小。 這個區別有實際後果:p-value 再小,也沒說效果值不值得做。因此報告結果時應該同時給效果量與信賴區間,而不是只講顯不顯著。
1.3 型一 / 型二錯誤與檢定力¶
| H₀ 實際為真(沒差異) | H₀ 實際為假(有差異) | |
|---|---|---|
| 拒絕 H₀(判定有效) | 型一錯誤(α) 假陽性:把沒用的功能上線 | ✅ 正確 |
| 不拒絕 H₀(判定無效) | ✅ 正確 | 型二錯誤(β) 假陰性:把有用的功能砍掉 |
這四格用圖看更直觀。關鍵在於:同一條判定門檻,會在「其實沒差異」和「其實有差異」這兩個世界裡,各自造成一種錯誤:
- 左邊那條曲線是「沒有差異」的世界。它右尾超過門檻的那一塊,就是 α——明明沒效果,卻剛好抽到夠極端的樣本而被判定有效。
- 右邊那條是「真的有差異」的世界。它落在門檻左邊的那一塊,就是 β——明明有效果,卻沒被偵測到。
- 剩下的那塊(右曲線在門檻右側)就是檢定力 Power = 1 − β:真的有差異時,能抓到的機率。業界慣例 0.8。
從圖上可以直接看出一件重要的事:把門檻往右推(α 調嚴),灰色的 α 區塊會縮小,但橘色的 β 區塊會同時變大。 兩者是蹺蹺板,要同時壓低,只能把兩條曲線變瘦——也就是加樣本。
業務語言:α 是「上線了沒用的東西」的成本,β 是「錯過有用的東西」的成本。哪個貴,就往哪邊調。改版成本極高的功能可以把 α 設嚴一點;探索性的小改動可以容忍高一點的 α。
釐清:慣例背後的隱含假設
α=0.05 搭配 power=0.8(即 β=0.2)是業界慣例,但這組數字並非中性——它隱含「假陰性的容忍度是假陽性的四倍」,背後的假設是「上線沒用的東西」通常比「錯過有用的東西」更貴。 這個假設不是永遠成立。探索階段的小改動、可隨時回退的功能,錯過的成本反而更高,此時把 power 拉高(或容忍較大的 α)才合理。慣例是預設值,不是規範。
1.4 信賴區間比 p-value 更該報¶
95% 信賴區間的意思是:用同樣方法重複做很多次實驗,約 95% 的區間會蓋住真值。(不是「真值有 95% 機率落在這個區間」——真值是固定的,隨機的是區間。)
實務上它比 p-value 有用,因為它同時給出方向、大小、精確度三件事:
二、樣本數與 MDE:實驗設計的核心¶
這一節是整頁最該學會的東西。 大部分失敗的 A/B 測試不是分析錯,是樣本數從一開始就不夠。
2.1 四個變數綁在一起¶
樣本數、顯著水準、檢定力、效果大小——定下三個,第四個就固定了:
| 變數 | 通常怎麼決定 |
|---|---|
| α | 慣例 0.05 |
| Power (1−β) | 慣例 0.8 |
| MDE(最小可偵測效果) | 業務決定:多小的提升才值得做? |
| n(每組樣本數) | 由上面三個算出來 |
MDE 這個縮寫拆開來看就清楚了:
MDE 是業務問題不是統計問題。 問的是「轉換率提升多少,才值得投入這次開發與後續維護」。設得太小 → 樣本數爆炸、實驗跑不完;設得太大 → 真實的中等效果偵測不到。
2.2 計算公式與實例¶
比較兩組比例(轉換率)時,每組所需樣本數:
n = 2 × (z_{1−α/2} + z_{1−β})² × p̄(1−p̄) / δ²
α=0.05, power=0.8 時:(1.96 + 0.842)² ≈ 7.85
p̄ = 兩組預期比例的平均,δ = 絕對差異
from scipy.stats import norm
def sample_size_proportion(baseline, relative_lift, alpha=0.05, power=0.8):
"""回傳每組所需樣本數(雙尾檢定)"""
z_a = norm.ppf(1 - alpha / 2)
z_b = norm.ppf(power)
p2 = baseline * (1 + relative_lift)
delta = p2 - baseline
p_bar = (baseline + p2) / 2
return 2 * (z_a + z_b) ** 2 * p_bar * (1 - p_bar) / delta ** 2
sample_size_proportion(0.05, 0.10) # → 31,235 每組
基準轉換率 5% 時,不同 MDE 的樣本需求:
| 想偵測的相對提升 | 絕對差異 | 每組樣本數 | 兩組合計 |
|---|---|---|---|
| +5% (5.00%→5.25%) | 0.25pp | 122,125 | 244,249 |
| +10% (5.00%→5.50%) | 0.50pp | 31,235 | 62,469 |
| +20% (5.00%→6.00%) | 1.00pp | 8,159 | 16,318 |
把整條曲線畫出來,這個關係會非常有感:
關鍵直覺:樣本數與效果大小的平方成反比。 MDE 砍半 → 樣本數變四倍。這是為什麼「想偵測很小的提升」在實務上幾乎不可行——圖左邊那段陡到幾乎垂直,就是很多實驗跑不完的原因。
基準轉換率也很關鍵(同樣要偵測 +10% 相對提升):
| 基準轉換率 | 每組樣本數 |
|---|---|
| 2% | 80,683 |
| 5% | 31,235 |
| 10% | 14,752 |
→ 低轉換率的指標貴得多。 這也是為什麼實驗常選較上游、較高頻的指標當主要指標。
2.3 從樣本數到「這個實驗做不做得起」¶
最少跑滿一個完整週(通常兩週),理由是消除星期效應——週末與平日的使用者行為結構不同,只跑五天等於在一個有偏的子母體上做實驗。
設計階段就該退回的實驗
算出來要跑 90 天,代表這個問題不適合用 A/B 測試回答。選項是:放大 MDE(只測有感的大改動)、換更上游的指標、改用其他方法(見 §五)。不要硬跑然後在第 30 天因為「看起來顯著了」就停。
釐清:MDE 不是「預期會漲多少」
MDE 常被誤填成「我猜這次改版會帶來多少提升」。它其實是決策門檻——低於這個幅度就不值得做,所以實驗也不需要有能力偵測它。 兩者混淆的後果很具體:把 MDE 填成樂觀的預期值(例如「應該會漲 20%」),算出來的樣本數會遠低於實際所需;真實效果若只有 +8%,實驗就會因檢定力不足而看不出來,得到「沒效果」的錯誤結論。
三、A/B 測試完整流程¶
整個流程與兩個把關點,先用一張圖建立全貌,再逐步看每一步在做什麼:
Step 1:定義假設與指標¶
| 指標類型 | 作用 | 數量 |
|---|---|---|
| 主要指標(OEC) | 決策依據,事前就定死 | 只能一個 |
| 護欄指標(Guardrail) | 確保沒有傷到其他地方(延遲、退訂率、客訴) | 3–5 個 |
| 輔助指標 | 幫助理解機制,不可用來翻轉決策 | 不限 |
主要指標只能一個,否則就落入多重比較(§四之三),而且「哪個指標好看就報哪個」是最常見的自我欺騙。
Step 2:事前登記(pre-registration)¶
開跑前寫下並凍結:假設、主要指標、MDE、樣本數、預計天數、決策規則(什麼結果 → 什麼行動)。
這一步的價值不在流程完備,而在把「事後找理由」這條路先堵死。
Step 3:隨機分派與品質檢查¶
- 分派單位要與分析單位一致(通常是 user 而非 session,否則同一人可能落入兩組)。
- 用穩定的 hash(如
hash(user_id + experiment_id))確保同一人每次都進同一組。 - 開跑後 24 小時先檢查 SRM(§四之二),有問題立刻停、修好重跑。
Step 4:跑滿,不要偷看¶
跑到預定樣本數/天數才分析。需要中途監控時用 §四之一的正規方法。
Step 5:分析與決策¶
from statsmodels.stats.proportion import proportions_ztest, confint_proportions_2indep
count = [1550, 1705] # 各組轉換數([對照, 實驗])
nobs = [31000, 31000] # 各組樣本數
stat, pval = proportions_ztest(count, nobs)
# z = -2.791, p = 0.0053
# ⚠️ 注意符號:函式算的是 prop1 - prop2(對照 - 實驗),
# 所以「實驗組勝出」會得到負的 z。雙尾 p 值不受影響。
lo, hi = confint_proportions_2indep(1705, 31000, 1550, 31000, method='wald')
# 絕對差異的 95% CI = [+0.00149, +0.00851],即 [+0.15pp, +0.85pp]
上面這組數字的完整結論長這樣:
對照組 5.000% → 實驗組 5.500%
相對提升 +10.0%,|z| = 2.791,p = 0.0053
95% CI(絕對差)[+0.15pp, +0.85pp] → 相對 [+3.0%, +17.0%]
決策:顯著。但區間下界僅 +3.0%,若 MDE 定的「值得做」門檻是 +5%,
則證據不足以支撐上線 —— 需延長實驗收窄區間,或接受風險上線。
這就是為什麼要報信賴區間:單看 p=0.0053 會直接得出「上線」,看了區間才發現真實效果可能只有 +3%。
四、七個會讓結論失效的實務謬誤¶
4.1 偷看(Peeking)— 最常見也最致命¶
每次「現在顯著了嗎」都是一次額外檢定,假陽性率會累積膨脹。
A/A 測試模擬(兩組真實無差異,α=0.05,每次檢定門檻不變,3,000 次模擬):
| 中途檢查次數 | 實際假陽性率 |
|---|---|
| 1(只在結束時看) | 4.6% ✅ |
| 2 | 8.6% |
| 5 | 14.5% |
| 10 | 19.6% ⚠️ |
每天看一次、跑兩週,假陽性率約是宣稱值的四倍。意思是:明明沒效果的實驗,有五分之一會被你判定成功。
正確做法:
- 跑滿預定樣本數才分析(最簡單)。
- 真的需要中途停止,用序貫檢定(sequential testing):alpha spending function、O'Brien-Fleming boundary,或 always-valid p-value。這些方法會把中途檢查的次數算進門檻。
- 只在護欄指標嚴重惡化時中途喊停——那是止損,不是取勝。
釐清:問題不在「看」,而在「用同一個門檻看很多次」
常見的誤解是「監控實驗進度有什麼不對」。監控本身沒問題——用單次檢定的門檻反覆判定勝負才是問題。α=0.05 的保證只對「檢定一次」成立,檢定十次就等於給了自己十次撿到假陽性的機會。 所以序貫檢定不是禁止中途看,而是把「會看幾次」事前納入門檻計算。實務上的分界是:中途看護欄指標用來止損,不用來宣告勝利。
4.2 樣本比例不符(SRM)— 最被低估的紅旗¶
分派設定 50/50,實際卻不是 50/50,代表分派或記錄環節有 bug。這時任何結論都不可信,因為兩組的組成已經不可比。
用卡方檢定驗:
| 實際分派 | 比例 | χ² | p | 判定 |
|---|---|---|---|---|
| 10,000 / 10,300 | 49.3% / 50.7% | 4.43 | 0.035 | ⚠️ 可疑 |
| 10,000 / 10,100 | 49.8% / 50.3% | 0.50 | 0.481 | OK |
| 50,000 / 50,600 | 49.7% / 50.3% | 3.58 | 0.059 | 邊緣,要查 |
常見成因:重新導向造成的流失差異、某組載入較慢導致跳出、機器人流量分佈不均、記錄事件在某組漏發。
SRM 的正確反應是停下來找 bug,不是調整分析方法把它「修正」掉。 這是少數「發現了就該中止實驗」的訊號。
4.3 多重比較¶
同時檢定多個指標或多個分群,至少一個假陽性的機率會快速上升:
| 獨立檢定數 | 至少一個假陽性 | Bonferroni 校正後的 α' |
|---|---|---|
| 1 | 5.0% | 0.0500 |
| 3 | 14.3% | 0.0167 |
| 5 | 22.6% | 0.0100 |
| 10 | 40.1% | 0.0050 |
| 20 | 64.2% | 0.0025 |
檢定 20 個指標,有三分之二的機率至少撿到一個「顯著」——即使全部都沒效果。
處理方式:主要指標只設一個(最有效的預防);必須多重檢定時用 Bonferroni(保守)或 Benjamini-Hochberg FDR(較不保守,指標多時實用);分群分析一律視為探索性,結論要用新實驗驗證。
4.4 辛普森悖論¶
整體看 A 贏,但每個分群看都是 B 贏——當各分群的樣本比例不均時會發生。
實務上最常見的觸發情境:實驗中途調整流量分配比例(例如前三天 10/90、之後 50/50)。這會讓兩組在「早期使用者 vs 後期使用者」的組成上失衡,而這兩群的基礎轉換率本來就不同。
預防:分派比例定了就不要中途改;分析時同時看整體與主要分群,兩者矛盾就去找組成差異。
4.5 新奇效應與首因效應¶
- 新奇效應(Novelty):使用者只是因為「不一樣」而多點,效果會隨時間衰減。
- 首因效應(Primacy):老使用者需要時間適應新版,初期表現被低估。
兩者都會讓短期結果誤導長期判斷,方向還相反。
診斷方式:把效果按「使用者進入實驗後的第幾天」拆開看。健康的效果應該大致平穩;單調衰減到接近零就是新奇效應。必要時對新舊使用者分開分析。
4.6 統計顯著 ≠ 業務顯著¶
樣本夠大時,任何微小差異都會顯著。轉換率 5.00% → 5.02% 在百萬級樣本下 p 值可以很漂亮,但這 0.02pp 可能連開發成本都不夠付。
決策應該回到事前定義的 MDE:效果的信賴區間下界有沒有超過「值得做」的門檻。這也是 §三 Step 5 那個例子的重點。
4.7 事後挖分群(HARKing)¶
實驗整體不顯著,於是開始切分群——「在 iOS 使用者身上顯著」「在新用戶身上顯著」——切二十刀總會找到一刀顯著(見 §4.3)。
規則:分群假設必須事前提出並納入樣本數計算;事後發現的分群結論一律標記為「待驗證假設」,要用獨立的新實驗確認才能拿來做決策。
五、什麼時候不該用 A/B 測試¶
| 情境 | 為什麼不行 | 替代方案 |
|---|---|---|
| 流量太小,算出來要跑幾個月 | 樣本數不足 | 放大 MDE、換上游指標、質性研究 |
| 有網路效應(社群、雙邊市場) | 兩組會互相影響,違反 SUTVA 假設 | 叢集隨機(依地區/時段分派)、切換式設計 |
| 改動無法分版(品牌、定價策略) | 技術上或法律上無法同時存在兩版 | 前後測 + 對照地區、合成控制法 |
| 長期效果為主(留存、品牌認知) | 實驗週期無法涵蓋 | 長期追蹤研究、代理指標 + 事後驗證 |
| 罕見但嚴重的事件(重大故障) | 樣本數需求極大 | 監控告警而非實驗 |
「這個問題適不適合用 A/B 測試回答」是設計階段的第一道判斷,比後續任何分析技巧都更早決定實驗的成敗。硬把不適用的問題塞進 A/B 框架,得到的數字再漂亮也不成立。
六、幾個容易搞混的判斷¶
前面各節的重點,換成「實際遇到時怎麼判斷」的形式收尾。
| 情況 | 常見的直覺反應 | 應該怎麼判斷 |
|---|---|---|
| 實驗跑一半就顯著了 | 提早結束,趕快上線 | 不能。這是 peeking,假陽性率已膨脹(§4.1)。除非事前就採用序貫檢定 |
| p = 0.06 | 「差一點,算有效吧」或「沒效」 | 兩者都不對。看信賴區間與效果量,區分是真的沒效還是樣本不足,再決定延長或放棄 |
| 兩組人數不一樣多 | 用加權或比例調整「修正」 | 先做 SRM 卡方檢定(§4.2)。顯著偏離代表分派或記錄有 bug,該停下來查,不是調整算法 |
| 主要指標顯著了 | 直接上線 | 再看兩件事:信賴區間下界是否超過事前定的 MDE 門檻、護欄指標有無惡化 |
| 整體不顯著,但某分群顯著 | 「至少對這群有效」 | 視為待驗證假設,不能直接當結論(§4.7)。要用獨立的新實驗確認 |
| 效果隨時間衰減 | 「實驗失敗了」 | 可能是新奇效應(§4.5)。按進入實驗後的天數拆開看,並分開檢視新舊使用者 |
| 樣本數算出來要跑三個月 | 先跑再說,之後看情況 | 設計階段就該退回:放大 MDE、換上游指標,或改用其他方法(§五) |
延伸閱讀(本站)¶
- 模型評估與 Cross-Validation 實務 — 同樣在做推論,但對象是模型性能而非產品改動
- ML 面試核心觀念 — 分類指標的定義(本頁的轉換率檢定會用到)
- 常見 ML Case Study — 模型上線後常以 A/B 測試驗證業務價值
- 特徵工程心法 — 實驗資料的清理與分群變數處理
來源與參考¶
本頁的樣本數、多重比較與 SRM 數字皆以標準公式計算,peeking 一節為本頁自行模擬(A/A 測試、3,000 次重複、α=0.05),計算方式已附於各節程式碼,可自行複現。
- Kohavi, R., Tang, D., Xu, Y.《Trustworthy Online Controlled Experiments》(Cambridge University Press, 2020) — 業界實驗設計的標準參考,SRM、OEC、護欄指標等概念出處
- Kohavi et al., "Online Controlled Experiments at Large Scale" (KDD 2013)
- statsmodels: Statistics for proportions
- scipy.stats 官方文件
- Evan Miller, "How Not To Run An A/B Test" — peeking 問題的經典說明
- Wasserstein, R. L. & Lazar, N. A., "The ASA Statement on p-Values" (The American Statistician, 2016) — p-value 誤用的官方聲明
本頁為方法整理,公式與慣例(α=0.05、power=0.8)為業界通用設定,實際專案請依決策成本調整。



