進階已經雙重審閱,尚未人工抽查

多重比較與次族群分析

多重比較不是「p 值要打折」這種技術細節,而是一個關於承諾的問題:0.05 保證的是單一次檢定的錯誤率,看二十個就不再保證任何事。本頁用模擬把型一錯誤的膨脹、三種調整法的實際表現,以及一張切得夠細的次族群森林圖為什麼幾乎一定會給你一個「陽性」的分組,全部量出來。

0.05 承諾的是一次,不是二十次

α = 0.05 的意思是:在沒有效果的情況下,這一次檢定有 5% 的機率會宣稱有效果。 它對「這一次」以外的任何事都沒有承諾。

如果二十個結果彼此獨立、而且全部都真的沒有效果,至少出現一個「顯著」的機率是

1(10.05)k1-(1-0.05)^{k}
檢定個數 k至少一個假陽性的機率
15.0%
29.8%
522.6%
1040.1%
2064.2%
5092.3%
10099.4%

這不是模擬,是算術。但下面那個是模擬:5,000 次虛構試驗, 每次每組 60 人、20 個結果指標, 而且每一個指標的兩組在程式碼裡都是從同一個分布抽出來的——真實效果全部是零, 所以每一個「顯著」都是假陽性,不需要推論。

  • 平均每次試驗跑出 0.995 個「顯著」結果(理論值正好是 20 × 0.05 = 1)
  • 64.3% 的試驗至少有一個
  • 最多的那一次跑出 5 個

三種調整方法,各自保證的東西不一樣

左圖:橫軸是獨立檢定的個數(1 到 100),縱軸是至少出現一個假陽性的機率,曲線從 0.05 快速爬升,20 個時已到 0.64,100 個時是 0.99;水平虛線標在 0.05。右圖:四根長條比較四種做法的族系錯誤率,未調整那根是 0.64,Bonferroni、Holm、Benjamini-Hochberg 三根都貼在 0.05 的虛線上。
左:不調整時,型一錯誤隨檢定個數膨脹的速度。右:三種調整法在「全部都是虛無」這個情境下都把族系錯誤率壓回 0.05——它們的差別要在有真實效果時才看得出來。產圖腳本 figures/scripts/B8-05-multiplicity.R
做法族系錯誤率
不調整64.26%
Bonferroni5.06%
Holm5.06%
Benjamini–Hochberg(FDR)5.12%
方法它保證什麼什麼時候用
Bonferroni族系錯誤率(family-wise error rate)不超過 α:整組檢定裡出現任何一個假陽性的機率確認性分析、結果指標少、每一個結論都要能單獨站住
Holm同上,但逐步進行,永遠不會比 Bonferroni 拒絕得少幾乎任何原本要用 Bonferroni 的場合
Benjamini–Hochberg偽發現率(false discovery rate)不超過 α:被宣稱為陽性的那些之中,錯的比例。⚠️ 這個保證需要檢定之間獨立或正相關;任意相依要改用 Benjamini–Yekutieli探索性、篩選式的大量檢定(基因、代謝物、PheWAS)

上表三種調整的族系錯誤率都落在 5.06% 附近, 看起來一模一樣——那是因為這個模擬裡真實效果全部是零。 在「全部虛無」的情況下偽發現率控制與族系錯誤率控制會重合; 一旦有些效果是真的,Benjamini–Hochberg 會拒絕得比 Bonferroni 多,代價是容許被宣稱的陽性裡有一定比例是錯的。

體學論文(基因體、蛋白質體、代謝體、PheWAS)裡那張火山圖(volcano plot)就是上面這一節換一個畫法:橫軸放效果量、縱軸放 log10(p)-\log_{10}(p),於是 p 值愈小的點愈高、效果量愈極端的點愈往兩側,兩條決策線就是兩條水平線。下面這張用的不是新資料,是本頁同一個模擬裡的第 2 次試驗(挑選規則事先定好:第一個假陽性個數剛好等於期望值 20 × 0.05 = 1 的那一次,不是挑最好看的一次),20 個結果指標的真實效果全部是零。未調整的 0.05 那條線之上有 1 個點,Benjamini–Hochberg 的線之上有 0 個。站在紅線之上那一點不是訊號,是這頁從頭到尾在講的那種假陽性——它的原始 p 是 0.029,BH 調整後變成 0.57。換句話說,火山圖上「有沒有點浮在線上面」是一個結論,不是資料的性質:同一批點換一條線就換一個結論,而換線不需要重跑任何分析。看這種圖的第一件事因此是問那條線是哪一種門檻。

