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

選擇偏誤

選擇偏誤不是「樣本不夠有代表性」這麼含糊的一句話,而是一條可以寫下來的規則:誰進到分析裡。本頁用同一個世代跑四種不同的失訪規則(外加一列全員基準),證明其中兩種完全不傷估計值、一種只傷相對風險不傷勝算比、一種把兩者都毀掉——以及為什麼校正共變項救不回來。

它跟干擾不是同一件事,所以校正救不回來

干擾(confounding)是被比較的兩群人本來就不一樣,而那個「不一樣」同時影響暴露與結果。 它發生在你收到的資料裡面,所以只要那個變項有被量到,把它放進模型就能處理。

選擇偏誤是誰進到這份資料這件事本身就取決於暴露或結果。它發生在資料產生之前, 你手上的每一列都已經是被篩過的。把年齡、性別、共病全部放進模型,改變不了「沒被選進來的人不在這裡」。

醫院裡的兩個病,明明無關卻看起來互斥

先看一個乾淨到不可能被誤讀的例子。母體有兩個病, 盛行率分別是 8% 與 12%, 在程式碼裡是各自獨立抽的,所以真實的勝算比就是 1。 兩者都不會影響對方,也沒有任何共同原因。

唯一發生的事情是:得到其中任何一個病,住院的機率都會上升。 兩個病都沒有的人,住院機率是 2.0%; 只有 A 病是 36.3%,只有 B 病是 31.4%, 兩個都有是 55.4%。最後那一格是整件事的引擎: 同時有兩個病的人最容易被收進來,於是住院族群裡「兩個都有」被相對放大, 而「一個都沒有」幾乎被清空——剩下的多半是只有其中一個。

分析的對象人數A 與 B 的勝算比
整個母體400,0000.990
只看住院的人32,3170.097

在住院的人裡面,兩個病看起來強烈互斥。這就是 Berkson 偏誤(Berkson’s bias,又稱入院率偏誤)。 機制不神秘:住院的人多半至少有一個病,所以在這群人裡「沒有 A 病」幾乎就意味著「有 B 病」。 關聯是被選擇這個動作創造出來的,不是母體裡本來就有的。

左圖:橫軸是沒有任何一個病的人的住院率(對數尺度),縱軸是住院者中兩個病的勝算比(對數尺度)。住院率越低,勝算比被壓得越低,最低到約 0.02;住院率升到 1(等於全母體)時回到 0.99,貼上真值為 1 的水平虛線。右圖:五種選擇規則下的相對風險(圓點)與勝算比(三角),各有一條真值虛線。前三種的兩個估計值都貼在各自的線上;第四種「只取決於結果」的勝算比 1.61 仍在線上,但相對風險掉到 1.34,明顯在線的下方;第五種「同時取決於暴露與結果」的相對風險 4.52 與勝算比 7.32 都遠高於各自的線。
左:醫院越挑,被創造出來的關聯越強;右:不是每一種選擇都造成偏誤,而且同一種選擇對兩個效果量的傷害不一樣。產圖腳本 figures/scripts/B8-03-selection-bias.R

左圖那條曲線值得多看一眼:它是連續的。醫院不是「有偏誤 / 沒偏誤」的開關, 而是越專門、收治門檻越高,被創造出來的關聯就越強。 最左端那個 0.5% 的住院率,把真值為 1 的勝算比壓到 0.025;最右端所有人都「住院」時,估計值回到 0.990——那一格就是整個母體。

四種「誰沒進到分析」的規則,代價完全不同

Berkson 是極端案例。更常見的問題是世代研究的失訪:有些人沒有追蹤到底。 下面用同一個世代(400,000 人,暴露盛行率 40%)跑五次。真實相對風險是 1.5 (未暴露風險 10%),真實勝算比是 1.588。

第一列是全員分析的基準,第二列是與暴露、結果都無關的隨機流失(留存率一律 35%)。第三到第五列才是要互相比較的三列:它們的留存機率一律在 90% 與 20% 之間二選一,唯一的差別是依什麼決定

誰留下來分析人數未暴露風險暴露風險相對風險勝算比
全員分析(基準)400,0009.9%15.1%1.5231.616
與暴露、結果都無關的流失139,0369.9%15.1%1.5261.620
只取決於暴露的流失192,1039.9%15.0%1.5161.608
只取決於結果的流失114,31032.9%44.1%1.3411.610
同時取決於暴露與結果的流失97,0379.8%44.3%4.5187.318

