卡方检验隐藏逻辑:正态分布平方和如何塑造统计推断
2026/9/18 11:46:26 网站建设 项目流程

卡方检验的隐藏逻辑:为什么正态分布的平方和如此重要?

很多人学卡方检验的时候,教材上直接甩出一个统计量公式:T = Σ(Oi - Ei)² / Ei,然后告诉你“当T足够大时拒绝原假设”。背下来很容易,考试也能过,但真到了自己处理数据时,问题就来了:为什么是平方?为什么要除以期望频数?为什么偏偏和正态分布有关系?这三个问题如果答不上来,你对卡方检验的理解就还停留在“套公式”的层面。

这篇文章想做的,就是把卡方检验背后那条隐藏的逻辑链慢慢掰开:从“观测频数和期望频数的偏差”出发,一路推到“标准正态分布的平方和”,再解释为什么最终形成了一个独立的卡方分布。顺带也会聊很多教科书写得不够透的实操细节,比如自由度到底怎么数、期望频数太小怎么办、什么时候要动连续性校正。不管你是做市场调研、医学统计、用户分析,还是单纯在啃统计学教材,这篇文章都值得你花十几分钟读完。读完你会发现,很多以前靠背的规则,其实是能从原理里自己推出来的。

1. 卡方检验到底在检验什么

1.1 核心问题:观察值和理论值之间的偏差是否“异常”

先说清楚卡方检验的定位。它是非参数检验里最常用的一个工具,核心任务是判断“实际观察到的分类数据,和某个理论预期之间,差异是否大到不能再用随机波动来解释”。

举个例子。你抛一枚硬币100次,正面58次、反面42次。理论上正反面各50次,但现在差了8次。问题是:这8次偏差算正常吗?如果硬币是公平的,重复做这个实验,偏差大于等于8次的概率有多大?如果这个概率很小,比如小于0.05,那你就有理由怀疑硬币不是公平的。卡方检验就是帮你算出这个“概率”的工具。

很多人在这一步就开始犯迷糊。他们会想:既然观测值和期望值的差,已经算出来了,直接比大小不就行了?为什么还要搞一个平方,又要除以期望值,折腾出这么个统计量?

因为“直接比大小”有个致命问题:偏差的绝对值本身没有统一的衡量尺度。同样是偏差5,出现在期望频数为100的组里,和出现在期望频数为5的组里,意义完全不一样。前者是5%的相对偏差,后者是100%的相对偏差。所以必须对偏差做一个“标准化”处理。怎么标准化?这背后是一整套统计学逻辑,也是整篇文章要讲的重点。

1.2 偏差的标准化:为什么要除以期望频数

我们先来看一个直觉上的问题:为什么卡方统计量里每一项是(Oi - Ei)²/Ei,而不是简单的(Oi - Ei),或者是(Oi - Ei)²?

先说为什么不直接用(Oi - Ei)。因为如果直接用偏差之和,正负偏差会相互抵消。比如一个组偏多5,另一个组偏少5,加起来是0,看起来完美符合理论值,但实际上一塌糊涂。所以必须把偏差“转正”,要么取绝对值,要么取平方。卡方检验选择了平方。

接着是为什么除以Ei。这一项在统计学里叫“标准化”或“加权”。理论上,期望频数越大的组,允许的随机波动范围也越大。打个比方,你往一个篮子里扔100个球,每个球进不进是随机的,那进了50个和进了60个,可能都算正常;但如果只扔了5个球,进了1个和进了4个,差异就非常显著了。同样大小的绝对偏差,放在期望值大的组别里,应该被“打折”;放在期望值小的组别里,应该被“放大”。除以Ei就实现了这个效果。

但是这里有个更深的数学问题:为什么是除以Ei,而不是除以其他东西?从后面的推导可以看出,这是因为在特定假设下,每个组的标准化偏差近似服从标准正态分布,而Ei恰好是泊松分布或二项分布的方差。这个伏笔先埋下,我们把逻辑链推到位之后,它自然会浮现出来。

2. 为什么偏偏是正态分布的平方和

2.1 从二项分布出发,逼近正态分布

要做卡方检验,我们面对的数据本质上是计数数据。计数数据的天然模型是二项分布。假设某个事件发生的概率是p,做了n次独立重复试验,那么事件发生次数X服从二项分布B(n, p),期望为np,方差为np(1-p)。

现在关键的一步来了:当n足够大时,二项分布可以用正态分布来近似。这是棣莫弗-拉普拉斯中心极限定理的内容。更精确地说: [ \frac{X - np}{\sqrt{np(1-p)}} \approx N(0, 1) ] 也就是说,把观测次数减去期望次数,再除以标准差,得到的结果近似服从标准正态分布。

