的本質(zhì):從正態(tài)平方和到實(shí)戰(zhàn)應(yīng)用)
1. 從“看不懂公式”到理解卡方檢驗(yàn)的根1.1 為什么你用了那么久卡方檢驗(yàn)卻總覺(jué)得它在“黑箱”里運(yùn)行先講一個(gè)我自己的經(jīng)歷。早幾年做數(shù)據(jù)分析時(shí)我處理過(guò)一個(gè)渠道投放轉(zhuǎn)化率的項(xiàng)目需要判斷不同素材的點(diǎn)擊行為是否有顯著差異。當(dāng)時(shí)我用卡方檢驗(yàn)代碼三行出結(jié)果p值小于0.05于是信心滿滿地寫(xiě)了“兩組存在顯著差異”的結(jié)論。后來(lái) reviewers 問(wèn)我你的檢驗(yàn)統(tǒng)計(jì)量為什么服從卡方分布卡方分布的自由度為什么是 2那一刻我才意識(shí)到我只是會(huì)“按按鈕”根本不理解這個(gè)檢驗(yàn)背后的邏輯。這不是個(gè)例。我見(jiàn)過(guò)太多人在做 A/B 測(cè)試、用戶行為分析、醫(yī)學(xué)統(tǒng)計(jì)時(shí)把卡方檢驗(yàn)當(dāng)成一個(gè)黑箱數(shù)據(jù)丟進(jìn)去p 值冒出來(lái)然后就結(jié)束了。一旦被問(wèn)到“為什么這個(gè)統(tǒng)計(jì)量服從卡方分布”“為什么自由度是 (行數(shù)-1)×(列數(shù)-1)”就會(huì)卡殼。答案其實(shí)藏在標(biāo)題那句話里卡方檢驗(yàn)的底層邏輯是正態(tài)分布的平方和。你看一眼卡方分布的概率密度函數(shù)可能會(huì)被那個(gè)帶 Gamma 函數(shù)的式子嚇到但它的真正定義非常樸素——如果有 k 個(gè)相互獨(dú)立的標(biāo)準(zhǔn)正態(tài)隨機(jī)變量 Z?, Z?, ..., Z?那么它們的平方和χ2 Z?2 Z?2 ... Z?2就服從自由度為 k 的卡方分布。這件事非常重要因?yàn)樗选罢龖B(tài)分布”和“假設(shè)檢驗(yàn)”用一條數(shù)學(xué)鏈條連起來(lái)了。你能檢驗(yàn)擬合優(yōu)度、能檢驗(yàn)列聯(lián)表獨(dú)立性、能估計(jì)方差置信區(qū)間本質(zhì)上都在利用這條“正態(tài)平方和”的關(guān)系。這篇文章我想把這層關(guān)系徹底講透先回到數(shù)學(xué)定義再看三個(gè)典型應(yīng)用場(chǎng)景最后給出一整套可以直接跑的實(shí)操代碼和踩坑記錄。不管你之前對(duì)卡方檢驗(yàn)的理解有多少看完應(yīng)該都能有自己的判斷框架。1.2 卡方檢驗(yàn)是什么它解決什么問(wèn)題用一句話說(shuō)卡方檢驗(yàn)是一類(lèi)基于卡方分布的假設(shè)檢驗(yàn)方法它用來(lái)判斷“觀察到的頻數(shù)次數(shù)”與“理論上期望的頻數(shù)”之間是否存在顯著差異。這個(gè)差異如果大得離譜我們就傾向于拒絕“兩者一致”的原假設(shè)。常見(jiàn)應(yīng)用場(chǎng)景包括檢驗(yàn)一枚骰子是否均勻擬合優(yōu)度檢驗(yàn)檢驗(yàn)電商頁(yè)面中不同 Banner 的點(diǎn)擊率是否有差異列聯(lián)表獨(dú)立性檢驗(yàn)檢驗(yàn)性別與購(gòu)買(mǎi)偏好是否相關(guān)檢驗(yàn)一組數(shù)據(jù)的方差是否等于某個(gè)特定值方差檢驗(yàn)判斷回歸模型中的殘差是否滿足正態(tài)性假設(shè)間接用卡方判斷。這些場(chǎng)景看起來(lái)五花八門(mén)但它們的檢驗(yàn)統(tǒng)計(jì)量最終都?xì)w結(jié)為“觀察值減期望值平方再除以期望值”的累加形式或者歸結(jié)為“樣本方差乘以系數(shù)后服從卡方分布”這一結(jié)論。之所以能做到統(tǒng)一正是因?yàn)榭ǚ椒植际菑臉?biāo)準(zhǔn)正態(tài)分布平方和里“長(zhǎng)”出來(lái)的而當(dāng)我們面對(duì)頻數(shù)、比例、方差等問(wèn)題時(shí)很多統(tǒng)計(jì)量的漸近分布都能轉(zhuǎn)化成正態(tài)再轉(zhuǎn)化成卡方。我建議你把卡方分布理解成一個(gè)“由正態(tài)的平方堆砌出來(lái)的標(biāo)準(zhǔn)尺子”。你用這把尺子去量觀察頻數(shù)和期望頻數(shù)的偏差量出來(lái)的值如果超過(guò)了尺子上的臨界區(qū)域說(shuō)明偏差不只是抽樣誤差而是真實(shí)的系統(tǒng)差異。2. 深入數(shù)學(xué)本質(zhì)為什么偏偏是“平方和”定義卡方分布2.1 “平方”第一步先消除方向再放大極端偏差很多人第一次看到卡方分布的定義時(shí)會(huì)想為什么不是絕對(duì)值的和為什么不是直接的和這里“平方”有兩個(gè)關(guān)鍵作用。第一平方消除了正負(fù)方向的影響。一個(gè)標(biāo)準(zhǔn)正態(tài)變量 Z 可以取正值也可以取負(fù)值如果直接把 Z 加起來(lái)正負(fù)會(huì)相互抵消得不到任何有意義的“距離”度量。平方之后無(wú)論 Z 是正是負(fù)貢獻(xiàn)都是非負(fù)的我們衡量的純粹是“偏離原點(diǎn)多遠(yuǎn)”。第二平方會(huì)放大大的偏差、壓縮小的偏差。對(duì)于一個(gè)離原點(diǎn)很遠(yuǎn)的點(diǎn)比如 Z3平方后是 9Z-3 平方后同樣是 9。這意味著偏離大的樣本在統(tǒng)計(jì)量里會(huì)被賦予更大權(quán)重而接近 0 的樣本幾乎不影響結(jié)果。這個(gè)放大的特性讓卡方統(tǒng)計(jì)量對(duì)“尾部異?!狈浅C舾小蟮钠顣?huì)讓統(tǒng)計(jì)量急劇增大從而更容易落在拒絕域里。這里可以打一個(gè)生活化的比方。假設(shè)你在衡量一個(gè)籃球隊(duì)的投籃準(zhǔn)度每個(gè)球員投一次距離靶心的偏差用 Z 表示。如果你只看 Z 的平均值一個(gè)投偏右邊 3 米的球員和一個(gè)投偏左邊 3 米的球員會(huì)互相抵消得出“整體挺準(zhǔn)”的假象。但如果你把每個(gè)偏差平方后加起來(lái)兩個(gè)方向上的大偏差都會(huì)顯形。這就是平方運(yùn)算的意義它把“偏離”變成“能量”或“代價(jià)”并且對(duì)大偏差特別不寬容。在擬合優(yōu)度檢驗(yàn)中這個(gè)邏輯體現(xiàn)得非常直接每一類(lèi)別的貢獻(xiàn)是 (觀察頻數(shù)-期望頻數(shù))2/期望頻數(shù)。差值越大貢獻(xiàn)越大差值越小貢獻(xiàn)越小。所有類(lèi)別的貢獻(xiàn)加起來(lái)就是一個(gè)總的“偏差能量”。如果這個(gè)能量超過(guò)卡方分布提供的閾值就認(rèn)為觀察數(shù)據(jù)與期望假設(shè)不一致。2.2 標(biāo)準(zhǔn)正態(tài)分布平方和的推導(dǎo)從單變量到多變量我們來(lái)看一個(gè)最基本的例子。設(shè) Z ~ N(0,1)即標(biāo)準(zhǔn)正態(tài)分布。令 Y Z2。那么 Y 服從什么分布通過(guò)變量變換法可以推導(dǎo)出 Y 的概率密度函數(shù)。設(shè)標(biāo)準(zhǔn)正態(tài)的概率密度是f(x) (1/√(2π))·exp(-x2/2)令 y x2則 |x| √ydx/dy 1/(2√y)。兩個(gè)對(duì)稱分支合在一起得到 Y 的概率密度f(wàn)_Y(y) (1/√(2π))·exp(-y/2)·(1/√y), y 0整理一下f_Y(y) (1/√(2π))·y^(-1/2)·exp(-y/2)這個(gè)形式其實(shí)就是 Gamma 分布 Gamma(shape1/2, rate1/2) 的密度函數(shù)也叫自由度為 1 的卡方分布記作 χ2(1)。再推廣一步。如果有 k 個(gè)相互獨(dú)立的標(biāo)準(zhǔn)正態(tài)變量 Z?, Z?, ..., Z_k它們的平方和Q Z?2 Z?2 ... Z_k2可以利用矩母函數(shù)或卷積證明Q 的分布是 Gamma(shapek/2, rate1/2)也就是自由度為 k 的卡方分布 χ2(k)。這個(gè)推導(dǎo)過(guò)程說(shuō)明了一個(gè)關(guān)鍵點(diǎn)卡方分布本質(zhì)上是一種特殊的 Gamma 分布它的形狀參數(shù)由“正態(tài)變量的個(gè)數(shù)”決定。每多一個(gè)獨(dú)立的標(biāo)準(zhǔn)正態(tài)變量進(jìn)入平方和自由度就加一卡方分布的均值也就加一因?yàn)?χ2(k) 的均值為 k。方差則是 2k。順便說(shuō)一句如果你看到卡方分布密度函數(shù)里那個(gè) Gamma 函數(shù) Γ(k/2)不用慌它只是為了保證密度函數(shù)在定義域上積分為 1 而引入的歸一化常數(shù)在檢驗(yàn)中通常不會(huì)直接手算它而是查表或者用軟件。2.3 自由度表示“有效信息量”而不是變量數(shù)量“自由度”這個(gè)詞對(duì)初學(xué)者很抽象但它其實(shí)是理解卡方分布的關(guān)鍵。自由度 k在壓方檢驗(yàn)中往往不等于你觀測(cè)到的變量個(gè)數(shù)而是等于有效獨(dú)立的“標(biāo)準(zhǔn)正態(tài)信息”個(gè)數(shù)。舉個(gè)最典型的例子設(shè) X?, X?, ..., X_n 是來(lái)自總體 N(μ, σ2) 的獨(dú)立樣本。樣本方差定義為S2 (1/(n-1))·Σ(X? - X?)2我們要檢驗(yàn)總體方差 σ2 是否為某個(gè)給定值 σ?2常用的統(tǒng)計(jì)量是χ2 (n-1)·S2/σ?2這個(gè)統(tǒng)計(jì)量服從 χ2(n-1)。這里有個(gè)非常常見(jiàn)的困惑明明用了 n 個(gè)樣本為什么自由度是 n-1 而不是 n原因是我們計(jì)算樣本方差時(shí)先估算了樣本均值 X?這個(gè)估算過(guò)程給數(shù)據(jù)施加了一個(gè)線性約束Σ(X? - X?) 0。也就是說(shuō)在 n 個(gè)偏差 X? - X? 中只有 n-1 個(gè)是自由變化的最后一個(gè)可以由前 n-1 個(gè)確定。換算到標(biāo)準(zhǔn)正態(tài)平方和的語(yǔ)言里真正相互獨(dú)立的標(biāo)準(zhǔn)正態(tài)變量其實(shí)只有 n-1 個(gè)。這一點(diǎn)特別容易出錯(cuò)。我見(jiàn)過(guò)有人直接把自由度填成樣本量 n結(jié)果臨界值查錯(cuò)結(jié)論也會(huì)跟著錯(cuò)。判定自由度時(shí)一定要問(wèn)自己到底有多少個(gè)獨(dú)立的信息單元在貢獻(xiàn)這個(gè)平方和有沒(méi)有在用樣本均值或期望頻數(shù)合計(jì)之類(lèi)的約束條件“每用一個(gè)估計(jì)參數(shù)自由度通常就會(huì)少一個(gè)?!痹跀M合優(yōu)度檢驗(yàn)中如果我們?cè)诠烙?jì)參數(shù)時(shí)用了 m 個(gè)參數(shù)自由度就會(huì)變?yōu)轭?lèi)別數(shù)減 1 再減 m在列聯(lián)表獨(dú)立性檢驗(yàn)中行合計(jì)和列合計(jì)是已知的約束自由度就是 (r-1)(c-1)。3. 藏在教科書(shū)角落的三個(gè)核心應(yīng)用——它們都在吃“正態(tài)平方和”的老本3.1 擬合優(yōu)度檢驗(yàn)骰子是否公平由“偏差平方和”裁決擬合優(yōu)度檢驗(yàn)Goodness of Fit Test是最容易看出“觀察-期望平方和”邏輯的場(chǎng)景。拿擲骰子舉例你擲一枚骰子 600 次理論上每個(gè)面應(yīng)該出現(xiàn) 100 次。但現(xiàn)實(shí)中每個(gè)面出現(xiàn)的次數(shù)不會(huì)剛好都是 100有的面出現(xiàn) 92 次有的面出現(xiàn) 108 次。問(wèn)題來(lái)了這些偏差只是隨機(jī)波動(dòng)還是說(shuō)明骰子有問(wèn)題卡方擬合優(yōu)度檢驗(yàn)給出的統(tǒng)計(jì)量是χ2 Σ? (O? - E?)2 / E?其中 O? 是第 i 類(lèi)的觀察頻數(shù)E? 是第 i 類(lèi)的期望頻數(shù)。這個(gè)統(tǒng)計(jì)量在大樣本下近似服從自由度為 (k-1) 的卡方分布k 是類(lèi)別數(shù)。為什么服從卡方分布核心原因在于在樣本量足夠大時(shí)觀察頻數(shù) O? 的抽樣分布近似正態(tài)而 (O? - E?) / √E? 近似標(biāo)準(zhǔn)正態(tài)。對(duì)這些量平方求和就回到了“標(biāo)準(zhǔn)正態(tài)平方和”的老路。需要注意這里“每類(lèi)觀測(cè)頻數(shù)近似正態(tài)”并不是說(shuō)原始數(shù)據(jù)是正態(tài)的。擲骰子的原始結(jié)果是離散的類(lèi)別但多分類(lèi)計(jì)數(shù)經(jīng)過(guò)中心極限定理之后每類(lèi)的計(jì)數(shù)誤差可以被正態(tài)分布很好地近似。這個(gè)“近似正態(tài)再平方求和”的思路是整個(gè)卡方檢驗(yàn)?zāi)軓V泛應(yīng)用的統(tǒng)計(jì)基礎(chǔ)。實(shí)操時(shí)有一個(gè)經(jīng)驗(yàn)法則如果某個(gè)類(lèi)別的期望頻數(shù)小于 5χ2 近似就可能會(huì)變差。此時(shí)建議合并相鄰類(lèi)別后再檢驗(yàn)或者改用精確檢驗(yàn)方法。3.2 獨(dú)立性檢驗(yàn)列聯(lián)表里的“期望頻數(shù)”為什么是行合計(jì)乘列合計(jì)除以總數(shù)獨(dú)立性檢驗(yàn)應(yīng)該是最常見(jiàn)的卡方應(yīng)用。它的原假設(shè)是兩個(gè)分類(lèi)變量相互獨(dú)立。比如我們想判斷“是否喜歡某個(gè)產(chǎn)品”是否與“性別”有關(guān)。數(shù)據(jù)整理成 2 行 × 2 列的列聯(lián)表或更多行更多列。獨(dú)立性檢驗(yàn)的統(tǒng)計(jì)量形式還是χ2 Σ?? (O?? - E??)2 / E??其中 O?? 是第 i 行第 j 列的觀察頻數(shù)。這里最難理解的是期望頻數(shù) E?? 怎么算。很多人只會(huì)套公式“行合計(jì) × 列合計(jì) / 總數(shù)”但不明白為什么。答案來(lái)自概率論里的獨(dú)立性定義如果兩個(gè)事件 A 和 B 獨(dú)立那么 P(A∩B) P(A)·P(B)。在列聯(lián)表中第 i 行的邊緣頻率估計(jì)值為“行合計(jì) / 總數(shù)”第 j 列的邊緣頻率估計(jì)值為“列合計(jì) / 總數(shù)”。如果它們獨(dú)立那么這一格的聯(lián)合概率估計(jì)值就是“行合計(jì) / 總數(shù)”乘以“列合計(jì) / 總數(shù)”。期望頻數(shù)等于這個(gè)概率估計(jì)值乘以總數(shù)得到E?? (行合計(jì) × 列合計(jì)) / 總數(shù)這個(gè)“行合計(jì)乘列合計(jì)除以總數(shù)”的公式由此而來(lái)不是憑空捏造的。獨(dú)立性檢驗(yàn)的自由度是 (r-1)(c-1)這個(gè)也值得解釋一下。在給定行合計(jì)和列合計(jì)的條件下列聯(lián)表內(nèi)部的格子并不是全部自由的。比如一個(gè) 2×2 表只要你知道某個(gè)格子的數(shù)值其他三個(gè)格子的值就都被行合計(jì)和列合計(jì)確定了。所以自由度是 (2-1)×(2-1)1。推廣到 r 行 c 列自由度就是 (r-1)(c-1)。這與“平方和里獨(dú)立標(biāo)準(zhǔn)正態(tài)分量的個(gè)數(shù)”完全對(duì)應(yīng)。一個(gè)二次需要注意的是期望頻數(shù)不能太小。如果 20% 以上格子的期望頻數(shù)小于 5或者任意一格期望頻數(shù)小于 1χ2 近似就不可靠。此時(shí)建議使用 Fisher 精確檢驗(yàn)或者使用卡方檢驗(yàn)加模擬 p 值。3.3 方差估計(jì)與置信區(qū)間卡方分布不只是“頻數(shù)檢驗(yàn)工具”很多人不知道卡方分布還有一個(gè)重要角色估計(jì)總體方差。公式(n-1)·S2/σ2 ~ χ2(n-1)是方差區(qū)間估計(jì)的基礎(chǔ)。你可以反著用這個(gè)分布構(gòu)造 σ2 的置信區(qū)間。比如給定置信水平 1-α可以找到兩個(gè)分位數(shù) χ2_{1-α/2} 和 χ2_{α/2}使得P(χ2_{1-α/2} ≤ (n-1)S2/σ2 ≤ χ2_{α/2}) 1-α解出 σ2 的范圍得到方差的置信區(qū)間[ (n-1)S2 / χ2_{α/2}, (n-1)S2 / χ2_{1-α/2} ]這個(gè)公式在生產(chǎn)質(zhì)量控制、測(cè)量系統(tǒng)分析、金融風(fēng)險(xiǎn)的波動(dòng)率估計(jì)里都有應(yīng)用。理解它并不需要背公式而只需要記住一件事樣本方差之所以能跟卡方分布掛鉤是因?yàn)闃颖痉讲畋举|(zhì)上也是一個(gè)“正態(tài)偏差的平方和”——分子 Σ(X? - X?)2 除以 σ2 后恰好可以改寫(xiě)為 n-1 個(gè)獨(dú)立標(biāo)準(zhǔn)正態(tài)變量的平方和。這也是為什么“正態(tài)分布的平方和”這個(gè)關(guān)系如此重要它把“方差”這種二階矩與“卡方分布”這種檢驗(yàn)分布連接起來(lái)。你通過(guò)樣本方差去推斷總體方差本質(zhì)上就是在通過(guò)一組標(biāo)準(zhǔn)正態(tài)平方和去推斷正態(tài)分布的離散程度。4. 實(shí)操現(xiàn)場(chǎng)從零復(fù)現(xiàn)一次卡方檢驗(yàn)并驗(yàn)證它與正態(tài)平方和的關(guān)系4.1 用 Python 模擬標(biāo)準(zhǔn)正態(tài)平方和直方圖對(duì)比理論卡方曲線理論講得再多也不如直接動(dòng)手跑一遍。我們先驗(yàn)證最基本的關(guān)系標(biāo)準(zhǔn)正態(tài)分布的平方和確實(shí)服從卡方分布。用 Python 寫(xiě)一個(gè)模擬腳本import numpy as np import matplotlib.pyplot as plt from scipy import stats np.random.seed(42) # 模擬自由度 k3 的卡方分布 k 3 n_sim 100000 samples np.random.normal(loc0, scale1, size(n_sim, k)) chi_sq_samples np.sum(samples**2, axis1) # 畫(huà)直方圖 plt.figure(figsize(10, 6)) plt.hist(chi_sq_samples, bins80, densityTrue, alpha0.6, label模擬值) # 疊加理論卡方密度曲線 x np.linspace(0, 20, 400) plt.plot(x, stats.chi2.pdf(x, dfk), r-, label理論χ2(3)密度曲線) plt.xlabel(標(biāo)準(zhǔn)正態(tài)平方和) plt.ylabel(概率密度) plt.title(自由度 k3 的正態(tài)平方和分布) plt.legend() plt.show()運(yùn)行這段代碼你會(huì)在直方圖上看到一條非常貼合的理論曲線。這就是卡方分布的“真身”你不需要從卡方分布里抽樣只需要從標(biāo)準(zhǔn)正態(tài)分布里抽取獨(dú)立樣本平方再求和就能得到卡方分布。這個(gè)實(shí)驗(yàn)每次跑都會(huì)成功因?yàn)樗皇乔珊隙菙?shù)學(xué)定理在起作用。你可以進(jìn)一步修改自由度 k 為 1、5、10觀察曲線形態(tài)變化。k 越大曲線越向右移也越來(lái)越對(duì)稱。這是因?yàn)楫?dāng)自由度增大時(shí)卡方分布逐漸趨近于正態(tài)分布中心極限定理的又一個(gè)體現(xiàn)。4.2 手工計(jì)算一個(gè)完整擬合優(yōu)度檢驗(yàn)?zāi)M我們模擬一個(gè)“檢測(cè)骰子是否公平”的例子。假設(shè)擲骰子 600 次記錄每個(gè)面出現(xiàn)次數(shù)然后檢驗(yàn)骰子是否均勻。import numpy as np from scipy import stats np.random.seed(2024) n_rolls 600 observed np.random.multinomial(n_rolls, p[1/6]*6) print(觀察頻數(shù):, observed) # 期望頻數(shù)每個(gè)面理論出現(xiàn) 100 次 expected np.full(6, n_rolls / 6) # 計(jì)算卡方統(tǒng)計(jì)量 chi2_stat np.sum((observed - expected)**2 / expected) df len(observed) - 1 p_value 1 - stats.chi2.cdf(chi2_stat, df) print(f卡方統(tǒng)計(jì)量: {chi2_stat:.4f}) print(f自由度: {df}) print(fp值: {p_value:.4f}) # 也可以直接用 scipy 的函數(shù) chi2_scipy, p_scipy, df_scipy, expected_scipy stats.chi2_contingency( np.array([observed, expected]) )這里需要注意stats.chi2_contingency通常用列聯(lián)表輸入我這里把它強(qiáng)行塞進(jìn)兩個(gè)“行”只是為了演示接口用法實(shí)際做擬合優(yōu)度檢驗(yàn)更推薦直接手算或者用stats.chisquare(observed, f_expexpected)chi2_result stats.chisquare(observed, f_expexpected) print(chi2_result)stats.chisquare會(huì)自動(dòng)計(jì)算卡方統(tǒng)計(jì)量、自由度和 p 值。但說(shuō)實(shí)話我建議你在理解階段別完全依賴這個(gè)函數(shù)最好先手算一遍再拿它驗(yàn)證。原因很簡(jiǎn)單手算能讓你意識(shí)到統(tǒng)計(jì)量是“每一項(xiàng)偏差平方除以期望頻數(shù)”的累加而直接調(diào)庫(kù)會(huì)讓這一層邏輯徹底被隱藏。4.3 列聯(lián)表獨(dú)立性檢驗(yàn)的標(biāo)準(zhǔn)步驟與 Python/R 對(duì)照列聯(lián)表獨(dú)立性檢驗(yàn)的邏輯我們用一份模擬的“性別 × 購(gòu)買(mǎi)意愿”數(shù)據(jù)來(lái)演示。數(shù)據(jù)行是人列是“愿意購(gòu)買(mǎi) / 不愿意購(gòu)買(mǎi)”。import numpy as np from scipy import stats # 構(gòu)建 2×2 列聯(lián)表 table np.array([[120, 80], [90, 110]]) chi2, p, dof, expected stats.chi2_contingency(table, correctionFalse) print(卡方統(tǒng)計(jì)量:, chi2) print(p值:, p) print(自由度:, dof) print(期望頻數(shù)矩陣:\n, expected)expected輸出結(jié)果可以看到每個(gè)格子的期望頻數(shù)它的計(jì)算方式就是行合計(jì)×列合計(jì)/總數(shù)。我強(qiáng)烈建議你拿這個(gè)輸出結(jié)果驗(yàn)證一下公式。在 R 語(yǔ)言里同樣做這件事只需要一行table - matrix(c(120, 80, 90, 110), nrow 2, byrow TRUE) chisq.test(table, correct FALSE)R 的chisq.test默認(rèn)會(huì)做連續(xù)性校正continuity correction這在 2×2 表中尤其常見(jiàn)。如果你希望計(jì)算結(jié)果與 Python 的correctionFalse一致需要顯式設(shè)置correct FALSE。關(guān)于校正的問(wèn)題我放到下一節(jié)詳細(xì)講。這里先打一個(gè)預(yù)防針兩種軟件默認(rèn)設(shè)置不同可能讓你拿到不同的 p 值這不是 bug而是統(tǒng)計(jì)學(xué)家對(duì)“近似質(zhì)量”的不同取舍。4.4 實(shí)操中的 3 條心得第一先看邊際分布再跑檢驗(yàn)。如果列聯(lián)表中某一行或某一列的合計(jì)特別小檢驗(yàn)的可靠性會(huì)大幅下降。你應(yīng)該在跑檢驗(yàn)之前就觀察表格看看期望頻數(shù)最小的格子有多小。第二報(bào)告結(jié)果時(shí)不要只寫(xiě) p 值。至少要附帶統(tǒng)計(jì)量值和自由度比如“χ2(1) 8.34, p 0.004”。這個(gè)習(xí)慣能幫助讀者判斷你的模型設(shè)定是否合理也方便別人檢查你的自由度是否算對(duì)。第三檢驗(yàn)前想清楚原假設(shè)到底是什么。擬合優(yōu)度檢驗(yàn)的原假設(shè)是“觀察數(shù)據(jù)來(lái)自某理論分布”獨(dú)立性檢驗(yàn)的原假設(shè)是“兩個(gè)變量獨(dú)立”。如果連原假設(shè)都沒(méi)想清楚p 值再小也沒(méi)有意義。5. 常見(jiàn)問(wèn)題與排查技巧實(shí)錄5.1 連續(xù)性校正Yates 校正到底用不用這是我在做 2×2 列聯(lián)表時(shí)遇到最多的爭(zhēng)執(zhí)。Yates 連續(xù)性校正在公式里給每個(gè) |O-E| 減去 0.5公式變成χ2 Σ (|O? - E?| - 0.5)2 / E?這樣做的好處是在小樣本時(shí)讓 χ2 統(tǒng)計(jì)量更接近理論卡方分布避免低估 p 值壞處是它讓統(tǒng)計(jì)量變小從而讓結(jié)果傾向于“保守”即不太容易拒絕原假設(shè)。這可能導(dǎo)致檢驗(yàn)功效下降明明有差異卻檢不出來(lái)。我的經(jīng)驗(yàn)是如果樣本量不大比如總頻數(shù)小于 40或有期望頻數(shù)小于 5校正是有道理的如果樣本量很大校正與否對(duì)結(jié)果幾乎沒(méi)有影響因?yàn)?(|O-E|-0.5)2 與 (O-E)2 的差異會(huì)趨于消失。Python 里stats.chi2_contingency的correctionTrue是默認(rèn)值R 里chisq.test也默認(rèn)帶校正這說(shuō)明主流工具的默認(rèn)選擇是保守派。但實(shí)際操作時(shí)我通常會(huì)在樣本量足夠大所有期望頻數(shù)大于 5時(shí)關(guān)閉校正這樣更不容易漏掉真實(shí)差異。5.2 期望頻數(shù)太小合并類(lèi)別還是用 Fisher 精確檢驗(yàn)期望頻數(shù)太小時(shí)χ2 分布近似會(huì)失效。到底多小算太小常規(guī)經(jīng)驗(yàn)法則是期望頻數(shù)小于 5 的格子比例不能超過(guò) 20%且不能有期望頻數(shù)小于 1 的格子。如果違反了這個(gè)條件有兩條路合并相鄰類(lèi)別在擬合優(yōu)度檢驗(yàn)中把類(lèi)別合理合并比如把年齡段“18-24”“25-34”合并成“18-34”可以減少類(lèi)別數(shù)提高每類(lèi)的期望頻數(shù)。改用 Fisher 精確檢驗(yàn)在列聯(lián)表檢驗(yàn)中Fisher 精確檢驗(yàn)不依賴卡方近似而是直接計(jì)算超幾何分布下的精確概率。在小樣本下它是更可靠的選擇。Python 里可以用scipy.stats.fisher_exact只支持 2×2 表更大的表可以用scipy.stats.chi2_contingency中的lambda_log-likelihood或者 R 里的fisher.test。我這里引用一句我常用的判斷準(zhǔn)則來(lái)自經(jīng)典統(tǒng)計(jì)教材如果總頻數(shù)小于 20直接用 Fisher如果總頻數(shù)在 20 到 40 之間且所有期望頻數(shù)大于 5用卡方如果有期望頻數(shù)小于 5用 Fisher。5.3 自由度算錯(cuò)卡方檢驗(yàn)最常見(jiàn)的翻車(chē)現(xiàn)場(chǎng)自由度算錯(cuò)帶來(lái)的直接后果是 p 值整體偏移有時(shí)候本來(lái)顯著的變成不顯著或者相反。我自己踩過(guò)的最深一次坑是在做多維列聯(lián)表時(shí)把自由度假設(shè)成了 (r-1)(c-1)但我的模型里其實(shí)已經(jīng)塞了一個(gè)額外變量自由度應(yīng)該再減去相應(yīng)參數(shù)個(gè)數(shù)。當(dāng)時(shí) p 值看起來(lái)非?!帮@著”但后來(lái)復(fù)核時(shí)才發(fā)現(xiàn)自由度不對(duì)結(jié)論差了很多。這里我整理一個(gè)自由度速查表檢驗(yàn)類(lèi)型自由度公式說(shuō)明擬合優(yōu)度檢驗(yàn)k-1-mk 為類(lèi)別數(shù)m 為從數(shù)據(jù)中估計(jì)的分布參數(shù)個(gè)數(shù)列聯(lián)表獨(dú)立性檢驗(yàn)(r-1)(c-1)r 為行數(shù)c 為列數(shù)方差檢驗(yàn)n-1n 為樣本量多重比較修正后的卡方檢驗(yàn)按具體對(duì)比矩陣計(jì)算不要照搬單一公式建議在輸出結(jié)果前手動(dòng)驗(yàn)證一次自由度特別是你用了別人的代碼腳本時(shí)。我經(jīng)??吹骄W(wǎng)上的教程直接把自由度假設(shè)為 1這在很多場(chǎng)景下是錯(cuò)的。5.4 卡方檢驗(yàn) vs Fisher 精確檢驗(yàn) vs G 檢驗(yàn)怎么選很多初學(xué)者以為卡方檢驗(yàn)是唯一的頻數(shù)檢驗(yàn)方法實(shí)際上還有 Fisher 精確檢驗(yàn)和似然比 G 檢驗(yàn)??ǚ綑z驗(yàn)Pearson χ2計(jì)算簡(jiǎn)單適用范圍廣超大樣本時(shí)非常方便但期望頻數(shù)小時(shí)近似變差。Fisher 精確檢驗(yàn)不依賴大樣本近似小樣本精確但只能處理 2×2 表擴(kuò)展表計(jì)算量會(huì)爆炸。G 檢驗(yàn)似然比檢驗(yàn)統(tǒng)計(jì)量為 2·ΣO·ln(O/E)同樣近似服從卡方分布在某些場(chǎng)景下比 Pearson 卡方更穩(wěn)健但直觀性不如卡方。如果你只是做常規(guī)頻數(shù)判斷卡方足夠用。如果樣本量不大且數(shù)據(jù)稀疏優(yōu)先考慮 Fisher。如果你的數(shù)據(jù)量很大G 檢驗(yàn)可以作為穩(wěn)健性檢查的補(bǔ)充。5.5 用檢驗(yàn)前先看數(shù)據(jù)的 4 個(gè)自查清單我每次用卡方檢驗(yàn)前都會(huì)過(guò)一遍下面的清單也建議你保存下來(lái)數(shù)據(jù)類(lèi)型是否為頻數(shù)計(jì)數(shù)而不是百分比或比例除非是原始計(jì)數(shù)換算而來(lái)各觀測(cè)之間是否獨(dú)立同一個(gè)被試被重復(fù)計(jì)數(shù)了嗎期望頻數(shù)是否滿足經(jīng)驗(yàn)法則小于 5 的格子比例小于 20%自由度和分組級(jí)別是否匹配有沒(méi)有漏掉被估計(jì)的參數(shù)個(gè)數(shù)把這些檢查做完再下結(jié)論能避免絕大多數(shù)“統(tǒng)計(jì)方法誤用”的尷尬。寫(xiě)在最后我對(duì)卡方檢驗(yàn)的體會(huì)我記得第一次親手模擬出“標(biāo)準(zhǔn)正態(tài)平方和等于卡方分布”的那天心里有一種豁然開(kāi)朗的感覺(jué)。以前背的那些公式——擬合優(yōu)度、獨(dú)立性檢驗(yàn)、方差置信區(qū)間——忽然串成了同一條線。它們做的都是同一件事把數(shù)據(jù)和假設(shè)之間的偏差轉(zhuǎn)化成“若干個(gè)獨(dú)立標(biāo)準(zhǔn)正態(tài)變量平方和”的形式放到χ2這把尺子上量一量。這也是我在實(shí)際項(xiàng)目中越來(lái)越強(qiáng)調(diào)基礎(chǔ)數(shù)學(xué)的原因。數(shù)據(jù)分析師可以調(diào)包但不能永遠(yuǎn)調(diào)包。當(dāng)你理解了一個(gè)統(tǒng)計(jì)量為什么服從某種分布你就能判斷在什么場(chǎng)景下它成立、什么場(chǎng)景下它失效而不是機(jī)械地等機(jī)器給結(jié)論。如果你也想快速驗(yàn)證自己是否真的理解了我建議你用上面第 4.1 節(jié)的小實(shí)驗(yàn)把自由度改成 2、5、10然后用一組真實(shí)業(yè)務(wù)數(shù)據(jù)跑一遍擬合優(yōu)度檢驗(yàn)。當(dāng)你親眼看到模擬直方圖壓在那條理論曲線上時(shí)你對(duì)卡方檢驗(yàn)的認(rèn)識(shí)就徹底不一樣了。最后再分享一個(gè)小技巧做列聯(lián)表分析時(shí)別只提交 p 值和卡方值把期望頻數(shù)矩陣也附上。它既是審稿人檢查你模型假設(shè)的依據(jù)也是你自己判斷檢驗(yàn)是否可靠的最直接證據(jù)。