比較的基準是第一列,不是理論真值:這是一次抽樣,第一列的 1.523 與 1.616 就是這份資料在完全沒有流失下能得到的答案, 它與理論值的差距是模擬誤差的尺度。逐列讀,這張表說了四件不一樣的事:

  • 與暴露、結果都無關的流失(第二列)——即使丟掉超過六成的人,兩個估計值都還在真值上。 損失的是精確度(信賴區間變寬),不是正確性。
  • 只取決於暴露的流失(第三列)——一樣沒有偏誤。這一列常被誤讀: 「暴露組的追蹤率比較高」聽起來很嚴重,但只要在每一個暴露層裡,留下來的人與離開的人的風險一樣, 層內的風險就沒有被動到,而相對風險是層內風險的比值。
  • 只取決於結果的流失(第四列)——相對風險掉到 1.341, 但勝算比是 1.610,幾乎沒有動。下一節專講這件事。
  • 同時取決於暴露與結果的流失(第五列)——相對風險 4.52、 勝算比 7.32,相對真值分別高估 3.0 倍與 4.6 倍。

為什麼病例對照研究報勝算比,不報相對風險

上一節第四列不是巧合,是一個代數事實:依結果抽樣,會把每一個暴露層的勝算乘上同一個常數, 所以兩層的比值不變。風險就沒有這個性質——風險有上限 1,乘上一個常數會被壓縮。

病例對照研究做的正是「依結果抽樣」:先找到病例,再找對照。所以它天生就是第四列那個情境, 而它報勝算比不報相對風險,不是慣例或偏好,是只有勝算比在那個抽樣設計下還估得到

知道選擇機率就能加權回去——而知道它才是難的地方

最後一列那個被毀掉的估計(下表第一列,與上表第五列是同一次抽樣、同一批人), 是可以救的:如果你知道每個人被留下來的機率, 就用它的倒數當權重(inverse probability of selection weighting),把留下來的人放大回他們代表的那群人。

相對風險勝算比
直接分析留下來的人4.5187.318
以選擇機率的倒數加權1.5321.626
真值1.5001.588

加權之後兩個估計值都回到真值附近。但這個示範有一個作弊的地方,而且那正是重點: 在模擬裡,選擇機率是程式碼寫死的,我知道它精確到小數點以下每一位。

真實研究裡沒有人知道那個機率。你只能用「還在的人」與「離開的人」身上有記錄到的變項去建一個模型預測它, 而如果離開的原因裡有任何一部分是沒被記錄到的(病情惡化、搬家、死亡未被通報), 那個模型就系統性地錯,加權只是把錯誤搬個位置。

臨床研究裡最常見的幾種,以及它們是哪一列

名稱誰被篩掉對應上表哪一列
Berkson/入院率偏誤只看住院者,而兩個病都提高住院機率比第五列更極端:選擇同時取決於「暴露」與「結果」
健康工作者效應在職者比一般人健康,而能不能在職與暴露有關第五列
盛行使用者偏誤只納入「目前正在用藥」的人,早期停藥與早期死亡的人被排除第五列
志願者/應答偏誤願意參加或回覆問卷的人,其暴露與結果都與不回覆者不同第五列
差別失訪暴露組裡出事的人特別容易失聯第五列
依結果抽樣(病例對照)刻意依結果抽第四列——這是設計,不是偏誤,只要報勝算比
依暴露抽樣(暴露世代)刻意依暴露抽第三列——同樣是設計

讀論文時看哪裡

  1. 流程圖的每一個框都要有數字與理由。 CONSORT 或 STROBE 的流程圖如果只寫「排除 n 人」, 沒寫排除的原因與各原因的人數,讀者無法判斷這是第三列還是第五列。
  2. 失訪要分組報。 總失訪率藏得住差別失訪;暴露組與對照組各自的失訪率藏不住。
  3. 失訪者的基線特徵。 好的論文會附一張「留下來的人 vs 離開的人」的比較表。 沒有這張表,就只能相信作者說的。
  4. 納入條件裡有沒有「目前正在用」「能夠回診」「同意參加」這類詞。 這些詞每一個都定義了一條選擇規則。
  5. 對照組是從哪裡來的。 醫院對照、鄰居對照、母體登錄對照,三者的偏誤結構完全不同。

動手跑一次

set.seed(20260823)
n <- 200000

# A cohort with a known truth: risk 0.10 unexposed, risk ratio 1.5
E <- rbinom(n, 1, 0.4)
Y <- rbinom(n, 1, ifelse(E == 1, 0.15, 0.10))

