診斷準確度的統合分析
一篇診斷研究交出來的不是一個數字而是一對,而且兩者被同一個切點綁在一起。這一頁用 AUDIT-C 酒精篩檢的實測資料把常見的口號拆開:分開合併之後合併點幾乎沒有移動,真正壞掉的是聯合陳述——兩個獨立區間交叉出來的矩形面積更大、覆蓋率反而更低,而且形狀正好包含了資料說不可能的那個角落。另外談信賴橢圓與預測橢圓的差別,以及 SROC 曲線從哪裡開始是外插。
一篇診斷研究交出來的是一對數字
一般的統合分析合併的是一個純量:一個效果量,配上它的變異數(見效果量與變異數)。診斷準確度研究不是這樣。它交出來的是一張 2×2 表,而從那張表讀出來的敏感度與特異度是兩個結果變數,兩者由同一個切點決定(見2×2 表、敏感度與特異度與切點選擇)。
切點往「容易判陽性」的方向移,敏感度上去、特異度下來;往反方向移,兩者互換。所以當十幾篇研究各自用了不同的切點(或名義上同一個切點、實務上判讀寬嚴不同),這兩個數字在研究之間會沿著一條曲線一起移動,而不是各自獨立地散開。
這件事的後果是:把敏感度丟給一個隨機效應模型、把特異度丟給另一個,等於宣告兩者無關。本頁要做的是把這個宣告的代價量出來,而不是重複口號。用的資料是 mada::AuditC——14 篇 AUDIT-C 酒精篩檢問卷的研究,合計 18,332 人(其中 2,071 人有目標狀況)。
這批研究長什麼樣子
| 研究 | n | TP | FN | FP | TN | 敏感度 | 特異度 | DOR |
|---|---|---|---|---|---|---|---|---|
| 1 | 895 | 47 | 9 | 101 | 738 | 0.839 | 0.880 | 36.4 |
| 2 | 1,992 | 126 | 51 | 272 | 1543 | 0.712 | 0.850 | 13.9 |
| 3 | 233 | 19 | 10 | 12 | 192 | 0.655 | 0.941 | 28.6 |
| 4 | 393 | 36 | 3 | 78 | 276 | 0.923 | 0.780 | 36.7 |
| 5 | 1,319 | 130 | 19 | 211 | 959 | 0.872 | 0.820 | 30.4 |
| 6 | 243 | 84 | 2 | 68 | 89 | 0.977 | 0.567 | 44.2 |
| 7 | 603 | 68 | 0 | 112 | 423 | 1.000 | 0.791 | 515.7 |
| 8 | 6,955 | 752 | 0 | 3226 | 2977 | 1.000 | 0.480 | 1388.9 |
| 9 | 255 | 59 | 5 | 55 | 136 | 0.922 | 0.712 | 26.6 |
| 10 | 3,551 | 142 | 50 | 571 | 2788 | 0.740 | 0.830 | 13.8 |
| 11 | 626 | 137 | 24 | 107 | 358 | 0.851 | 0.770 | 18.7 |
| 12 | 600 | 57 | 3 | 103 | 437 | 0.950 | 0.809 | 69.4 |
| 13 | 112 | 34 | 1 | 21 | 56 | 0.971 | 0.727 | 60.4 |
| 14 | 555 | 152 | 51 | 88 | 264 | 0.749 | 0.750 | 8.9 |
敏感度與特異度那兩欄是未經校正的觀察值——研究實際報出來的東西。DOR(diagnostic odds ratio,診斷勝算比)那一欄則是在每一格加了 0.5 之後算的,因為有 2 篇研究的 FN 是零,未校正的 DOR 會是無限大。同一批研究的規模差距很大:最小的一篇 112 人,最大的一篇 6,955 人,後者一篇就佔了全部樣本的 38%。這個事實在最後一節會再出現一次。
機制:切點一動,兩個數字往反方向走
先不要跑任何模型。把每篇研究的 logit(敏感度) 對 logit(特異度) 畫出來就看得到:
figures/scripts/B7-08-diagnostic-meta.RPearson 相關係數是 -0.737(95% CI -0.911 到 -0.339,p = 0.0026,df = 12),Spearman ρ 是 -0.732。迴歸線的斜率 -0.280,R² 是 0.543。
這個負相關不是被一篇高槓桿研究撐起來的,這件事重要到值得單獨查證。逐一把每篇研究剔除再重算,相關係數落在 -0.805 到 -0.569 之間——最不負的那個值出現在剔除第 8 篇的時候,也就是樣本數最大、在 logit(敏感度) 軸上跑得最遠的那一篇。把兩篇有零格的研究(第 7 與第 8 篇)一起拿掉,相關係數是 -0.750。
換句話說,這一頁接下來的論證有一個可以引用的正面證據在支撐,不是一句免責聲明。
切點效應從哪裡來,以及這份資料的一個缺口
散布圖上那條斜線最直接的解釋是各研究用了不同的切點。但實務上會留下同一個形狀的來源不只一種,讀報表時要分得開:
- 明示的切點不同 —— 同一份問卷或同一個生物標記,有的研究用比較低的門檻、有的用比較高的。
- 切點相同、判讀寬嚴不同 —— 影像與病理最常見:名義上是同一套判定標準,不同判讀者的實際門檻不同。
- 參考標準不同 —— 用來定義「真的有目標狀況」的那個標準換掉,兩個指標會一起移動。
- 族群的病情光譜不同 —— 收的是症狀明顯的住院病人,還是社區篩檢的一般人,會同時改變兩個指標。
前兩者是嚴格意義的切點效應,後兩者不是,但它們在資料上留下的痕跡很像。Bivariate 模型並不區分這四種來源,它做的事只是承認「兩個指標相關」並把這件事建進變異數結構;要分辨來源得靠 meta-regression,把切點、參考標準、族群特徵當成共變項放進去(作法與異質性那一頁的 meta-regression 相同,只是被解釋的東西變成兩個)。
分開合併之後:合併點幾乎沒有動
現在跑兩個各自獨立的單變量隨機效應模型(REML、logit 尺度),再跑一個 mada::reitsma() 的 bivariate 模型,兩者用同一套連續性校正,把結果並排:
| 指標 | 分開合併 | bivariate | 差距(百分點) |
|---|---|---|---|
| 敏感度 | 0.893(0.814–0.941) | 0.891(0.808–0.941) | +0.19 |
| 特異度 | 0.781(0.715–0.835) | 0.780(0.715–0.833) | +0.11 |
figures/scripts/B7-08-diagnostic-meta.R點估計幾乎沒動,聯合陳述動了。 分開合併確實同時比 bivariate 高了一點,方向與教科書講的一致,但幅度是 0.19 與 0.11 個百分點——寫在論文摘要裡不會有人看得出差別,四捨五入到小數第二位就消失了。這一頁不會說「分開合併會嚴重高估」,因為在這份資料上它沒有。
而且這不是資料太乖。沒有共變項的時候,bivariate 模型的邊際點估計本來就會跟兩個單變量模型很接近:兩者的固定效應部分估的是同一件事,相關性進入的是變異數結構,不是中心位置。相關性改變的是不確定性的形狀,所以差別要到聯合陳述那一層才看得出來。
順帶一提,兩個指標的研究間異質性都很大:敏感度那一側 τ² = 1.215、I² = 93.5%,特異度那一側 τ² = 0.427、I² = 98.6%。I² 是比例不是量(見異質性:I²、τ² 與預測區間),但這麼高的 τ² 在 logit 尺度上是真的很大的散布,稍後的預測橢圓會把它變成看得見的東西。
聯合陳述才是壞掉的地方
論文報表最常見的長相是這樣兩句話:合併敏感度 0.893(95% CI 0.814–0.941)、合併特異度 0.781(95% CI 0.715–0.835)。讀者接著會做一件很自然的事:把這兩個區間交叉,得到一個矩形,然後說「這個檢驗的真實表現落在這個範圍裡」。
這一步就是錯的地方,而且錯了兩層。
第一層:兩個 95% 區間交叉出來的東西不是 95% 區域。 就算兩者真的獨立,聯合覆蓋率也只有 90.25%(0.95 的平方)。這件事與模型無關,是機率的算術。
第二層才是這一頁的重點:形狀不對。 用 bivariate 模型的抽樣分布做 200,000 次蒙地卡羅,那個矩形的實際聯合覆蓋率是 91.9%。同一批抽樣對 bivariate 的信賴橢圓算出 94.93%,作為程序本身的檢查——這個數字該接近 95%,它確實接近。
矩形的面積是 0.0152,橢圓是 0.0117,前者是後者的 1.30 倍。面積大了三成,覆蓋率卻更低——因為多出來的面積都長錯地方。
上圖 B 面板一眼看得出來:矩形的左上角是「敏感度很高、同時特異度也很高」,右下角是「兩者同時很低」。這兩個角落正是負相關排除掉的組合,橢圓不涵蓋它們,而矩形涵蓋。矩形省下的是橢圓的兩個長軸端點——「敏感度高、特異度低」與「敏感度低、特異度高」,也就是資料實際上支持的那兩種可能。
把矩形的角落拿去算概似比,會發生什麼事
上一節的問題聽起來還有點抽象,直到把那個矩形接進臨床用得到的量為止。概似比(likelihood ratio)就是這樣一個量,而它的定義同時吃掉兩個指標(見概似比):陽性概似比是敏感度除以偽陽性率,陰性概似比是「1 減敏感度」除以特異度。
用 bivariate 的合併點算,陽性概似比是 4.04、陰性概似比是 0.140。現在改用矩形最樂觀的那個角落——敏感度取上界 0.941、特異度也取上界 0.835——算出來的陽性概似比變成 5.69,是合併點的 1.41 倍;陰性概似比變成 0.071,大約是合併點的一半。
這組數字不是「樂觀的估計」,是模型說不會同時發生的組合。 一個把兩個區間交叉來用的讀者,會得到一個看起來很有說服力、卻沒有任何資料支持的檢驗。
實務上的規矩因此很簡單:概似比、預測值、決策曲線這類需要同時用到兩個指標的量,區間不能靠兩個邊界做四則運算,必須在模型的聯合分布上算——從 bivariate 的抽樣分布抽樣,對每一次抽樣算一次概似比,再取分位數;或用 delta method。上一節那段模擬程式碼稍加修改就是這件事。
信賴橢圓與預測橢圓不是同一個東西
上面那個橢圓還有一個更常被誤讀的兄弟。兩個橢圓中心相同,差別在於它們是什麼東西的不確定性:
figures/scripts/B7-08-diagnostic-meta.R- 信賴橢圓的變異數是
vcov(固定效應),講的是平均操作點落在哪裡。研究愈多它愈小。 - 預測橢圓的變異數是
vcov(固定效應) + Psi,講的是下一篇研究的真實操作點落在哪裡。它不會隨著研究變多而縮小,因為 Psi 是真實的研究間散布,不是我們的無知。
⚠️ 預測橢圓指的是下一篇研究的真值,不包含那篇研究自己的抽樣誤差。它是單變量預測區間(見異質性那一頁)的二維版本,不是「下一篇研究會觀察到的那個點」的區間——真的要預測觀察值,還要再疊上那篇研究依樣本數而定的抽樣變異。
兩者的差距在這份資料上非常大。預測橢圓的面積是信賴橢圓的 10.37 倍:
| 區域 | 敏感度範圍 | 特異度範圍 | 面積 |
|---|---|---|---|
| 95% 信賴(平均操作點) | 0.781–0.949 | 0.698–0.844 | 0.0117 |
| 95% 預測(下一篇研究的真值) | 0.291–0.994 | 0.412–0.947 | 0.1210 |
合併點的敏感度區間看起來相當精確,但下一篇研究的真實敏感度可以低到 0.291。這個對比比合併點那 0.19 個百分點有力得多,而且它回答的才是臨床上真正的問題:這個檢驗拿到我的診間,表現會是什麼樣子。一篇只報信賴橢圓的統合分析,等於用「平均值有多確定」去回答「下一次會怎樣」。
SROC 曲線:離開資料就是外插
圖上那條曲線是 summary ROC(SROC)曲線,本例用的是 Rutter-Gatsonis 參數化。它畫的是:如果把切點沿著模型估出來的那條軌跡移動,敏感度與特異度會怎麼交換。曲線下面積 AUC = 0.887,限縮在觀察範圍內的 partial AUC = 0.861。
這個 AUC 不是單一研究 ROC 曲線下的面積(見ROC 曲線與 AUC)。單一研究的 ROC 是在同一群人身上移動切點畫出來的;SROC 是跨研究的,每一點來自不同的族群、不同的判讀者、不同的參考標準。兩者長得很像,意思差很多。
而且曲線只有一段是有資料撐著的。這 14 篇研究的偽陽性率落在 0.059 到 0.520 之間;圖上那個範圍內畫成實線,範圍外畫成點虛線。點虛線那兩段是模型的外插——它們的形狀完全由模型假設決定,沒有任何研究在那個區域提供過資訊。看到一篇論文把 SROC 曲線畫到偽陽性率 0.01 的地方,並且引用該處的敏感度,那個數字是模型算出來的,不是量出來的。
報表上會看到兩個模型名字
診斷準確度統合分析的論文裡,方法段落通常會出現下面兩個名字之一,讀者常以為是兩種相競爭的做法:
- Bivariate random effects(Reitsma 等人) —— 直接對 (logit 敏感度, logit 偽陽性率) 這一對做二維隨機效應,估的是合併操作點與它的聯合不確定性。本頁用的就是這一個。
- HSROC(hierarchical summary ROC,Rutter-Gatsonis) —— 參數化成「區辨能力」與「切點」兩個潛在量,估的是那條曲線。
在沒有共變項的情況下,兩者是同一個模型的兩種寫法,可以互相換算——所以本頁既報得出合併點(來自 bivariate 的參數),也畫得出 SROC 曲線(ruttergatsonis 參數化)。有共變項的時候兩者才會分家:共變項加在「區辨能力」上,跟加在「敏感度與特異度」上,問的不是同一個問題。
所以看到論文寫「bivariate」而報表裡有 SROC 曲線,不是矛盾;看到寫「HSROC」而報表裡有合併點,也不是。要追問的是共變項放在哪一層,以及合併點是模型直接估的還是從曲線上挑的。
為什麼不乾脆合併 DOR
看到「一對數字很麻煩」,很自然會想到把它壓成一個純量:診斷勝算比(DOR)就是這樣的東西,本頁第一張表的最後一欄。壓成純量之後,一般的統合分析工具立刻就能用——早期的 Moses-Littenberg 做法正是拿每篇的 log DOR 去畫 SROC 曲線。
代價有兩個,而且都不小。
第一,DOR 丟掉了臨床上最重要的那個區分。 兩個 DOR 相同的檢驗,可以一個敏感度很高、特異度平平(適合 rule-out),另一個反過來(適合 rule-in)。DOR 相同不代表能互相取代,而醫師要決定的正好是「這個檢驗該放在流程的哪一步」。
第二,DOR 在極端的表格上很不穩。 本頁那 2 篇有零格的研究,校正之後 DOR 被推到整批研究裡最極端的兩個值,log DOR 的標準誤也是全部 14 篇裡最大的兩個(都在 1.42 附近,其餘研究落在 0.17 到 0.87 之間)。整批研究的 DOR 從 8.9 一路到 1388.9,跨了兩個數量級,而最高的那兩個完全是零格造成的。
所以 DOR 現在的位置是描述,不是合併的目標:它適合放在表裡讓讀者看到各研究的整體區辨能力差多少,不適合當成統合分析的主要結果。
該報一個點,還是整條曲線
切點效應愈強,「合併敏感度是 X」這句話本身的意義就愈有限——它把不同門檻的研究平均起來,得到一個可能沒有任何研究真的操作在上面的點。這份資料的研究間散布確實很大:Psi 在 logit 尺度上的兩個標準差是 1.175(敏感度)與 0.638(偽陽性率),這正是預測橢圓大得那麼誇張的原因。
三種常見的處理方式,選哪一種取決於資料而不是偏好:
- 報整條 SROC 曲線,加上合併點與預測區域。 本頁的做法,也是切點確實不同時最誠實的呈現:曲線說「這個檢驗的能力大致是這樣」,預測區域說「下一篇研究可能落在哪」。
- 把用同一個門檻的研究抽出來單獨合併,其餘的放進敏感度分析。這樣合併點才有明確的意思——它是「在這個門檻上」的表現。前提是抄得到每篇的切點。
- 以切點為共變項做 meta-regression。 資訊量最大,需求也最高,同樣卡在上一節那個缺口。
另一個錯,性質完全不同:把所有 2×2 表加起來
上面談的都是模型層次的問題。還有一個更基本的錯誤在實務上照樣常見:直接把 14 張 2×2 表的四個格子分別加總,再用總數算敏感度與特異度。
| 做法 | 敏感度 | 特異度 |
|---|---|---|
| 加總後相除 | 0.890 | 0.691 |
| 分開合併 | 0.893 | 0.781 |
| bivariate | 0.891 | 0.780 |
敏感度那一欄三種做法差不多,特異度那一欄不是:加總後相除給出 0.691,比兩個統合估計低了大約 8.9 個百分點。
原因與切點無關,與分析單位有關。加總的做法把每一個受試者當成分析單位,於是那篇 6,955 人的研究(佔全部樣本 38%)幾乎自己決定了答案——而它的特異度是全部 14 篇裡最低的。統合分析的分析單位是研究,不是人;隨機效應模型會把權重往中間拉,正是為了不讓一篇研究把其餘十幾篇淹掉(見固定效應與隨機效應)。
這個錯誤與前面談的「分開合併」是兩件不同的事,不要混在一起講:一個是忽略了兩個指標之間的連結,另一個是忽略了研究才是分析單位。一篇論文可以只犯其中一個。
連續性校正:先把它固定住,比較才乾淨
上面那張並排表有一個前提:兩種做法用了同一套連續性校正——每一格都加 0.5,這是 mada::reitsma() 內部的預設。這樣剩下的差距才只反映模型。
如果單變量那一側改用 metafor 的預設(只在有零格的研究補 0.5),差距會放大到 0.98 與 0.20 個百分點:
| 單變量模型的校正方式 | 敏感度 | 特異度 |
|---|---|---|
| 每一格都加(與 bivariate 相同) | 0.893 | 0.781 |
| 只補零格(metafor 預設) | 0.901 | 0.782 |
多出來的那一截是校正方式的差異,不是模型的差異。 一篇論文如果拿「只補零格的單變量結果」去對比「bivariate 結果」,然後宣稱差距全是分開合併造成的,那個歸因是錯的。零格處理本身沒有標準答案,各種做法的代價在效果量與變異數那一頁談過;這裡的要求只有一個:做比較時,把不是你要比的東西固定住。
動手跑一次
library(mada)
library(metafor)
library(ellipse)
data(AuditC, package = "mada") # 14 篇,欄位是 TP / FN / FP / TN
cc <- AuditC + 0.5 # 每一格都加 0.5,與 reitsma() 內部一致
# ── 1. 先看機制,不要先跑模型 ──────────────────────────────────
madad(AuditC, correction = 0.5)$cor_sens_fpr # 敏感度 vs 偽陽性率(正值)
cor.test(qlogis(cc$TP / (cc$TP + cc$FN)), # 敏感度 vs 特異度(負值)
qlogis(cc$TN / (cc$TN + cc$FP)))
# ── 2. 分開合併:兩個各自獨立的單變量模型 ─────────────────────
es_sens <- escalc(measure = "PLO", xi = cc$TP, ni = cc$TP + cc$FN)
es_spec <- escalc(measure = "PLO", xi = cc$TN, ni = cc$TN + cc$FP)
m_sens <- rma(yi, vi, data = es_sens, method = "REML")
m_spec <- rma(yi, vi, data = es_spec, method = "REML")
plogis(c(m_sens$beta, m_sens$ci.lb, m_sens$ci.ub)) # 合併敏感度與 95% CI
plogis(c(m_spec$beta, m_spec$ci.lb, m_spec$ci.ub)) # 合併特異度與 95% CI
# ── 3. bivariate:一個模型,帶研究間共變異數 ──────────────────
fit <- reitsma(AuditC, correction = 0.5, correction.control = "all")
summary(fit) # sensitivity 與 false pos. rate 的合併值與 95% CI
fit$Psi # 研究間共變異數;psi12 > 0 就是那個負相關
AUC(fit) # SROC 曲線下面積(不是單一研究的 ROC AUC)
# ── 4. 兩個橢圓:mada 只畫信賴橢圓,預測橢圓要自己疊 Psi ───────
b <- as.numeric(coef(fit)) # (logit 敏感度, logit 偽陽性率)
V <- fit$vcov # 固定效應的抽樣共變異數
e_conf <- ellipse(V[c(2, 1), c(2, 1)], centre = b[c(2, 1)], level = 0.95)
e_pred <- ellipse((V + fit$Psi)[c(2, 1), c(2, 1)], centre = b[c(2, 1)], level = 0.95)
plot(fit, sroclwd = 2, xlim = c(0, 0.62), ylim = c(0.25, 1))
points(fpr(AuditC), sens(AuditC), pch = 21)
lines(plogis(e_conf[, 1]), plogis(e_conf[, 2]), lwd = 2)
lines(plogis(e_pred[, 1]), plogis(e_pred[, 2]), lty = 2) # 大很多的那一個
# ── 5. 那個矩形實際上覆蓋多少?自己模擬一次比讀公式快 ─────────
set.seed(20260823)
z <- matrix(rnorm(2 * 2e5), ncol = 2) %*% chol(V)
sim_sens <- plogis(b[1] + z[, 1])
sim_spec <- 1 - plogis(b[2] + z[, 2])
mean(sim_sens >= plogis(m_sens$ci.lb) & sim_sens <= plogis(m_sens$ci.ub) &
sim_spec >= plogis(m_spec$ci.lb) & sim_spec <= plogis(m_spec$ci.ub))驗證環境:R 4.6.0 + mada 0.5.12 + metafor 5.0.1 + ellipse 0.5.0
import numpy as np
import pandas as pd
from scipy.special import logit
from scipy.stats import pearsonr, spearmanr
# mada::AuditC 的逐篇四格表,14 篇。
tab = pd.DataFrame({
"TP": [47, 126, 19, 36, 130, 84, 68, 752, 59, 142, 137, 57, 34, 152],
"FN": [9, 51, 10, 3, 19, 2, 0, 0, 5, 50, 24, 3, 1, 51],
"FP": [101, 272, 12, 78, 211, 68, 112, 3226, 55, 571, 107, 103, 21, 88],
"TN": [738, 1543, 192, 276, 959, 89, 423, 2977, 136, 2788, 358, 437, 56, 264],
})
# TP / FN / FP / TN 逐篇,就在上面
cc = tab + 0.5 # 與 R 端同一套連續性校正
sens = cc.TP / (cc.TP + cc.FN)
spec = cc.TN / (cc.TN + cc.FP)
print(pearsonr(logit(sens), logit(spec))) # 負相關 = 切點效應
print(spearmanr(logit(sens), logit(spec)))
# 逐一剔除,確認相關不是靠單一高槓桿研究
r_loo = [np.corrcoef(np.delete(logit(sens).values, i),
np.delete(logit(spec).values, i))[0, 1]
for i in range(len(cc))]
print(min(r_loo), max(r_loo))
# 合併那一步到此為止:Python 沒有現成的 bivariate / HSROC 實作。
# 不要退而求其次用兩個單變量模型然後不說 —— 那正是本頁在講的問題。Python 沒有 Reitsma bivariate/HSROC 模型的成熟實作。statsmodels 的 MixedLM 不提供「兩個結果變數共用一組研究層隨機效應」的參數化,硬做等於自己寫 likelihood,所以本頁的模型實務上必須用 R。下面的 Python 只做得到描述層——那一段仍然值得跑,因為機制在跑模型之前就看得到。
怎麼讀報表
- 有沒有說用了哪一種模型。 「bivariate random effects(Reitsma)」或「HSROC(Rutter-Gatsonis)」是可接受的答案;只寫「pooled sensitivity and specificity」而沒有模型名稱,通常就是兩個單變量模型。
- 有沒有給研究間共變異數或它的相關係數。 這是切點效應在報表上的位置。只有兩個 τ² 而沒有共變異數項,代表模型裡兩者是獨立的。
- 兩個區間有沒有被交叉使用。 摘要裡出現「敏感度 X(CI)且特異度 Y(CI)」而正文用它做聯合宣稱,就是本頁第五節那個矩形。
- 報的是信賴區域還是預測區域。 只有信賴區域的統合分析,回答不了「這個檢驗在我的族群會怎樣」。
- SROC 曲線畫到哪裡。 觀察到的偽陽性率範圍如果沒有標出來,曲線兩端的部分要當成外插看。
- 零格與連續性校正怎麼處理。 特別是在拿兩種做法互相比較的時候,校正方式必須一致,否則差距的歸因是錯的。
- 有沒有把加總後相除的結果當成統合結果。 檢查方式很簡單:如果合併值剛好等於「總 TP 除以總(TP + FN)」,那就是。
- 模型有沒有收斂,殘餘自由度是多少。 Bivariate 模型要估五個參數(兩個平均、兩個變異、一個共變異),研究篇數少的時候收斂會不穩或把共變異估到邊界。本例收斂,殘餘自由度 23、對數概似 31.56。論文沒提收斂狀況時,至少確認 Psi 的相關係數不是剛好正負 1——那通常是估到邊界的訊號。
常見誤用
| 誤用 | 為什麼錯 |
|---|---|
| 敏感度與特異度各跑一個隨機效應模型,然後把兩個區間交叉 | 交叉出來的矩形涵蓋了負相關排除掉的角落,實際聯合覆蓋率低於名目值 |
| 把 14 張 2×2 表加總再相除 | 分析單位變成受試者,最大的一篇研究會主導結果 |
| 把預測橢圓說成「下一篇研究會觀察到的點」 | 預測橢圓是下一篇研究的真值,不含那篇研究自己的抽樣誤差 |
| 只報信賴橢圓 | 回答的是「平均值有多確定」,不是「下一次會怎樣」 |
| 引用 SROC 曲線在觀察範圍外的座標 | 那一段完全由模型假設決定,沒有研究提供過資訊 |
| 把 SROC 的 AUC 當成單一研究 ROC 的 AUC | 前者跨研究、跨族群、跨判讀者,不是同一群人移動切點畫出來的 |
| 比較兩種合併方法時各用各的連續性校正 | 差距裡混進了校正方式的效應,歸因會錯 |
| 兩個檢驗的 DOR 相近就說可以互相取代 | DOR 是純量,看不出偏向 rule-in 還是 rule-out |
| 把 bivariate 與 HSROC 當成兩種相競爭的結論 | 沒有共變項時兩者等價,差別在共變項加在哪一層 |
| 用兩個區間的邊界四則運算出概似比的區間 | 邊界的組合在模型下不相容,區間要在聯合分布上算 |
| 因為異質性高就不做統合 | 異質性高在診斷準確度研究是常態,正確的動作是建模與解釋,不是放棄 |
| 用「分開合併會嚴重高估」當作萬用理由 | 在這份資料上高估幅度只有 0.19 個百分點;真正的理由在聯合陳述,不在合併點 |
重跑本頁的所有數字
/opt/homebrew/bin/Rscript figures/scripts/B7-08-diagnostic-meta.R讀讀看這張圖
答案取自產生本頁圖表的同一份統計輸出,不是另外打上去的。
有人說「敏感度與特異度不能分開合併」。在這 14 篇 AUDIT-C 研究上,分開合併給的敏感度是 0.893、特異度是 0.781,bivariate 模型給 0.891 與 0.780。那句話錯了嗎?
看答案與解析
正確答案: 沒錯,但錯的地方不在合併點:兩者只差 0.193 個百分點,真正壞掉的是把兩個區間交叉出來的聯合陳述
在這份資料上分開合併確實同時高估了兩個指標,方向與教科書一致,但幅度只有 0.193 個百分點這種等級,小到沒有任何臨床意義。真正被破壞的是聯合陳述:把兩個獨立的 95% 區間交叉成矩形,即使兩者真的獨立,聯合覆蓋率也只有九成左右,而且形狀還不對。0.691 是把 14 張表直接加起來再除得到的特異度,那是另一個性質完全不同的錯——它把研究這個分析單位丟掉了,最大的一篇就佔了全部樣本的近四成;它錯得更嚴重,但不是這一題在問的東西。1.215 是分開合併時敏感度的 τ²,異質性大是事實,但隨機效應模型本來就是為了處理異質性而存在的,異質性大不構成「不能用」的理由;不能用的理由是兩個指標由同一個切點決定,而分開合併等於宣告它們無關。
把敏感度與特異度的兩個 95% 區間交叉成一個矩形,它的面積是 bivariate 信賴橢圓的 1.30 倍,而蒙地卡羅算出來的實際聯合覆蓋率只有 91.9%。面積更大,為什麼覆蓋更少?
看答案與解析
正確答案: 因為多出來的面積長錯地方:同一批抽樣對橢圓算出 94.927%,矩形多出來的是左上與右下兩個角,正是負相關排除掉的組合
錯有兩層。第一層是算術:就算兩個指標真的獨立,兩個 95% 區間交叉出來的聯合覆蓋率也只有 90.250%,這與模型無關。第二層才是重點——形狀不對。矩形的左上角是「敏感度很高、同時特異度也很高」,右下角是「兩者同時很低」,而這兩個角落正是負相關排除掉的組合;矩形涵蓋它們,卻省下了橢圓的兩個長軸端點,也就是資料實際上支持的那兩種可能。於是面積大了三成,覆蓋率反而更低。94.928% 是同一批抽樣對信賴橢圓算出來的覆蓋率,它接近名目值,正好證明程序本身沒有問題——把矩形的低覆蓋率推給抽樣不夠密,這個數字就是反例。0.015 是矩形的面積,面積本身不是問題,面積長在哪裡才是。
有人拿矩形最樂觀的那個角落——敏感度取上界 0.941、特異度也取上界 0.835——去算陽性概似比。這個做法哪裡有問題?
看答案與解析
正確答案: 問題在那個角落是模型說不會同時發生的組合:logit 尺度上兩者的研究間相關是 0.854,取兩個上界等於挑一個資料排除掉的點
概似比的定義同時吃掉兩個指標,所以它的區間不能靠兩個邊界做四則運算。矩形左上角那個組合——敏感度與特異度同時取上界——正是負相關排除掉的方向:Psi 在 logit 敏感度與 logit 偽陽性率上的相關是 0.854,換算成敏感度與特異度就是明顯的負相關,兩者同時很高是資料說不可能的。0.220 是合併點的偽陽性率,把那個角落說成「把不確定性用滿」正好搞錯了不確定性的形狀,它不是比較樂觀的估計,是沒有任何資料支持的組合。0.844 是信賴橢圓在特異度方向的極值,它比矩形的上界更高,但橢圓的邊界不是一個矩形的角落——在那個特異度上,橢圓對應的敏感度並不是它自己方向上的極值,把兩個方向的極值配成一組仍然是同一個錯。正確做法是在模型的聯合分布上算:從 bivariate 的抽樣分布抽樣,每一次抽樣算一次概似比,再取分位數,或用 delta method。
SROC 圖上有兩個同心橢圓,外圈的面積是內圈的 10.37 倍。這兩個橢圓的差別是什麼?
看答案與解析
正確答案: 外圈是預測橢圓,講的是下一篇研究的真實操作點落在哪:它的敏感度可以低到 0.291,而且不會隨著研究變多而縮小
兩個橢圓中心相同,差別在於它們是什麼東西的不確定性。信賴橢圓的變異數是固定效應的 vcov,講的是平均操作點在哪裡,研究愈多它愈小;預測橢圓的變異數是那個 vcov 加上 Psi,講的是下一篇研究的真實操作點在哪裡,它不會隨著研究變多而縮小,因為 Psi 是真實的研究間散布而不是我們的無知。所以下一篇研究的真實敏感度可以低到 0.291,而合併點的區間看起來相當精確。0.781 是信賴橢圓在敏感度方向的下界;預測橢圓並不是把每一篇自己的抽樣誤差疊上去——它指的是下一篇研究的真值,真的要預測觀察值還得再加那篇研究依樣本數而定的抽樣變異。1.175 是 Psi 在 logit 敏感度上的標準差,它正是預測橢圓大這麼多的來源,但兩個橢圓不是同一個量的兩個信心水準:一個是平均值的不確定性,一個是分布本身的離散。一篇只報信賴橢圓的統合分析,等於用「平均值有多確定」去回答「下一次會怎樣」。
這 14 篇研究的偽陽性率落在 0.059 到 0.520 之間。一篇論文把 SROC 曲線畫到偽陽性率 0.01 的地方,並引用該處的敏感度。那個數字是什麼?
看答案與解析
正確答案: 那是外插:0.017 完全由模型假設決定,那個區域沒有任何一篇研究提供過資訊
SROC 曲線只有一段是有資料撐著的:這批研究的偽陽性率落在 0.059 到 0.520 之間,範圍外那兩段是模型的外插,形狀完全由模型假設決定。偽陽性率 0.01 遠在觀察範圍之外,該處的 0.017 是算出來的,不是量出來的。0.887 是整條曲線下的面積,把它讀成「曲線上每一點都同等可靠」剛好把摘要當成了證據——AUC 是把曲線壓成一個數字,它不會讓沒有資料的那一段長出資料來。0.861 是 partial AUC,它的意義正好相反:它是刻意限縮在觀察範圍內算的,存在的理由就是不要把外插段算進去。順帶一提,這個 AUC 也不是單一研究 ROC 曲線下的面積——單一研究的 ROC 是在同一群人身上移動切點畫出來的,SROC 是跨研究的,每一點來自不同的族群、判讀者與參考標準。
既然一對數字很麻煩,為什麼不把每一篇壓成一個診斷勝算比(DOR)再用一般的統合分析工具合併?
看答案與解析
正確答案: 因為 DOR 丟掉了臨床上最重要的區分:兩個 DOR 相同的檢驗可以一個適合 rule-out、一個適合 rule-in,而合併特異度 0.780 正是決定它放在流程哪一步的依據
壓成純量之後一般的統合分析工具立刻就能用,代價有兩個。第一,DOR 丟掉了臨床上最重要的區分:兩個 DOR 相同的檢驗,可以一個敏感度很高、特異度平平(適合 rule-out),另一個反過來(適合 rule-in),而醫師要決定的正好是這個檢驗該放在流程的哪一步——0.780 這個合併特異度就是那類判斷的依據,DOR 裡看不到它。第二,DOR 在極端的表格上很不穩:這批研究裡偽陰性為零的那兩篇,校正之後 DOR 被推到全部研究裡最極端的位置,log DOR 的標準誤也是最大的兩個。0.887 是 SROC 的 AUC,它與 DOR 都是整體區辨能力的摘要,但摘要相同不代表可以互相取代,那正是第一個代價說的事。0.861 是 partial AUC;早期的 Moses-Littenberg 做法正是拿每篇的 log DOR 去畫 SROC 曲線,所以「壓成純量之後曲線就畫不出來」不成立——曲線畫得出來,消失的是曲線上該站在哪一點的資訊。
用到這個方法的章節
素材來源與授權
本頁為原創內容