那條綠線落在哪裡還需要多說一句,因為它不是一個固定高度。 Benjamini–Hochberg 是逐級上行(step-up)的程序:把 20 個 p 值由小排到大,第 i 小的那個要跟自己那一階比,階高是 α × i / 20。能通過自己那一階的最大 p 值就是那條線,它以下的全部宣告為陽性——所以線的高度跟著資料走,真的有訊號時它可以遠高於 Bonferroni 的門檻。Bonferroni 則相反,它讓每一個 p 值都只跟最低那一階比。而這次試驗裡沒有任何 p 值通過任何一階,這樣的 p 值並不存在,能誠實畫出來的只有最低那一階本身,α / 20 = 0.0025——數值上就等於 Bonferroni 的門檻。這不與上表矛盾:沒有人爬上梯子的時候,兩個程序在梯腳相遇。

火山圖。橫軸是效果量(兩組平均差,SD 單位),縱軸是 -log10(p),20 個模擬的虛無結果指標排成典型的 V 形:效果量接近 0 的點都貼在底部,愈往左右兩側的點愈高。一條紅色水平虛線畫在未調整的 p = 0.05,一條綠色水平虛線畫在 Benjamini-Hochberg 的門檻 p = 0.0025——這次試驗裡沒有任何 p 值通過自己那一階,所以這條線落在 BH 階梯的最低一階,數值上也就等於 Bonferroni 的門檻。只有 1 個點(右側最遠的那個,效果量約 0.39)落在紅線之上,綠線之上一個點都沒有。
同一份模擬換成體學論文的畫法。這裡沒有任何真實效果,所以紅線之上的點全部是假陽性。BH 的線因為沒有任何 p 值通過自己那一階而掉到階梯的最低一階,數值上等同 Bonferroni 的門檻,不是有真訊號時 BH 會給的那條較寬鬆的線;它把那個點擋了下來。產圖腳本 figures/scripts/B8-05-multiplicity.R

次族群分析:問題不在有沒有調整,在問錯了問題

臨床試驗最常見的多重比較不是二十個結果指標,是一張次族群森林圖。 下面的模擬只有一個結果、一個真實效果,而且每一個次族群的真實效果完全相同—— 沒有任何交互作用存在。試驗總人數固定,切成 g 個等分。

次族群個數至少一組顯著、同時至少一組不顯著交互作用檢定的假陽性率
211.3%5.2%
476.2%5.7%
696.7%5.7%
898.7%6.4%
1097.5%7.0%

中間那一欄是「這個藥對某一群人有效、對另一群無效」這種句子的來源,而它的可信度取決於切了幾組。 切成 6 組時,有 96.7% 的試驗 會出現至少一組顯著、至少一組不顯著的分裂結果——而真相是每一組的效果一模一樣。 單純的男女二分是另一回事:只切 2 組時分裂率是 11.3%, 下面的 Callout 會回到這個對比。

右欄是對照組:正確的問法不是「哪一組顯著」,而是「各組的效果是不是真的不同」, 也就是交互作用檢定。它的假陽性率一路維持在 5.2% 到 7.0% 之間——貼著名目的 5%, 上緣略高(組數多時每組只剩幾十人,大樣本近似開始失準,見本節末)。

兩個誠實的但書,因為它們也在同一張表上:

  • 中間那一欄在 8 組時是 98.7%, 到 10 組反而略降到 97.5%。 它不是單調的:切得夠細之後每一組都太小,於是「全部都不顯著」開始變常見, 而全部不顯著就不算分裂。分裂率下降不代表問題變小,代表資訊已經稀釋到什麼都看不出來。
  • 右欄在 10 組時是 7.0%, 比名目的 5% 高一些。這是大樣本近似在每組只剩幾十人時的誤差, 不是交互作用檢定本身失效——但它提醒了一件事:組數多到一定程度,連正確的檢定也開始不可靠。

什麼時候該調整,什麼時候不該

情境該不該調整為什麼
一個主要結果、事先指定不用只有一個檢定,0.05 的承諾還在
多個共同主要結果,任一達標就宣稱成功這正是族系錯誤率的定義情境
多個共同主要結果,全部達標才宣稱成功不用全部都要過,型一錯誤率反而更低
次要結果,明講是支持性或探索性不一定若不用來下結論,調整不是重點;如實標示才是
期中分析多次查看同一個結果,用 alpha 消耗函數
事後的次族群調整也救不回來問題是分析未事先指定,不是門檻太鬆
敏感度分析(同一問題換方法)不用目的是看結論穩不穩,不是找顯著
高通量篩選要,用偽發現率族系錯誤率會把真訊號一起壓掉

讀論文時看哪裡

  1. 計畫書或註冊資料裡的主要結果是哪一個。 摘要裡的那一句如果不是它,先問為什麼。
  2. 總共量了幾個結果。 方法段落列了十五個、結果段落報了三個,另外十二個在哪裡。
  3. 次族群是事先指定還是事後的。 CONSORT 要求講清楚;沒講清楚就當作事後的。
  4. 有沒有報交互作用的 p 值。 只報各組的效果與各組的 p 值,等於在請讀者做那個會出錯的比較。
  5. 調整方法有沒有寫,以及控制的是哪一種錯誤率。 「已用 Bonferroni 校正」與「FDR < 0.05」是兩個不同的宣稱。
  6. 期中分析的 alpha 花掉多少。 最終的顯著門檻通常小於 0.05。