在我们做卡方检验的典型场景里,当样本量不小、期望频数不太低时,这个近似效果是可以接受的。于是,每个组别内部的偏差,经过标准化处理后,都可以近似看成一个标准正态分布的取值。这个结论是整个卡方分布公式的出发点。

2.2 标准正态分布平方的性质:卡方分布的诞生

现在的问题很自然:每个组的标准化偏差都近似是标准正态分布,但我们最后要把所有组的贡献加起来,得到的是一个总体的“汇总统计量”。把几个标准正态分布的变量加起来,得到的是什么分布?

答案不是正态分布,而是一个新分布。统计学家卡尔·皮尔逊早在1900年左右就研究清楚了这个问题。他发现,如果一个随机变量Z服从标准正态分布,那么Z²服从自由度为1的卡方分布,记为χ²(1)。它的概率密度函数是: [ f(x) = \frac{1}{\sqrt{2\pi}} x^{-1/2} e^{-x/2}, \quad x > 0 ] 这个分布只有一个参数,就是自由度1。

更一般地,如果有k个相互独立的标准正态变量Z₁, Z₂, ..., Zₖ,那么它们的平方和Z₁² + Z₂² + ... + Zₖ²服从自由度为k的卡方分布χ²(k)。这个东西在直觉上非常漂亮:一个正态变量的平方,是一个“偏态”的分布;两个正态变量的平方和,分布形态会有所改变;随着自由度的增加,卡方分布逐渐趋向于对称,并最终逼近正态分布。

所以,卡方检验在数学层面做的事情,其实非常简洁纯粹:把观测偏差标准化成若干个近似标准正态分布的变量,然后取平方和,用卡方分布作为这个平方和的理论分布,最后在原假设下计算“出现当前偏差或更大偏差的概率”。这个概率就是我们熟悉的p值。

2.3 为什么是平方而不是绝对值

你现在可能想问:既然标准正态变量的平方服从卡方分布,那如果我取的是绝对值,会不会得到一个“绝对值正态分布”?确实有这样一个分布,叫“半正态分布”或“折叠正态分布”,但在卡方检验的语境里,平方有不可替代的优势。

第一,平方在数学上更好处理。卡方分布有完整的概率表、累积分布函数和数值算法,做显著性检验非常方便。绝对值的分布虽然也能算,但涉及的处理复杂度更高,而且检验统计量的构造不像平方和这么自然。

第二,平方天然放大了大偏差的权重。在统计推断里,极端偏差往往比小偏差携带更多“反对原假设”的信息。用平方的方式,偏差为2的项贡献4,偏差为3的项贡献9,差异将被显著放大。这样统计量对“局部严重偏离”更敏感,检验的功效也更好。

第三,从数学推导的角度看,正态分布平方和的分布可以精确推导出来,而绝对值和的分布则很难和正态分布建立起优雅的联系。皮尔逊之所以选择平方,正是因为他看到了二项分布逼近正态分布后,平方和有着极其简练的理论支撑。

2.4 自由度的门道:平方和为什么需要打折

自由度的概念,是理解卡方检验最容易被卡住的地方。很多时候,你算了一大堆组的平方和,但实际能“自由变化”的组数并没有那么多。举个例子,一个2×2列联表,有4个格子,但行合计和列合计都是固定的,所以一旦其中1个格子的频数确定,其他3个格子就被迫确定了。真正自由的格子数是(2-1)×(2-1)=1。

为什么自由度会影响检验结论?因为自由度越大,卡方分布越“往右移”,同样大小的统计量对应的p值会变大。如果你错误地使用了过大的自由度,p值会被虚高,本来显著的差异可能会变成不显著;反之,如果低估了自由度,p值会偏小,容易得到假阳性的结论。自由度是卡方检验里最容易出错、也最需要仔细核对的一个参数。

回到正态分布的平方和视角,自由度k的本质是:这k个标准正态变量中,真正独立的有多少个。如果变量之间存在线性约束,那么平方和的“有效项数”就会减少,自由度也要随之缩减。这一点在后面推导实际卡方统计量时会体现得非常明显。

3. 卡方统计量的完整推导:从零开始拼出那个公式

3.1 一种朴素但不完全正确的构造方式