rr <- function(e, y) mean(y[e == 1]) / mean(y[e == 0])
rr(E, Y)                                  # the truth, computed on everybody

# Selection that depends on the exposure ONLY — still unbiased
keep <- rbinom(n, 1, ifelse(E == 1, 0.9, 0.2))
rr(E[keep == 1], Y[keep == 1])

# Selection that depends on BOTH — this is the one that breaks
keep2 <- rbinom(n, 1, ifelse(E == 1 & Y == 1, 0.9, 0.2))
rr(E[keep2 == 1], Y[keep2 == 1])

# Weight back by the inverse of the (here: known) selection probability
p  <- ifelse(E == 1 & Y == 1, 0.9, 0.2)[keep2 == 1]
Es <- E[keep2 == 1]; Ys <- Y[keep2 == 1]; w <- 1 / p
wrisk <- function(g) sum(w[Es == g] * Ys[Es == g]) / sum(w[Es == g])
wrisk(1) / wrisk(0)

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

常見誤用

誤用為什麼錯
用多變項模型「校正選擇偏誤」校正處理的是資料裡的干擾;沒進到資料的人不在模型裡
看到失訪率高就判定有偏誤與暴露、結果都無關的流失只損失精確度
看到失訪率低就判定沒問題少量但高度差別的失訪一樣可以翻轉結論
只報總失訪率差別失訪只在分組的數字裡看得見
病例對照研究報相對風險依結果抽樣後風險已經不是母體的風險,只有勝算比還估得到
用醫院對照卻不討論對照疾病與暴露的關係這正是 Berkson 的入口
只納入「目前正在用藥」的人並稱之為世代研究盛行使用者偏誤;早期停藥與早期事件被系統性排除
報了 IPW 校正卻不說權重模型的內容校正的可信度完全來自那個模型的假設,不寫等於沒報

重跑本頁的所有數字

/opt/homebrew/bin/Rscript figures/scripts/B8-03-selection-bias.R

讀讀看這張圖

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

母體裡 A 病與 B 病是各自獨立抽的,所以真實的勝算比就是 1,而整個母體算出來是 0.990。只看住院的人,勝算比變成多少,那代表什麼?

看答案與解析

正確答案: 0.097。在住院這群人裡兩個病看起來強烈互斥,而那個關聯是「只看住院者」這個動作創造出來的

0.097 是住院族群的勝算比,而母體的 0.990 已經告訴我們真實關聯是沒有的。差距不是抽樣誤差,是選擇本身:住院的人多半至少有一個病,所以在這群人裡「沒有 A 病」幾乎就等於「有 B 病」。0.784 與 0.025 都不是這批住院資料那一格,兩個都來自左圖那條把收治門檻換成別的值再算一次的曲線;拿其中一格回答「這家醫院會給什麼」,等於換了一家醫院再回答,而 0.784 附帶的「偏誤量級不大」正是這樣得來的。至於生物學上的拮抗,模擬裡兩個病是各自獨立抽的,沒有任何機制可以產生它。把被選擇創造出來的關聯講成疾病之間的關係,是這一頁最想擋掉的誤讀。

同一個世代跑五種流失規則。第三列「只取決於暴露的流失」把暴露組留下 90%、未暴露組只留下 20%,聽起來很嚴重。它的相對風險是多少?

看答案與解析

正確答案: 1.516,與全員分析的基準幾乎一樣。只要在每一個暴露層裡,留下來的人與離開的人風險相同,層內風險就沒被動到

1.516 幾乎就是全員分析的基準,這一列沒有偏誤。相對風險是暴露層內的風險除以未暴露層內的風險,而依暴露決定誰留下來,動到的是每一層有多少人,不是層內的風險——兩層各自被隨機抽稀,比值不變。這也是為什麼依暴露抽樣的世代研究是設計而不是偏誤。4.518 是第五列,那裡的流失同時取決於暴露與結果,兩層的風險本身都被扭曲了,才會炸到那個量級。1.341 是第四列,流失只取決於結果,它壓低的是相對風險而不是勝算比。三列的失訪率都很高,代價卻完全不同——該問的不是掉了幾成,而是掉的規則是什麼。

第四列「只取決於結果的流失」把相對風險壓到 1.341。同一列的勝算比是多少,這件事為什麼重要?

看答案與解析

正確答案: 1.610,幾乎沒有動。依結果抽樣會把每一個暴露層的勝算乘上同一個常數,兩層的比值因此不變——這正是病例對照研究報勝算比的理由