動手跑一次

set.seed(20260822)

# One trial: 20 endpoints, no effect anywhere
one_trial <- function(k = 20, n = 60) {
  replicate(k, t.test(rnorm(n), rnorm(n), var.equal = TRUE)$p.value)
}

p <- one_trial()
sum(p < 0.05)                          # how many "significant" findings from nothing

p.adjust(p, "bonferroni") < 0.05       # all FALSE, almost always
p.adjust(p, "holm")       < 0.05
p.adjust(p, "BH")         < 0.05

# The family-wise error rate, measured rather than asserted
mean(replicate(1000, any(one_trial() < 0.05)))                       # about 0.64
mean(replicate(1000, any(p.adjust(one_trial(), "holm") < 0.05)))     # about 0.05

驗證環境:R 4.6.0。本頁所有數字都是模擬產生的,seed 固定為 20260822。

常見誤用

誤用為什麼錯
量了十幾個結果,只報顯著的那幾個這是選擇性報告;調整 p 值救不了沒被報出來的部分
「這個藥對男性有效、對女性無效」該做的是交互作用檢定;組數一多,分裂的次族群結果幾乎一定會出現
用次族群的 p 值大小當作交互作用的證據兩組的 p 值一大一小,與兩組效果不同不是同一件事
事後次族群用更嚴格的門檻就當作已處理問題是分析未事先指定,不是門檻太鬆
把 FDR 控制講成「校正過的 p 值」它控制的是被宣稱陽性中的錯誤比例,不是族系錯誤率
對敏感度分析做多重比較調整敏感度分析問的是穩定性,不是額外的顯著性檢定
期中看了三次,最後仍用 0.05 判定多次查看會膨脹型一錯誤,最終門檻必須更小
探索性分析用族系錯誤率控制會把真訊號一起壓掉,該用偽發現率
因為「本研究為探索性」就完全不提多重性探索性不是豁免,是要求把所有做過的比較都列出來

重跑本頁的所有數字

/opt/homebrew/bin/Rscript figures/scripts/B8-05-multiplicity.R

讀讀看這張圖

答案取自產生本頁圖表的同一份統計輸出,不是另外打上去的。

二十個彼此獨立的結果指標,全部真的沒有效果,每一個都用 0.05 檢定一次。至少出現一個「顯著」的機率是多少?

看答案與解析

正確答案: 0.642。0.05 承諾的是單一次檢定,看二十個之後它不再承諾任何事

0.642 是「二十次檢定沒有任何一次出錯」的補數:每一次不出錯的機率是九成五,連續二十次都不出錯就掉到不到四成。0.050 是只做一次檢定那一列,把它套到二十個檢定上正是「α 是整組的錯誤率」這個誤解,而 α 從來沒有做過那個承諾。0.226 是只做五次那一列,用它得出「上升很慢」會低估一張切了二十格的表有多容易長出一個陽性。這張表也解釋了為什麼確認性試驗要事先指定單一主要結果指標:不是因為其他結果不重要,是因為 0.05 這個門檻只有在「一次」的前提下才有意義。

模擬裡三種調整法的族系錯誤率都落在名目值附近,而不調整是 0.643。這是不是說明三種方法效果一樣?

看答案與解析

正確答案: 不是。Benjamini–Hochberg 這裡是 0.0512,只因為這個模擬的真實效果全部是零;一旦有些效果是真的,它會拒絕得比 Bonferroni 多,代價是被宣稱的陽性裡有一定比例是錯的

0.0512 與 0.0506 在這個模擬裡確實幾乎一樣,但那是因為真實效果全部是零——在全部虛無的情況下,偽發現率控制與族系錯誤率控制會重合。它們保證的東西不同:Bonferroni 與 Holm 保證整組檢定裡出現任何一個假陽性的機率不超過門檻,Benjamini–Hochberg 保證的是被宣稱為陽性的那些之中錯的比例。所以拿 0.0506 比 0.0512 說「Bonferroni 比較安全」有兩個毛病:五千次模擬在這個位數上的差距是雜訊,而且兩個數字量的根本不是同一件事,比大小沒有意義。0.0500 是名目值,三者都貼著它同樣不代表它們可以互換。選哪一個要先問「錯一個的代價是什麼」:要決定一個藥能不能上市,出現任何一個假陽性都不行;要從三萬個基因裡挑一百個做後續實驗,那一百個裡有幾個是錯的完全可以接受。