我们先来看一种最自然的构造方式。假设我们要检验一个分类变量是否符合某种理论分布,共有m个类别,每个类别的期望频数为Ei,观测频数为Oi。如果每组都是独立的二项分布,且期望频数足够大,那么: [ \frac{O_i - E_i}{\sqrt{E_i}} \approx N(0, 1) ] 注意这里默认了一个条件:当原假设成立时,二项分布的方差np(1-p)约等于np,即当p很小时。但在卡方检验的实际应用中,p不一定很小,所以这个近似的细节是需要仔细讨论的。

如果我们简单地认为上述标准化偏差服从标准正态分布,那把所有组的平方加起来: [ \sum_{i=1}^{m} \frac{(O_i - E_i)^2}{E_i} ] 从表面上看,这应该服从自由度为m的卡方分布。但这个结论有一个漏洞:各组之间并不是互相独立的。因为观测频数之和是固定的,总和等于样本量n,所以给定前m-1个组的值,最后一组就自动确定了。这意味着自由度不是m,而是m-1。

3.2 线性约束下的自由度收缩

这里我们遇到了卡方检验中最精妙、也最容易忽略的一步:平方和对应的“有效维度”会因为线性约束而收缩。我们把所有标准化偏差看成是m个近似正态分布的变量,它们之间有一个线性关系: [ \sum_{i=1}^{m} (O_i - E_i) = 0 ] 即所有组的观测频数之和等于期望频数之和。这个等式不是一个近似,而是精确成立的,因为期望频数本身就是按“总和相同”这个条件算出来的。

一个含有m个变量、受到1个线性约束的系统,实际维度是m-1。所以这m个变量的平方和,并不服从自由度为m的卡方分布,而是服从自由度为m-1的卡方分布。这就是为什么拟合优度检验的自由度计算是“分类数减1”。

在列联表里,情况更复杂一点。一个r行c列的表,在行列合计都给定的情况下,自由度为(r-1)(c-1)。这个公式很多书上直接给出来,但很少有人解释为什么。实际上,它是根据“行合计约束 + 列合计约束”共同推导出来的:整体有rc个格子,行合计有r个约束,列合计有c个约束,但行合计的总和等于列合计的总和(都等于总样本量n),所以有效约束不重复计数,自由度 = rc - r - c + 1 = (r-1)(c-1)。

3.3 各组的近似独立性与“期望频数不低于5”这个规则

前面推导过程中,我们默认各组之间的标准化偏差近似独立。严格来说,它们并不完全独立,因为它们共享一个线性约束。当分类数m很大、每个类别的期望频数都足够大时,这种“近似独立性”的效果是可以接受的,自由度修正到了m-1就已经足够精确。

那为什么老教材上总说“期望频数不能低于5”?这其实不是卡方分布本身的要求,而是正态近似是否可靠的要求。二项分布用正态分布近似,在np和n(1-p)都不小于5时效果较好;对应到每个组的期望频数Ei,就变成了“所有期望频数都不宜小于5”。如果你的表里出现了期望频数小于5的格子,卡方统计量就不再精确服从χ²分布,检验结论可能失真。

但“不低于5”并非铁律。近些年的统计研究普遍认为,对于较大的列联表,允许20%左右的格子期望频数在1到5之间,只要没有期望频数为0的格子即可。不过作为日常实操,稳妥起见,优先保证每个格子期望频数不低于5仍然是最安全的选择。

3.4 从2×2列联表看公式的落地

我们用一个最常见的2×2列联表来感受一下公式的实际使用。假设你想研究“性别”和“是否愿意尝试某种新产品”之间有没有关系。收集了100个人的数据:

  • 男性愿意:30人,男性不愿意:10人
  • 女性愿意:45人,女性不愿意:15人

先算期望频数。行合计:男性40人,女性60人;列合计:愿意75人,不愿意25人;总样本100。在“性别与意愿无关”的原假设下,男性的期望愿意人数 = 40 × 75 / 100 = 30,这个例子正好和观测一致。其他格子的期望值也按同样方式计算。

如果逐项计算每个格子的(Oi - Ei)²/Ei,再累加得到T值,然后比较T和自由度为1的卡方分布临界值,就能得出显著性判断。这个表里期望频数都远大于5,用卡方分布来做近似是相当稳妥的。

需要特意提一句:2×2列联表的自由度只是1,卡方分布非常偏态,临界值也不同于大自由度的情况。如果整体样本量很小,比如总人数只有30,这时使用卡方检验容易出错,最好改用Fisher精确检验。

4. 实操环节:手把手跑一次卡方检验

4.1 用Python做拟合优度检验