1.610 與全員分析那一列幾乎相同,所以只取決於結果的流失沒有動到勝算比。代數上的原因是它把每一個暴露層的勝算乘上同一個常數,比值於是不變;風險沒有這個性質,因為風險有上限,乘上常數會被壓縮——這就是同一列的相對風險掉到 1.341 的來源。7.318 是第五列,那裡的流失同時取決於暴露與結果,連勝算比都保不住。1.588 是理論真值,而這張表要比的基準是第一列的全員分析,不是理論值:同一次抽樣裡,第一列才是「完全沒有流失時這份資料會給的答案」。病例對照研究做的正是依結果抽樣,所以它報勝算比不報相對風險不是慣例,是只有勝算比在那個設計下還估得到。

第二列與第五列丟掉的比例是同一個量級。哪一個說法對?

看答案與解析

正確答案: 第二列丟掉超過六成,相對風險仍是 1.526,與全員分析一致——失訪率高低本身不是判準,掉的規則才是

1.526 是第二列:丟掉超過六成之後,相對風險仍與全員分析一致,因為與暴露、結果都無關的流失損失的是精確度,不是正確性。4.518 是第五列,它的失訪率與第二列同一個量級,估計值卻被毀掉——所以失訪率高不能當判準,掉的規則是什麼才能。1.523 是第一列的全員分析,把它安到第五列頭上會得出完全相反的結論。實務上該追的問題是:暴露組裡發生結果的人是不是特別容易被追蹤到。論文只報一個總失訪率的話這個問題無法回答,所以分組失訪率與失訪者的基線特徵才是該找的東西。

第五列那個被毀掉的估計,用選擇機率的倒數加權之後,相對風險回到多少?這代表加權法可以在真實研究裡照做嗎?

看答案與解析

正確答案: 回到 1.532,貼著真值。但模擬裡的選擇機率是程式碼寫死的,真實研究只能用有記錄到的變項去估它,估錯了加權只是把錯誤搬個位置

1.532 貼著真值,加權確實把第五列救回來了:它把留下來的人依被留下的機率放大回他們代表的那一群。但這個示範作弊,而那正是重點——選擇機率是模擬寫死的,精確到小數點以下每一位。真實研究裡沒有人知道它,只能用還在的人與離開的人身上有記錄到的變項建模型去估;離開的原因裡只要有一部分沒被記錄到(病情惡化、搬家、死亡未通報),那個模型就系統性地錯。4.518 是未加權的那一列,加權若不動點估計就不叫校正了。1.500 是理論真值,而加權後的估計只是落在它附近,不是等於它;把「回到真值附近」讀成「完全消掉偏誤」,正是加權法最常被過度解讀的地方。加權真正的產出是一組可以被檢驗的假設:權重模型放了什麼、為什麼那些變項夠。

左圖那條曲線的橫軸是「兩個病都沒有的人的住院率」。這個住院率從 0.5% 一路放寬到全體時,勝算比怎麼走?

看答案與解析

正確答案: 從 0.025 一路往上爬回真值附近。醫院不是有偏誤或沒偏誤的開關,收治門檻越高,被創造出來的關聯越強

曲線是連續的:最左端門檻最嚴的那一格把真值為 1 的勝算比壓到 0.025,最右端所有人都算住院時回到 0.990,而那一格就是整個母體。所以偏誤的大小是「醫院有多挑」的函數,不是一個是非題。0.990 是最右端那一格,把它當成整條曲線的樣子等於宣稱選擇不造成偏誤,而左端的 0.025 就在旁邊否定它。0.591 是曲線中段的一格,方向也反了——門檻放寬時被納入的「兩個病都沒有」的人變多,關聯是往真值回,不是被壓得更低。讀醫院為基礎的病例對照研究時,該問的是對照組從哪裡來、他們住院的原因與暴露有沒有關係。

延伸觀看

Principles of Epidemiology 09. Case-Control Study 2: M-H Methods & Selection Bias
繁中臺大開放式課程 NTU OCW· 68 min台大公開課,中文授課、英文投影片。後半段的選擇偏誤是繁中裡講得最完整的一份,看完再回來看本頁的模擬。
Confounding, chance, and bias
ENCochrane Austria· 10 min十分鐘把干擾、機遇、偏誤三者分開。本頁第一節要說的「選擇偏誤不是干擾」在這支裡有更慢的版本。

素材來源與授權

本頁為原創內容

回報內容問題

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

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

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

一併送出的資訊

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