火山圖上有一個點浮在未調整的 0.05 那條線之上,它的原始 p 是 0.029,而這二十個結果指標的真實效果全部是零。哪一個說法對?

看答案與解析

正確答案: 那個點是假陽性。它調整後的值是 0.5711,綠線之上一個點都沒有——火山圖上「有沒有點浮在線上」是一個結論,不是資料的性質

0.5711 是同一個點調整之後的值,遠離任何門檻,而綠線之上一個點都沒有。這二十個結果指標的真實效果全部是零,所以浮在紅線之上的那一點必然是假陽性,而它的期望個數本來就是二十乘以 0.05。0.3870 是那個點的效果量,它確實是這批點裡最極端的一個,但在全部虛無的模擬裡「最極端」只是隨機波動的極值,效果量大小不能替顯著性背書。0.0025 是這次試驗裡階梯的最低一階:沒有任何值通過自己那一階,所以線掉到梯腳,數值上等於 Bonferroni 的門檻——把「離門檻不遠」當成邊緣證據,等於用一個看得到的數字覆蓋掉一個算得出來的結論。看火山圖的第一件事是問那條線是哪一種門檻,因為同一批點換一條線就換一個結論,而換線不需要重跑任何分析。

一個試驗只有一個結果、一個真實效果,而且每一個次族群的真實效果完全相同。切成 6 組時,出現「至少一組顯著、至少一組不顯著」的機率是多少?

看答案與解析

正確答案: 0.9665。分裂結果幾乎一定會出現,因為每一組的人數只剩全體的幾分之一,檢定力跟著掉,效果相同的兩組只要一組運氣好、一組運氣差,就會落在門檻的兩邊

0.9665 是一個幾乎必然的事件,而真相是每一組的效果一模一樣。這一欄正是「這個藥對某一群人有效、對另一群無效」這種句子的來源,它的可信度取決於切了幾組。0.0570 是同一列右欄的交互作用檢定假陽性率——那才是貼著名目門檻的那一欄,也才是正確的問法:不是「哪一組顯著」,而是「各組的效果是不是真的不同」。0.1135 是只切兩組時的分裂率,它跟 0.9665 不是同一個量級,所以「切幾組不太影響」在這張表上直接被否定;一個只分男女的次族群分析,跟一張切得更細的森林圖,不是同一個等級的問題。次族群分析該有的樣子是事先指定、數量少、報交互作用的 p 值,並且把整張森林圖當成假說產生而不是假說驗證。

次族群分裂率在 8 組時是 0.987,到 10 組反而略降。降下來代表問題變小了嗎?

看答案與解析

正確答案: 不是。10 組時是 0.9755,下降的原因是每一組都太小、「全部都不顯著」開始變常見,而全部不顯著不算分裂

0.9755 比 0.987 低一點,但那不是好消息:切得夠細之後每一組只剩幾十個人,於是「全部都不顯著」開始變常見,而全部不顯著就不算分裂。分裂率下降代表資訊已經稀釋到什麼都看不出來,不代表推論變可靠。0.0695 是同一列右欄的交互作用檢定假陽性率,它略高於名目門檻,來源是大樣本近似在每組人數很少時的誤差——組數多到一定程度,連正確的檢定也開始不可靠。0.7620 是切成四組那一列,不是 10 組那一列;而且它附帶的說法把兩欄接錯了——交互作用檢定在右邊那一欄,它自己在組數變多時是往上走的(0.0695 就是最下面那一格),沒有任何機制讓它反過來把左邊那一欄壓下去。這一欄不是單調的,讀它的時候要把「為什麼降」問清楚。

五千次模擬試驗,每一次都檢定二十個真實效果為零的結果指標。平均每一次試驗會長出幾個假陽性?

看答案與解析

正確答案: 0.995 個。二十乘以 0.05 就是這個數——每一次試驗平均長出一個「顯著」的結果,而它們全部是假的

0.995 是平均個數,而 0.05 乘上二十正好是它。0.643 是另一個量:出現至少一個假陽性的試驗比例。兩者不相等,因為同一次試驗可以長出不只一個——這批模擬裡最多的一次長出了五個,於是平均個數比「至少一個」的比例更高。0.226 是檢定個數只有五時「至少一個」的機率,用它得出「不太會出問題」會低估二十格的表。實務上的翻譯是:一張報了二十個次要結果指標的表,期望值就是有一個會落在門檻之下,所以看到一個顯著的次要結果時,第一個問題是這張表總共有幾格。

素材來源與授權

回報內容問題

這個站的統計內容由 AI 撰寫、AI 互審,人工只做抽查。你看得出來的錯,我們不一定看得出來。

寫得越具體越修得動,例如哪一句話跟哪本教科書/哪篇論文的說法不一致。

留了才回得了信;不留也會看。

一併送出的資訊

這些是自動帶上的,每一項都可以取消。