卡方檢定與 Fisher's exact test
卡方在比觀察與期望的什麼、期望次數 5 這條線哪裡來、Fisher's exact test 到底解決了什麼、Yates 校正為什麼有爭議,以及配對資料為什麼一定要換成 McNemar。
這個方法在解決什麼問題
兩個變項都是類別(吸菸 / 不吸菸、低體重 / 正常體重),資料整理成一張列聯表(contingency table)。問題是:表格裡的分布,跟「兩個變項毫無關聯」的情況比起來,差得夠多嗎?
卡方檢定(chi-square test)把這個問題變成一道算術。先算出「如果兩變項獨立,每一格應該有幾個人」——用邊際比例乘回去:
再把每一格的偏離加總:
分母那個 是關鍵:同樣差 5 個人,在期望值 100 的格子裡不算什麼,在期望值 6 的格子裡是大事。這個統計量在虛無假設下近似服從自由度 的卡方分布——注意「近似」兩個字,本頁後面的爭論全部由它而來。
本頁的例子是 MASS::birthwt:189 位產婦,看產婦吸菸與新生兒低出生體重(< 2500 g)這兩個二元變項有沒有關聯。
動手跑一次
library(MASS)
data(birthwt, package = "MASS")
birthwt$smoke_f <- factor(birthwt$smoke, levels = c(0, 1),
labels = c("Non-smoker", "Smoker"))
birthwt$low_f <- factor(birthwt$low, levels = c(0, 1),
labels = c(">= 2500 g", "< 2500 g"))
tb <- table(birthwt$smoke_f, birthwt$low_f)
tb
cs <- chisq.test(tb) # 2x2 預設帶 Yates 校正
cs
cs$expected # ← 先看這個再決定用哪個檢定
chisq.test(tb, correct = FALSE)
fisher.test(tb) # 精確檢定,同時給 OR 與其信賴區間
# 效果量:卡方本身沒有效果量。
# phi 要用「未校正」的統計量算,所以這裡不能沿用 cs。
sqrt(chisq.test(tb, correct = FALSE)$statistic / sum(tb)) # phi(2x2 的 Cramér's V)
# 配對的類別資料要換方法(同一批人測兩次)
approval <- matrix(c(794, 86, 150, 570), nrow = 2)
mcnemar.test(approval)驗證環境:R 4.6.0 + MASS 7.3.65。chisq.test() 對 2×2 表預設 correct = TRUE(Yates 校正),這件事本頁「Yates 校正的爭議」那一節專門討論。
import statsmodels.api as sm
import numpy as np
from scipy import stats
from statsmodels.stats.contingency_tables import mcnemar, Table2x2
bw = sm.datasets.get_rdataset("birthwt", "MASS").data
tb = np.array([[sum((bw.smoke == 0) & (bw.low == 0)), sum((bw.smoke == 0) & (bw.low == 1))],
[sum((bw.smoke == 1) & (bw.low == 0)), sum((bw.smoke == 1) & (bw.low == 1))]])
chi2, p, dof, expected = stats.chi2_contingency(tb) # correction=True by default
print(expected) # ← 先看期望次數
stats.fisher_exact(tb)
t2 = Table2x2(tb)
print(t2.oddsratio, t2.oddsratio_confint())
mcnemar(np.array([[794, 150], [86, 570]]), exact=False, correction=True)scipy 的 chi2_contingency 同樣預設 correction=True,只對 2×2 生效。
這張表怎麼讀
| 正常體重 ≥ 2500 g(觀察 / 期望) | 低出生體重 < 2500 g(觀察 / 期望) | 合計 | |
|---|---|---|---|
| 未吸菸 | 86 / 79.1 | 29 / 35.9 | 115 |
| 吸菸 | 44 / 50.9 | 30 / 23.1 | 74 |
figures/scripts/B1-03-chi-square.R吸菸組 30/74 = 40.5% 生出低體重兒,未吸菸組 29/115 = 25.2%。
| 統計量 | 結果 |
|---|---|
| Pearson 卡方(未校正) | = 4.92,df = 1,p = 0.026 |
| Yates 校正後 | = 4.24,df = 1,p = 0.040 |
| Fisher’s exact test | p = 0.036 |
| 最小期望次數 | 23.1 |
| 勝算比 OR | 2.02(95% CI 1.08–3.78) |
| 相對風險 RR | 1.61(95% CI 1.06–2.44) |
| 絕對風險差 | 15.3 個百分點 |
| (2×2 的 Cramér’s V) | 0.161 |
三種常見的效果量各有適用場合:
- 相對風險 RR:世代研究與 RCT 用,直接是兩個風險的比值,最好解讀。
- 勝算比 OR:病例對照研究只能算 OR(設計本身固定了病例與對照的人數,風險算不出來),邏輯迴歸的係數也是 OR。罕見結果時 OR 近似 RR,本頁這種 25% 的常見結果則會明顯高估(2.02 vs 1.61)。
- Cramér’s V: 的表格用,範圍 0–1,不帶方向,適合描述關聯強度但臨床上不好解讀。
期望次數 5 這條線
規則通常被記成「任何一格的期望次數小於 5 就不能用卡方」。原始版本比這寬鬆:Cochran 在 1950 年代建議的是所有期望次數都 ≥ 1,且期望次數 < 5 的格子不超過全部格子的 20%。對 2×2 表來說,20% 不到一格,所以才退化成「一格都不能低於 5」。
要記住三件事:
- 它是經驗法則,不是定理。 5 這個數字沒有理論推導,它來自 1950 年代對卡方分布近似程度的數值檢查。
- 它管的是「近似」而不是「資料」。 期望次數小的時候, 統計量的分布是離散的、跳躍的,用連續的卡方分布去逼近就不準。這與資料本身好不好無關。
- 看的是期望次數,不是觀察次數。 觀察到 0 個人的格子不必然違規;期望次數 4.2 的格子即使觀察到更多人也算違規。所以
chisq.test()之後第一件事是印$expected。
同一份資料裡就有現成的例子。把分析限縮在 race == Black 這個分層(n = 26):
| 正常體重 ≥ 2500 g(觀察 / 期望) | 低出生體重 < 2500 g(觀察 / 期望) | |
|---|---|---|
| 未吸菸 | 11 / 9.2 | 5 / 6.8 |
| 吸菸 | 4 / 5.8 | 6 / 4.2 |
最小期望次數掉到 4.2,違反了規則。三種算法給的 p 值分別是:未校正 Pearson 0.149、Fisher’s exact 0.228、Yates 校正 0.300——在這張表上最保守的是 Yates 校正,未校正的 Pearson 最不保守。要注意的是 Fisher 並不保證在每個資料集都比 Yates 保守;後面兩節用模擬談的是兩者平均而言都落在名目水準以下這件事,不是它們之間有固定的先後。OR 的信賴區間寬到 0.63–17.16。三種算法都未達統計顯著,但真正該說的是這個分層的樣本數根本不足以偵測任何中等大小的關聯——信賴區間的寬度講的就是這件事,p 值講不出來。
Fisher’s exact test 什麼時候用
Fisher’s exact test 不做近似。它固定住兩邊的邊際總數,直接把「在這些邊際下所有可能的表格」列舉出來,用超幾何分布算出「至少這麼極端」的機率。因為不依賴大樣本近似,期望次數再小都成立。
用它的時機:
- 任何一格的期望次數低於 5(或表格總數很小)。
- 表格裡有 0。
- 樣本數小到你會擔心近似的時候——現代電腦下 2×2 的 Fisher 幾乎免費,沒有理由為了省計算而用近似。
Yates 校正的爭議
Yates 連續性校正把每一格的偏離先減 0.5 再平方:
用意是彌補「用連續分布逼近離散統計量」造成的偏差。R 的 chisq.test() 對 2×2 表預設開啟它,這也是為什麼同一份資料你用 R 與用某些軟體會得到不同的 p 值(本頁的例子:0.026 vs 0.040)。
爭議在於它校正過頭。用模擬把三種檢定放在虛無假設為真的情境下跑(兩組真實風險都是 20%,每個點 3000 次),看它們實際上多常宣告顯著——理想值是 0.05:
figures/scripts/B1-03-chi-square.R| 每組人數 | Pearson(未校正) | Yates 校正 | Fisher 精確 |
|---|---|---|---|
| 10 | 0.030 | 0.006 | 0.006 |
| 15 | 0.053 | 0.010 | 0.019 |
| 20 | 0.048 | 0.019 | 0.022 |
| 30 | 0.052 | 0.026 | 0.026 |
| 50 | 0.049 | 0.024 | 0.024 |
| 80 | 0.051 | 0.034 | 0.037 |
| 120 | 0.048 | 0.030 | 0.030 |
| 200 | 0.048 | 0.034 | 0.034 |
結果違反直覺但很一致:未校正的 Pearson 卡方在每組 15 人以上就已經貼著 0.05,而 Yates 與 Fisher 一路低於名目值——連每組 200 人時仍然只有 0.034 與 0.034。型一錯誤率低於名目值不是好事:它意味著你放棄了本來就付了樣本數代價買到的檢定力。
這是統計學裡少數幾個「教科書的標準建議與模擬結果對不上」的地方。務實的處理方式:
- 報告要寫明用了哪一種(未校正卡方 / Yates / Fisher),不要讓讀者猜。
- 樣本數夠時(期望次數都 ≥ 5),未校正的 Pearson 卡方是合理的預設。
- 樣本數小時,Fisher 是安全的選擇——它保守,但保守的方向是不會製造假陽性;此時真正的問題通常是檢定力不足,而不是選哪個檢定。
- 不論選哪個,都要報效果量與信賴區間。 上面整張爭論只影響第三位小數的 p 值,不影響 OR 是 2 還是 20。
配對的類別資料要用 McNemar
同一批人測兩次(治療前後、兩種診斷工具比較、配對設計的病例對照),資料看起來還是 2×2,但格子的意義完全不同:現在每一格是「同一個人的兩次結果」。
拿 R 說明文件裡那個經典例子(1600 位受訪者在兩個時點被問同一個問題):
| 第一次調查 \ 第二次調查 | 贊成 | 不贊成 |
|---|---|---|
| 贊成 | 794 | 150 |
| 不贊成 | 86 | 570 |
對角線上的人(兩次答案一樣)對「有沒有改變」這個問題完全沒有貢獻。 資訊全在兩個不一致格(discordant cells):150 人從贊成轉不贊成、86 人從不贊成轉贊成。McNemar 檢定就只拿這兩個數字:
這個式子算出來是 = 17.36,p = < 0.001。R 的 mcnemar.test() 預設會做連續性校正————所以它印出來的是 = 16.82,p = < 0.001;精確二項版本則是 p = < 0.001。這裡三個版本結論一致,但上面那個公式是未校正版,看到論文引用時要先確認它報的是哪一個再去對數字。
如果誤把它當獨立樣本丟給卡方檢定,會得到 = 785.5、p = < 0.001——一個天文數字般的顯著結果,但它檢定的是完全不同的虛無假設(同一位受訪者的第一次回答與第二次回答互相獨立),而那個假設本來就荒謬:同一個人的兩次回答當然相關。看到極端顯著的 p 值先想「這個檢定在問什麼」,往往比想「差異多大」更快抓到錯誤。
常見誤用
| 誤用 | 為什麼錯 |
|---|---|
| 只報卡方的 p 值,不報 OR / RR / 風險差 | 檢定回答「有沒有關聯」,效果量才回答「多少」,摘要該寫的是後者 |
| 看觀察次數而不是期望次數來判斷能不能用卡方 | 規則管的是期望次數;chisq.test() 之後要先印 $expected |
| 把「期望次數 < 5」記成鐵律 | Cochran 原始版本允許 20% 的格子低於 5、且全部 ≥ 1;2×2 才退化成一格都不行 |
| 同一批病人測兩次卻用卡方 | 配對資料要用 McNemar;卡方會把同一人算成兩個獨立觀察 |
| 有序類別(期別 I–IV)當名目變項做卡方 | 丟掉次序資訊、檢定力下降;應改用趨勢檢定(Cochran-Armitage)或次序模型 |
| 對每一組兩兩比較都做卡方而不調整 | 與 ANOVA 之後的多重比較是同一個問題,家族錯誤率會膨脹 |
| 用卡方檢定百分比或比率而不是次數 | 卡方吃的是次數,餵百分比等於把樣本數改成 100 |
| 以為 Fisher 的 exact 代表「更正確」 | exact 指 p 值精確計算;它同時是保守的,會損失檢定力 |
| p > 0.05 就說「兩者沒有關聯」 | 只能說本研究未偵測到關聯;小樣本時信賴區間往往寬到什麼都不能排除 |
| 卡方顯著就宣稱因果 | 關聯不等於因果,混淆與選擇偏誤都能造出顯著的列聯表 |
重跑本頁的所有數字
/opt/homebrew/bin/Rscript figures/scripts/B1-03-chi-square.R讀讀看這張圖
答案取自產生本頁圖表的同一份統計輸出,不是另外打上去的。
未吸菸組的低出生體重風險是 25.2%,同一張表上 OR 是 2.02、RR 是 1.61。這兩個數字為什麼差這麼多?
看答案與解析
正確答案: RR 是 1.61,而這個結果一點都不罕見——OR 只有在結果罕見時才近似 RR,這裡它明顯把風險的比值放大了
OR 與 RR 只有在結果罕見時才互相近似,而這裡未吸菸組的風險已經四分之一,離罕見很遠,所以 2.02 明顯大於 1.61。OR 不是風險的比值而是勝算的比值,勝算的分母是「沒有發生」,結果愈常見,勝算就把差距放得愈大。2.01 是 Fisher 的條件最大概似估計,它與樣本 OR 是兩種不同的估計量,不是哪個軟體算錯。世代研究與隨機試驗兩個風險都算得出來,該報 RR;病例對照研究因為設計本身固定了病例與對照的人數,風險算不出來,只能報 OR,邏輯迴歸的係數也是 OR。而最能落地的往往是絕對風險差,因為同一個相對風險在基準風險很低與很高時代表的臨床事件完全不同。
把分析限縮在其中一個分層之後(n = 26),最小期望次數掉到 5 以下。這代表什麼?
看答案與解析
正確答案: 期望次數 4.2 的那一格讓卡方分布的近似不再可靠——看的是期望次數不是觀察次數
期望次數 5 這條線管的是「卡方分布近似得好不好」,不是「資料好不好」。期望次數小的時候,統計量的分布是離散的、跳躍的,用連續的卡方分布去逼近就不準,所以判準是 4.2,觀察到幾個人不是。23.1 是整張表的最小期望次數,分層之後那是另一張表,不能拿它背書。0.3 這個關聯強度看起來比整張表的還大,但這個分層只有 26 個人,OR 的信賴區間寬到跨越一個數量級——樣本數不足以偵測任何中等大小的關聯,而那件事是信賴區間的寬度說的,p 值說不出來。順帶一提,原始的 Cochran 規則其實比「一格都不能低於 5」寬鬆:所有期望次數不低於 1,且期望次數低於 5 的格子不超過全部格子的兩成;2x2 表因為兩成不到一格,才退化成現在這個說法。
1600 位受訪者在兩個時間點各回答一次贊成或不贊成。把這張配對表當成獨立的雙向表去做卡方,會得到一個大得離譜的統計量。McNemar 檢定實際上用到哪些人?
看答案與解析
正確答案: 只有前後改變意見的人。往一個方向改的有 150 位,往另一個方向的比較少,檢定問的是這兩個數字對不對稱
配對表的對角線是兩次答案相同的人,包括兩次都贊成的 794 位。他們對「有沒有改變」完全沒有貢獻,因為他們同時出現在兩邊,怎麼算都不會動到差額。McNemar 只看不一致的那兩格:一個方向 150 位、另一個方向比較少,檢定問的就是這兩個數字對不對稱。把 1600 位當成兩群獨立的人去做卡方,算的是「贊成的比例在兩次之間差多少」,而配對讓同一個人出現兩次,等於把樣本數灌水,於是統計量大得離譜。看到「同一批人前後測」「同一隻眼」「配對設計」這些字眼,就要確認分析方法有沒有跟上。
吸菸組 74 人中有 30 位生出低體重兒,未吸菸組是 115 人中的 29 位,卡方 p = 0.0265。摘要裡最該寫的是哪一個數字?
看答案與解析
正確答案: 絕對風險差 0.153,每一百位吸菸產婦約多十五個低體重兒
卡方顯著只說明「有關聯」,不說方向、不說強度、不說因果,所以換一個 p 值仍然是 p 值:0.040 是另一種算法的結果,它一樣沒有回答風險高了多少。0.161 是關聯強度,範圍在零到一之間、不帶方向,描述用可以,臨床上不好解讀——沒有人知道 0.161 代表多少個嬰兒。0.153 這種絕對風險差最能落地,因為同一個相對風險在基準風險很低與很高的情境下代表的臨床事件完全不同。世代研究與隨機試驗該報相對風險與絕對風險差,病例對照研究只能報勝算比。
同一張雙向表,未校正 Pearson 的 p 是 0.0265、Yates 校正後是 0.0396、Fisher 精確檢定是 0.0362。有人主張「Fisher 名字裡有 exact,所以它的答案最正確」。
看答案與解析
正確答案: 0.0362 是精確算出來的、不是查近似分布,但它把兩邊的邊際當成已知固定
exact 指的是 p 值精確算出來、不是查近似分布,不是「答案更正確」。Fisher 之所以算得出精確的機率,是因為它固定住兩邊的邊際總數再列舉所有可能的表格;在真正固定邊際的設計裡這很自然,但這份研究是「收了一批產婦、事後才知道多少人吸菸」,邊際是隨機的。多條件了一個不必條件的東西,代價就是偏保守,所以 0.0362 落在未校正的 0.0265 與 Yates 的 0.0396 之間。保守不等於正確:一個永遠回答不顯著的檢定最保守,也最沒有用。而 p 值最小也不是該報的理由,那是挑最好看的數字。三個 p 值在這張表上都落在同一側,真正該寫進摘要的是效果量。
在兩組真實風險相同的模擬上重複抽樣,記錄三種算法宣告顯著的比例。每組 15 人時,未校正 Pearson 是 0.053、Yates 是 0.010、Fisher 是 0.019。這說明什麼?
看答案與解析
正確答案: Yates 的 0.010 遠低於名目水準——校正把型一錯誤率壓得太低,代價是檢定力
名目水準是這三個比例該對齊的標準。未校正的 0.053 幾乎剛好貼著它,所以「Pearson 在小樣本會製造假陽性」在這個模擬裡看不到。真正偏離的是校正過的那兩個:Yates 只有 0.010、Fisher 是 0.019,都遠低於名目——它們不是更正確,是更保守,而保守的代價是同樣大小的關聯需要更多人才偵測得到。0.048 是 n = 200 時的比例,它與小樣本時的 0.053 幾乎一樣,所以「樣本愈大愈保守」的方向也不對。要在小表格上下判斷,與其爭論該報哪一個 p 值,不如直接報效果量與它的信賴區間。
用到這個方法的章節
延伸觀看
醫學統計 EP12 卡方檢定
醫學統計 EP15 RR vs OR
醫學統計 EP02 變數類型素材來源與授權
本頁為原創內容