逆機率加權
加權如何用同一個傾向分數造出一個假想的母體、ATE/ATT/ATO 各自回答哪一個臨床問題、極端權重從哪裡來以及截尾與穩定化各自付出什麼代價,還有為什麼加權保留了所有人卻對模型設定更敏感。
這一頁在解決什麼問題
傾向分數配對用同一個分數解決了「一次校正十幾個共變項」的問題,但它付出了一個代價:配不到對的人被丟掉了。 那一頁的例子丟掉了一部分暴露組,也丟掉了沒被配到的那些對照——188 位對照裡只有 91 位(48.4%)進了最終分析。
逆機率加權(inverse probability of treatment weighting, IPTW)用同一個傾向分數做另一件事:不丟人,改成給每個人一個權重。 於是所有的資訊都留在分析裡,而且——這是它比配對更根本的優點——它可以估配對估不到的東西,包括全體母體的平均效果,以及隨時間改變的暴露(marginal structural model 的基礎)。
代價是它對傾向分數模型的設定更敏感。配對只用到分數的排序(誰跟誰最近),加權用到分數的數值(分母是它)。分數估錯 0.02,對配對可能什麼影響都沒有,對加權可能造出一個權重 50 的人。
加權在做什麼:造出一個假想的母體
直覺是這樣的:一位傾向分數只有 0.1 的病人,卻真的接受了暴露——這種人很罕見,在資料裡代表了「很多個跟他一樣、但沒接受暴露的人」。所以我們給他 的權重,讓他一個人代表十個人。
把這件事對每個人做一遍,就得到一個加權後的假想母體:在那個母體裡,接受暴露與否跟共變項無關——也就是說,它長得像一個隨機分派的試驗。
ATE(平均治療效果)的權重是:
是暴露與否, 是那個人的傾向分數。暴露者除以自己被暴露的機率,未暴露者除以自己沒被暴露的機率。式子只有一行,含意值得停一下:每個人都被放大成「跟他共變項相同的那一整群人」,於是同一群人同時出現在加權後的暴露組與對照組裡。 這就是為什麼 ATE 問的是「如果全部的人都治療 vs 全部的人都不治療」。
這一頁的例子與程式碼
沿用上一頁的同一批病人、同一個傾向分數模型(287 位病人、99 位暴露、47 個事件、12 個共變項)。用同一份資料是刻意的:配對與加權的差別因此只能來自方法本身。
這 287 位是原始世代 316 位裡共變項完整的那些,另外 29 位在進場之前就已經被排除(排除步驟見上一頁)。這件事值得在一頁標榜「不丟人」的教材上講明白:IPTW 不丟人,指的是分析集之內的加權階段不丟人。 決定誰進得了分析集的,是共變項的缺失,那一步發生得更早,而且加權完全處理不到它——要處理它得靠缺失值那一頁的方法。
library(medicaldata); library(survival)
data(blood_storage, package = "medicaldata")
d <- blood_storage
d$treat <- as.integer(d$RBC.Age.Group == 3)
covs <- c("Age", "AA", "FamHx", "PVol", "TVol", "T.Stage", "bGS",
"PreopPSA", "PreopTherapy", "Units", "sGS", "AnyAdjTherapy")
cc <- d[complete.cases(d[, c("TimeToRecurrence", "Recurrence", "treat", covs)]), ]
e <- fitted(glm(reformulate(covs, "treat"), data = cc, family = binomial()))
tt <- cc$treat
p <- mean(tt) # 全體接受暴露的比例
# ── 四種權重,全部是一行算術 ────────────────────────────────────────
w_ate <- tt / e + (1 - tt) / (1 - e) # 全體都治療 vs 全體都不治療
w_att <- tt + (1 - tt) * e / (1 - e) # 對「實際接受治療的人」
w_ato <- tt * (1 - e) + (1 - tt) * e # 對「治療與否勢均力敵的人」
w_stab <- tt * p / e + (1 - tt) * (1 - p) / (1 - e) # 穩定化:分子換成邊際機率
# 截尾:把最極端的 1% 與 99% 壓回門檻上
q <- quantile(w_ate, c(0.01, 0.99))
w_trunc <- pmin(pmax(w_ate, q[1]), q[2])
# ── 有效樣本數:權重越不均勻,它離實際人數越遠 ──────────────────────
ess <- function(w) sum(w)^2 / sum(w^2)
c(treated = ess(w_ate[tt == 1]), control = ess(w_ate[tt == 0]))
# ── 加權後的模型一定要用穩健變異數 ──────────────────────────────────
coxph(Surv(TimeToRecurrence, Recurrence) ~ treat,
data = cc, weights = w_ate, robust = TRUE)驗證環境:R 4.6.0 + survival 3.8.6 + medicaldata 0.2.0;權重全部用 base R 從定義算
import numpy as np, statsmodels.api as sm
from lifelines import CoxPHFitter
bs = sm.datasets.get_rdataset("blood_storage", "medicaldata").data
bs["treat"] = (bs["RBC.Age.Group"] == 3).astype(int)
covs = ["Age", "AA", "FamHx", "PVol", "TVol", "T.Stage", "bGS",
"PreopPSA", "PreopTherapy", "Units", "sGS", "AnyAdjTherapy"]
cc = bs[["TimeToRecurrence", "Recurrence", "treat"] + covs].dropna().copy()
e = sm.Logit(cc["treat"], sm.add_constant(cc[covs])).fit(disp=0).predict()
t, p = cc["treat"].to_numpy(), cc["treat"].mean()
w_ate = t / e + (1 - t) / (1 - e)
w_att = t + (1 - t) * e / (1 - e)
w_ato = t * (1 - e) + (1 - t) * e
w_stab = t * p / e + (1 - t) * (1 - p) / (1 - e)
ess = lambda w: w.sum() ** 2 / (w ** 2).sum()
print(ess(w_ate[t == 1]), ess(w_ate[t == 0]))
cc["w"] = w_ate
CoxPHFitter().fit(cc[["TimeToRecurrence", "Recurrence", "treat", "w"]],
duration_col="TimeToRecurrence", event_col="Recurrence",
weights_col="w", robust=True).print_summary()Python 側同樣是四行算術;lifelines 的 CoxPHFitter 接受 weights_col,並且會提醒你加上 robust=True。
三種權重回答三個問題
| 估計量 | 權重 | 問的臨床問題 | 加權後代表誰 |
|---|---|---|---|
| ATE | 如果所有人都接受這個治療,跟都不接受比,平均差多少 | 原本的整個母體 | |
| ATT | 對實際接受治療的那些人,治療比不治療好多少 | 治療組的族群 | |
| ATO | 對治療與否臨床上難以決定的那些人,差多少 | 傾向分數中段的重疊區 |
三者不是「不同精確度的同一個答案」,而是三個不同的問題。在效果會隨病人特徵改變的時候,它們的真值本來就不一樣。哪一個對,取決於你要拿這個數字做什麼決定:
- 衛生政策要問「全面推廣會怎樣」 → ATE
- 臨床上要問「我這些已經在用的病人,用對了嗎」 → ATT(配對預設給的就是這個)
- 指引要處理的是「兩種作法都說得通的灰色地帶」 → ATO
figures/scripts/B6-03-iptw.R| 加權方式 | 估計量 | HR | 95% CI | 最大權重 | 有效樣本數(暴露/對照) | 最大 |SMD| |
|---|---|---|---|---|---|---|
| Unweighted (crude) | -- | 1.02 | 0.57–1.84 | 1.00 | 99 / 188 | 0.156 |
| IPTW, ATE | ATE | 1.07 | 0.59–1.94 | 4.30 | 95 / 185 | 0.017 |
| IPTW, stabilised ATE | ATE | 1.07 | 0.59–1.95 | 1.67 | 95 / 185 | 0.017 |
| IPTW, ATE truncated 1/99% | ATE | 1.07 | 0.59–1.94 | 4.07 | 95 / 185 | 0.020 |
| IPTW, ATT | ATT | 1.20 | 0.66–2.21 | 1.56 | 99 / 166 | 0.043 |
| Overlap weights, ATO | ATO | 1.13 | 0.62–2.06 | 0.77 | 97 / 180 | 0.000 |
極端權重
這份資料的傾向分數落在 0.125 到 0.613 之間,離 0 與 1 都很遠,所以 ATE 權重最大只有 4.30——表現得太好了,好到看不出問題在哪裡。
極端權重的來源不是資料本身,而是傾向分數模型的設定。把同一份資料換成一個飽和的模型(六個共變項的所有兩兩交互作用,總共 28 個參數配 287 個人),傾向分數立刻被推到 0.032 與 0.853,最大權重跳到 12.3。
figures/scripts/B6-03-iptw.R兩種標準處理:
穩定化權重(stabilised weights) 把分子從 1 換成邊際機率(暴露組換成 、對照組換成 )。這不會改變估計的期望值,但把權重的平均值拉回 1 附近、大幅縮小變異——這份資料的最大權重從 4.30 降到 1.67,HR 幾乎不動(1.07 → 1.07)。穩定化沒有實質代價,預設就該用。
截尾(truncation) 把超過某個百分位的權重壓回門檻上。這份資料在第 1 與第 99 百分位截尾,門檻是 1.29 與 4.07,動到 6 個人。它降低變異數,但引入偏誤——被壓下來的那些人本來就是資料裡最稀有的組合,把他們的代表性砍掉,估的就不再是原本那個母體。門檻要事先訂、要報出來、而且應該用不同門檻做敏感度分析。
加權後的平衡
跟配對一樣,加權之後唯一該檢查的是平衡,判準一樣是 |SMD| < 0.1,一樣不要用 p 值。差別在於這裡要算的是加權後的平均與標準化差。
| 共變項 | 未加權 | ATE 權重 | ATT 權重 | ATO 權重 |
|---|---|---|---|---|
| Age (years) | -0.135 | 0.001 | -0.007 | 0.000 |
| African American | 0.045 | -0.010 | -0.005 | 0.000 |
| Family history | 0.156 | 0.010 | 0.000 | 0.000 |
| Prostate volume (g) | -0.132 | -0.010 | -0.004 | 0.000 |
| Tumour volume (grade) | -0.104 | -0.004 | -0.017 | 0.000 |
| T stage | -0.019 | -0.002 | 0.008 | 0.000 |
| Biopsy Gleason score | -0.003 | -0.014 | 0.011 | 0.000 |
| Preoperative PSA | 0.026 | 0.002 | 0.002 | 0.000 |
| Preoperative therapy | 0.011 | -0.009 | 0.043 | 0.000 |
| Units transfused | -0.010 | 0.017 | -0.014 | 0.000 |
| Surgical Gleason score | -0.017 | 0.001 | -0.036 | 0.000 |
| Any adjuvant therapy | 0.147 | -0.001 | -0.018 | 0.000 |
未加權時有 5 個共變項超過 0.1;三種權重都把它壓到 0 個,其中 ATO 那一欄整欄是零。
figures/scripts/B6-03-iptw.R同一份資訊畫成圖之後,兩件事變得比表格明顯:ATO 那一排點全部貼在零上(那是代數保證的,不是巧合), 以及未加權時偏得最遠的幾個變項,加權後被拉回來的幅度並不一樣。
注意這裡只檢查了進到傾向分數模型裡的那 12 個變項。 沒進模型的變項不會被平衡到,而平衡表看起來再漂亮也不會告訴你這件事——這是DAG 那一頁的重點在這裡的具體版本。
三個假設,三個名字
加權能給出因果效果,靠的是三個假設。它們在論文的 Methods 裡幾乎一定以英文原名出現, 而這一頁到目前為止其實已經把三個都講過了,只是還沒給名字。
可交換性(exchangeability)——在校正過的共變項下,誰接受治療與反事實結果無關, 也就是沒有未測量的干擾。隨機化直接買到它;觀察性研究只能假設「條件可交換性」, 而且這條假設無法用資料檢驗。想量化違反它的代價有多大,看 E-value 那一頁。
正性(positivity)——每一種共變項組合下,接受各種治療的機率都要大於零。 這一頁前面談的極端權重,就是它的臨床外衣:一個權重之所以爆大,是因為那種人幾乎不會接受那種治療, 於是模型只能拿極少數的人去代表一整群人。有兩種違反要分清楚:隨機性的(樣本不夠大,多收人會改善) 與結構性的(那種人依定義就不可能接受那種治療,收再多人也沒用)。ATO 之所以特別, 正是因為它換一個方式繞開這個問題——不是修權重,而是把要回答的族群重新定義在重疊得最好的那一段。
一致性(consistency)——觀察到接受某治療的人,他的結果就等於「該治療下」的反事實結果。 聽起來像廢話,但它要求治療被定義得夠明確。「運動」「減重」「早期介入」這種暴露有太多版本, 不同版本的效果不同時,估出來的東西沒有單一意義——這也是目標試驗模擬 堅持把介入寫成一份可執行的方案的理由。
三者的分工可以這樣記:可交換性管原則上有沒有可比的對照,正性管你的資料裡實際上有沒有, 一致性管你估的到底是什麼東西的效果。
有效樣本數
加權之後「有多少人」不再等於列數。有效樣本數(effective sample size, ESS)的定義是:
權重完全均勻時它等於實際人數,權重越不均勻它掉得越快。這份資料的主效果模型 ATE 權重下,暴露組的 ESS 是 95.0(實際 99 人)、對照組 185.1(實際 188 人)——損失很小。飽和模型下暴露組的 ESS 掉到 80.2。
ESS 應該跟 HR 一起報。 它是讀者判斷「這個信賴區間的寬度合不合理」唯一可用的線索:一個看起來 n 很大但 ESS 只有幾十的分析,跟一個真正的小樣本研究一樣不穩。
加權後的變異數
加權讓每一列不再是一個獨立的觀察值——權重本身是估出來的,而且同一個人被放大成好幾個人。直接跑一般的模型會低估變異數。標準作法是穩健(sandwich)變異數:R 的 coxph(..., weights = w, robust = TRUE),或用 bootstrap 把傾向分數模型也一起重估(只 bootstrap 結果模型會漏掉分數估計本身的不確定性)。
本頁表格裡所有的信賴區間都是穩健變異數算的。
加權還是配對
| 配對 | 加權 | |
|---|---|---|
| 誰留在分析裡 | 只有配得到的人 | 全部的人 |
| 預設估計量 | ATT | 由權重選(ATE/ATT/ATO) |
| 對 PS 模型設定的敏感度 | 較低(只用排序) | 較高(分數在分母) |
| 重疊不佳時 | 直接把人丟掉,你看得見 | 產生極端權重,你不看就看不見 |
| 診斷 | 平衡表、love plot、丟掉幾人 | 平衡表、權重分布、ESS |
| 能不能處理隨時間改變的暴露 | 很難 | 可以(marginal structural model) |
| 給臨床同事解釋 | 容易(「配對到條件相似的病人」) | 較難 |
結果怎麼寫
六種加權方式的信賴區間全部跨過 1。正確的寫法是:在這個世代中,未偵測到紅血球儲存時間與生化復發的關聯,並附上區間說明不確定的範圍。
不能因為 ATT 的點估計(1.20)看起來比 ATE(1.07)「明顯」就挑它來報。兩者的信賴區間高度重疊、都跨過 1,而且它們回答的是不同的問題——在這份資料上,估計量之間的差異落在雜訊的量級裡,不該被解讀成臨床訊號。
常見誤用
| 誤用 | 為什麼錯 |
|---|---|
| 只報 HR 不報估計量是 ATE、ATT 還是 ATO | 三者回答不同的臨床問題,數值本來就可以不同 |
| 不報權重分布與最大權重 | 極端權重是這個方法唯一的重大失效模式,讀者看不到就無從判斷 |
| 不報有效樣本數 | 名目 n 與 ESS 可以差好幾倍,信賴區間的寬度沒有別的線索可解釋 |
| 用未穩定化的權重卻不說明 | 穩定化幾乎沒有代價,不用要有理由 |
| 截尾門檻看結果再定 | 那是一個會改變估計族群的選擇,必須事先訂並報出來 |
| 加權後用一般變異數 | 權重讓觀察值不再獨立,會低估變異數 |
| 只 bootstrap 結果模型 | 傾向分數模型本身的不確定性沒被算進去 |
| 用 AUC 挑傾向分數模型 | 判準是加權後的平衡,不是預測能力 |
| 平衡表漂亮就宣稱無干擾 | 只有進到模型裡的變項會被平衡 |
| 把飽和的傾向分數模型當成「校正得比較徹底」 | 小樣本下它製造極端權重,估計會被少數幾個人主導 |
| 未達顯著寫成兩組相同 | 只能說本研究未偵測到差異 |
重跑本頁的所有數字
/opt/homebrew/bin/Rscript figures/scripts/B6-03-iptw.R讀讀看這張圖
答案取自產生本頁圖表的同一份統計輸出,不是另外打上去的。
重疊權重那一列的最大絕對標準化平均差,在表上顯示成零。這一格該怎麼讀?
看答案與解析
正確答案: 它就是 0.000,而且不是四捨五入才變成零——傾向分數用邏輯迴歸估的時候,這是一條恆等式
重疊權重的定義讓進到傾向分數模型的每一個共變項,加權平均在兩組間完全相等;程式吐出來的殘差是浮點運算的捨入,量級遠小於任何統計上的不平衡,所以 0.000 這一格不是四捨五入的結果,也不是這份資料運氣好。0.017 是 ATE 權重那一欄的最大值、0.043 是 ATT 那一欄的,兩個都在門檻以下,但都不是零,而它們與 0.000 的差別是種類上的、不是程度上的。代價寫在別的地方:ATO 的目標族群由資料決定,是傾向分數中段那群人,沒辦法事先指定,所以論文裡必須把「這個數字代表誰」講清楚。
把傾向分數模型換成飽和的版本(28 個參數配 287 個人),最大權重從 4.30 跳到 12.3。哪一句正確說明點估計發生了什麼?
看答案與解析
正確答案: 飽和模型的風險比是 1.01,跟主效果模型的 ATE 幾乎一樣,被吃掉的是精確度不是點估計
飽和模型的風險比是 1.01,主效果模型的 ATE 是 1.07,兩個點估計幾乎沒有差別;差的是精確度——暴露組的有效樣本數明顯掉下來,信賴區間跟著變寬。1.96 是飽和模型信賴區間的上界,不是點估計,把區間端點讀成估計值會得到「風險加倍」這種結論。而「權重不進到點估計」也不對:加權估計裡每一個人的貢獻都被權重乘過,權重集中有能力扭掉點估計,這份資料上剛好沒有扭掉,取決於那幾個高權重的人的結果長什麼樣,而你不去算就永遠不知道。所以極端權重該被當成診斷,不是結論。
有效樣本數在權重完全均勻時等於實際人數,權重越不均勻掉得越快。為什麼它該跟風險比一起報?
看答案與解析
正確答案: 因為名目人數看不出稀釋——這份資料暴露組的有效樣本數是 95.0,稀釋很小,但區間寬不寬要靠它才判斷得出來
主效果模型下暴露組的有效樣本數是 95.0,實際 99 人,稀釋很小。飽和模型下同一組掉到 80.2——名目人數一個都沒少,資訊卻憑空少掉將近二十個人份,信賴區間也跟著變寬。所以它不是「報不報都一樣」的東西,它是名目人數沒有辦法透露的資訊,而 95.0 這個數字之所以有價值,正是因為它可以不等於 99。至於拿它挑傾向分數模型,判準一直是加權後的平衡,不是有效樣本數也不是預測能力——照有效樣本數挑,會挑到那個把不平衡壓得最少的模型。
穩定化權重把最大權重從 4.30 降到 1.67,風險比幾乎不動;截尾則把超過第一與第 99 百分位的權重壓回門檻,動到六個人。兩者的差別是什麼?
看答案與解析
正確答案: 未穩定化的 ATE 是 1.070,穩定化不改變估計的期望值,截尾會改變估計所代表的族群
穩定化只是把分子從一換成邊際機率,權重的變異縮小而估計的期望值不變——未穩定化的 ATE 是 1.070、穩定化後是 1.073,差別在雜訊的量級,但那不是「換個尺度表示」:權重的分布真的變了,變異真的變小了,只是期望值沒動。截尾不同:被壓下來的那六個人本來就是資料裡最稀有的組合,把他們的代表性砍掉之後,1.066 對應的族群已經不完全是原本那一個。所以穩定化幾乎沒有代價、不用要有理由;截尾的門檻要事先訂、要報出來,並且用不同門檻做敏感度分析。看到結果再回頭定門檻,是讀者從論文上完全看不出來的選擇性呈現。
同一份資料、同一個傾向分數模型,ATT 的點估計比 ATE 大。要決定論文的主分析報哪一個,判準是什麼?
看答案與解析
正確答案: 判準是研究問題——ATT 的區間一路跨到 2.21,與 ATE 的區間高度重疊,數字好不好看分不出這兩個量
ATT 問的是「已經在用這個治療的那些人,用對了嗎」,ATE 問的是「全面推廣會怎樣」。在效果隨病人特徵改變的時候,兩者的真值本來就不一樣,不是同一個答案的兩種精確度,所以「哪一個估得比較準」問錯了問題——ATT 的區間一路跨到 2.21、ATE 的點估計是 1.07,兩個區間高度重疊、都跨過一,在這份資料上估計量之間的差異落在雜訊的量級裡。「永遠報保守的那一個」同樣是把選擇建立在數字上:哪個方向算保守由臨床問題決定,而且下一份資料上 ATE 也可能反過來比 ATT 大。正確的作法是事先說明主分析估的是哪一個。
加權後的平衡表上,所有共變項的絕對標準化平均差都被壓到門檻以下。這張表支持的宣稱到哪裡為止?
看答案與解析
正確答案: 到「進了傾向分數模型的那 12 個變項兩組相當」為止,沒進模型的變項連一列都不會出現在表上
平衡只保證進了傾向分數模型的那 12 個變項在加權後兩組相當。沒進模型的變項不會被平衡到,而且它們連一列都不會出現在平衡表上——這是 DAG 那一頁「統計校正只能處理你有測量到的變項」在這裡的具體版本,正式的名字叫可交換性,而它無法用資料檢驗。加權後超過門檻的變項歸零,說的只是這 12 個變項有沒有被平衡,不是干擾有沒有被清空;47 個事件是精確度的問題,事件再多也只會把區間縮窄,不會讓一張只涵蓋 12 個變項的表變成因果的證據。
用到這個方法的章節
延伸觀看
6.4 – Propensity Scores and Inverse Probability Weighting (IPW)
Estimating Causal Effects: Inverse Probability Weighting
Outcome research: Causal inference & Propensity score II 傾向分數素材來源與授權
本頁為原創內容