拟合优度检验的典型场景是检验一组样本是否符合某个理论分布。比如,你怀疑某平台用户的设备类型分布跟行业报告不一致,想做个验证。行业报告说设备占比是:iOS 50%,Android 45%,其他5%。你采集了200个用户样本,实际观测:iOS 104,Android 86,其他10。

在Python里,用scipy库可以快速完成检验:

import numpy as np from scipy import stats # 观测频数 observed = np.array([104, 86, 10]) # 期望比例 expected_prop = np.array([0.50, 0.45, 0.05]) # 期望频数 expected = expected_prop * observed.sum() # 卡方检验 chi2_stat, p_value = stats.chisquare(f_obs=observed, f_exp=expected) print(f"卡方统计量: {chi2_stat:.4f}") print(f"p值: {p_value:.4f}") print(f"自由度: {len(observed) - 1}")

跑出来的结果里,自由度是2,即组数3减1。这里因为总样本量是固定的200,所以有一个线性约束,自由度必须减1。很多初学者会在这一步犯错,直接把自由度填成3。scipy的chisquare函数默认不会帮你减自由度,需要自己传入或者手动计算。

4.2 用Python做列联表独立性检验

接下来是列联表场景。延续前面“性别×意愿”的例子,把数据整理成二维数组:

import numpy as np from scipy import stats # 2x2列联表 table = np.array([[30, 10], [45, 15]]) chi2_stat, p_value, dof, expected = stats.chi2_contingency(table, correction=False) print(f"卡方统计量: {chi2_stat:.4f}") print(f"p值: {p_value:.4f}") print(f"自由度: {dof}") print("期望频数表:") print(expected)

注意,这里我给correction参数传了False。为什么?因为Python里的chi2_contingency函数默认开启了Yates连续性校正。关于这个校正,后面我会单独讲清楚什么时候该用、什么时候不该用。如果你直接用默认参数,得到的结果和我这里会略有差异。

运行代码后,可得到自由度是1,这与(r-1)(c-1)的计算结果一致。如果你的表比较大,比如3行4列,自由度自动变成(3-1)×(4-1)=6。期望频数矩阵也会由函数直接输出,可以直观检查是否出现期望频数过小的问题。

4.3 手动计算:用Excel或手算验证一遍

不管用什么工具,我建议每个人都手动算一遍小例子,这样对公式的理解才会扎实。继续用性别和意愿的那个2×2列联表:

第一步,算期望频数。男性愿意格的期望值是40×75/100=30,男性不愿意格是40×25/100=10,女性愿意格是60×75/100=45,女性不愿意格是60×25/100=15。

第二步,逐项计算贡献:

  • 男性愿意:(30-30)²/30 = 0
  • 男性不愿意:(10-10)²/10 = 0
  • 女性愿意:(45-45)²/45 = 0
  • 女性不愿意:(15-15)²/15 = 0

这份数据里,观测值和期望值完全一致,卡方统计量为0,p值为1。说明性别和意愿之间没有观察到任何关联。现实中会得到统计量为0的数据非常罕见,大多数场景下你都会得到一些非零的卡方值。

自己手动算一次的好处是,你会真切感受到“标准化偏差”是怎么工作的。你也会发现,当某个格子的期望频数很小时,分母很小,哪怕观测值只是稍微偏离,就会产生非常大的单项贡献。这也是为什么期望频数过小时,卡方检验会变得不稳定。

5. 常见问题排查与实战心得

5.1 期望频数太小怎么办

这是卡方检验里被问得最多的问题。前面提到了“期望频数不低于5”的传统规则,但在实际数据处理中,特别是列联表格子比较多的时候,很难保证所有格子的期望频数都大于5。

处理方式有这么几种:合并类别是最常用的手段,把期望频数过低的相邻类别合并起来,增大期望频数;扩大样本量是最根本的解法,但很多时候受限于成本,做不到;Fisher精确检验则是2×2表的通用替代方案,它不依赖正态近似的假定,在小样本下更可靠;还有一个思路是使用似然比检验(G检验),它和卡方检验一样基于渐近理论,但在某些场景下表现更好。

我的经验是:当表格只有两行两列且样本量小于40时,优先考虑Fisher精确检验;当表格较大、只有少数格子期望频数略低于5时,可以继续使用卡方检验,但要在报告里注明这个情况。如果出现了期望频数小于1的格子,那就必须处理了,没有商量余地。

5.2 Yates连续性校正到底该不该开

说到Yates连续性校正,这是很多人在使用统计软件时最容易感到困惑的一个选项。Yates校正的核心思路是:因为离散分布用连续分布近似,存在系统性偏差,所以在计算卡方统计量时,把每个偏差的绝对值减去0.5之后再平方。这个0.5叫“连续性校正项”。

问题是,到底该不该用?统计学界对这个争论已经很长时间了。传统的观点认为,小样本下应该用校正,否则容易犯第一类错误(错误地拒绝原假设);现代有相当一部分统计学家认为,Yates校正过于保守,会降低检验功效,增加第二类错误的风险。

我的实践建议是:在2×2表中使用卡方检验时,如果样本量不大(比如总样本量小于40),直接上Fisher精确检验,别纠结校正不校正;如果样本量足够大(总样本量大于100),校正与否对结果影响不大,两种方法都可以;只有在中间地带(样本量40到100之间)时,我会倾向于报告未校正的卡方值和Fisher精确检验的p值,两者结合起来看结论是否一致。

5.3 多组比较时的两两检验问题

当我们处理的是r×c列联表,而且检验结果显著时,不少人会直接做两两比较,试图找出具体是哪几组之间存在显著差异。这个操作有一个大坑:多重比较会增加第一类错误。比如你有5个组,两两配对要做10次检验,每次检验的第一类错误率是0.05,那么出现至少一次假阳性的概率约为1-(1-0.05)^10 ≈ 0.4,远高于0.05。

处理方式有两种。一是用Bonferroni校正,把显著性水平除以比较次数,比如10次比较就把0.05降到0.005,好处是简单粗暴,缺点是过于保守;二是使用更精细的方法,比如Tukey-type多重比较,或基于拟合后残差的标准化检验。后者能告诉你哪个格子的残差显著偏离期望,更有针对性。

从操作上看,我更推荐第二种方式。在卡方检验显著后,计算每个格子的标准化残差: [ r_{ij} = \frac{O_{ij} - E_{ij}}{\sqrt{E_{ij}(1 - r_i/n)(1 - c_j/n)}} ] 标准化残差的绝对值大于2的格子,通常可以认为是对显著结果贡献比较大的格子。这个方法比盲目做两两卡方检验更合理,也更容易解释结论。

5.4 卡方检验的适用边界:什么时候该换方法

卡方检验虽然好用,但不是万能的。当变量是数值型且能区分等级时,比如“满意度评分1到10分”,卡方检验把数据按类别处理,会损失很多信息,这时更适合使用秩和检验或其他参数检验方法。

当样本量极大时,卡方检验几乎总会显著,因为现实数据很难和理论分布完美吻合。大样本下微小偏差也会被检测出来,这会误导你的业务判断。这时要做的不只是显著性检验,还要看效应量,比如Cramér's V,判断偏差的实际大小是否有业务意义。

当数据之间存在嵌套、分组结构时,比如学生嵌套在学校里,或者多次测量来自同一个对象,卡方检验的“样本独立”假设被违反,需要改用广义估计方程或混合效应模型。卡方值在这种场景下会被低估或高估,结论不可靠。

做个简单的决策参考:

场景建议方法
2×2列联表、小样本Fisher精确检验
2×2列联表、大样本卡方检验或Fisher,两者接近
r×c列联表、期望频数全部≥5卡方检验
部分期望频数在1~5之间合并类别或保留卡方但注明
期望频数有0必须先合并类别或调整分组
有序分类数据的趋势检验线性趋势卡方或秩相关方法
配对设计分类数据McNemar检验

这张表是我在实际处理数据时总结出来的,不一定适用于所有学科领域,但大部分场景都能覆盖。统计方法的选用没有放之四海皆准的套路,理解方法背后的假设,才能做出合理的判断。

6. 写在最后的一点体会

把卡方检验推到“正态分布平方和”这一步,对我自己理解统计学有非常大的帮助。以前用卡方检验,纯粹是机械地看p值小于0.05就说“显著”;现在会更自然地追问一句:这个检验背后的近似条件是否满足?样本量够不够?期望频数有没有过低的格子?自由度算对了吗?这些问题看起来繁琐,但恰恰是它们区分了一个人是在“用统计”还是“套统计”。

还有个小技巧,我每次做卡方检验前都会把期望频数矩阵先打印出来看一眼。这个习惯帮我避免过很多次因为期望频数过低导致的错误结论。数据在你手里不只是一组数字,它背后有生成过程,有抽样噪声,也有真实的业务信号。卡方检验就像一个过滤器,帮你判断观察到的差异是噪声还是信号。而这个过滤器能够成立的基石,正是正态分布平方和这个看似抽象的数学事实。理解了这个底层逻辑,再回头看那些曾经靠硬背的公式和规则,一切都顺理成章了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询