目录
老饼讲解:一步一步上手学习

【介绍】卡方检验之-独立性检验

作者 : 老饼 发表日期 : 2025-12-31 13:28:10 更新日期 : 2026-05-11 22:32:08
老饼讲解-简单易懂,干货满满,爽过嗦螺!


卡方独立检验是卡方检验(chi-square Test)的一种,它属于一种用来检验两组数据的分布差异是否显著的假设检验,在机器学习中一般用来检验变量的相关性,例如男、女两组身高数据的分布如果差异大,则说明性别对身高有影响。好了,下面我们就来详细说说卡方独立检验的原理、流程和代码实现。

一、卡方独立检验

卡方检验包括独立检验和拟合性检验,它们都是基于卡方值的检验方法,但是它们用于解决不同的问题。卡方拟合性检验可参考文章《卡方检验-拟合性检验》,今天我们只说卡方独立检验。

1.1. 卡方独立检验-解决什么问题

卡方-独立检验解决的问题如下:

卡方独立检验-解决什么问题

事件发生有n种可能: ,A组 和 B组在   上的分布现在表现出来的分别是:

 、  

我们想知道A组与B组在取值分布上有没有区别。

1.2. 卡方独立检验-思想与流程

我们先来看看卡方-独立检验的思路与流程,后面再来详细说它的具体操作。

卡方-独立检验的思路与流程如下:

卡方独立检验-思想与流程

一、假设没区别,算出期望值

      卡方检验先假设A组与B组没有区别,在这假设下,算出A组与B组的期望值。

二、计算期望值与事实值差异的概率

      计算事实值与期望值的差异(该差异构造成服从卡方分布)。

      由于差异值服从卡方分布,所以可进一步计算出差异值出现的概率。

三、根据概率,确定假设成不成立

      根据差异值出现的概率,从而确定假设合不合理。

      如果概率很小,说明当前是个小概率事件,则假设不合理,即A组与B组没有区别。

二、卡方独立检验-计算流程

好了,下面我们先来说说卡方独立检验的计算流程和步骤,后面再来说这些公式怎么得出来的。

我们先来认识一下事实表,事实表是指各组当前观察到的取值,它的格式如下:

事实表-A

一般将事实表记为A,然后现在要判断A中的组1与组2有没有区别。

2.1. 卡方独立检验-计算流程

好了,下面我们来看看卡方独立检验的详细步骤。

首先假设两组没有区别,然后计算"没有区别"的概率,如下:

Step-1:计算期望表

期望表 E 的计算公式为:

  

其中,为A第i行求和,为A第j列求和,为总样本数。

Step-2:计算卡方值

卡方值计算公式为:

    

Step-3:计算p值

p值如下计算:

  

其中,  :自由度,, r为A的行数,c为A列数

           :自由度df的卡方累积分布函数

备注:卡方累积分布函数一般由计算机或查表得到,没有显式公式。

得到p值后,进行判断就可以了,如果概率很小,就拒绝"没有区别"的假设,否则接受假设。

2.2. 卡方独立检验-计算实例-解说

好了,下面我们用一个实例,来更具体的看看卡方独立检验的检验过程。

设现在有男女两组身高的分布,如下:

 男女两组身高的分布

现问性别对身高有没有影响,那么先假设"男女两组的身高没有区别",然后计算它的概率,如下:

Step-1:计算期望表

1. 在计算期望表前,先对事实表进行行列汇总,如下:

 事实表进行行列汇总结果

2. 使用公式  计算期望表, 可得到结果:

 期望表的计算

即:

 期望表计算结果

Step-2:计算卡方值

根据公式计算卡方值,如下:

                  

这里的卡方值,就是事实与期望差异的度量。

Step-3:计算p值

1. 计算自由度

    根据公式计算自由度

               

2. 计算p值

    由   服从自由度为 2 的卡方分布,即可知

              

    其中,  是自由度为2的卡方累积分布函数

    使用 python的scipy.stats.chi2.cdf进行计算卡方值, 现  , 自由度  , 则代码如下:

 卡方值计算结果

即可得到:p = 0.17728440996987782。

一般p<0.05时我们会拒绝"没有区别"的假设,而这里p = 0.177,所以我们接受假设,也就是两组没有区别。

三、卡方独立检验-公式推导

在上面的卡方独立检验中计算过程中,期望表、卡方值与p值的计算都使用了公式,下面我们就来说说这些计算公式是怎么推导出来的。

3.1. 卡方独立检验-期望表的计算公式推导

先来说说期望表的计算公式是怎么推导出来的,设事实表A与它的汇总数据如下所示:

事实表A

其中,是第i行求和,是第列求和,是总和

如果组1、组2没有区别,那么它们的分布的期望应该与总体保持一致,所以组1、组2在各个取值上的分布占比,此时都应该为:

  

由于组1的总样本数为,故组1的期望取值为:

 

同理,组2的总样本数为,组2的期望取值为:

 

通过观察就可以得到,期望表的取值为:


3.2. 卡方独立检验-卡方值与p值的公式解说

好了,下面再来说说卡方值与p值的公式是怎么一回事。

由于每一个事实值都与期望值有所差异,不妨用  ​ 来量化这个差异,则总的差异为:

 

设  是服从正态分布的随机变量,则由统计学知识可知: 是服从标准正态分布的随机变量,从而服从自由度为的卡方分布。因此,差异的概率为:

  

其中, 是自由度为的卡分累积分布函数

这样就得到了在"组1、组2没区别"的假设下,样本出现当前差异的概率,如果概率过小,则拒绝假设,认为组1、组2存在区别,即p越小,代表两组别的分布区别越大。

四、卡方独立检验-代码实现

下面我们先通过scipy的函数来做卡方独立检验,然后再自己按公式来自实现卡方独立检验。

4.1. 用scipy计算-卡方独立检验

在python中要实现卡方独立检验,可以直接调用scipy的chi2_contingency函数,具体代码如下:

'''
本代码用于展示如何使用scipy来计算卡方独立检验
本代码来自《老饼讲解-机器学习》www.bbblearn.com
'''
import numpy as np
import scipy
A = np.array([[8,11,1],[3,18,9]])                               # 事实表,包含两个组别在3个类别上的样本数
chi2_value,p_value,free_n,ex = scipy.stats.chi2_contingency(A)  # 调用scipy的函数计算卡方值与P值
print('\n卡方值chi2 =',chi2_value,',p =',p_value)               # 打印卡方值与P值

代码运行结果如下:

卡方独立检验结果

从以上结果可以看到,p值相对较小,如果置信水平设为0.05,由于p<0.05,所以拒绝假设,认为两个组别存在区别。

4.2. 自实现-卡方独立检验

好了,为了加深对卡方独立检验的理解,我们不妨自己实现一下卡方独立检验,这也是很简单的,只需按照上面所说的步骤进行实现就可以了,具体代码如下:

'''
本代码用于展示如何自实现卡方独立检验
本代码来自《老饼讲解-机器学习》www.bbblearn.com
'''
import numpy as np
import scipy
def cal_chi2(pair):
    pair[pair==0]  = 1                                                     # 避免为0,将0置1
    class_rate     = pair.sum(axis=1)/pair.sum().sum()                     # 两类样本的占比
    col_sum        = pair.sum(axis=0)                                      # 各组别的样本个数
    ex             = np.dot(np.array([class_rate]).T,np.array([col_sum]))  # 计算期望值
    chi2           = (((pair - ex)**2/ex)).sum()                           # 计算卡方值
    df = (pair.shape[0]-1)*(pair.shape[1]-1)                               # 计算自由度
    p = 1-scipy.stats.chi2.cdf(df=df, x=chi2)                              # 计算p值
    return chi2,p                                                          # 返回卡方值与p值

# 调用自实现函数计算卡方值与P值
A = np.array([[8,11,1],[3,18,9]])                                          # 事实表:两组别在3个类别上的样本数
chi2,p = cal_chi2(A)                                                       # 调用自实现函数计算卡方值与P值
print('卡方值chi2 =',chi2,',p =',p)                                        # 打印卡方值与P值

代码运行结果如下:

自己计算的卡方独立检验结果

可以看到,自写代码计算的卡方值与scipy的函数计算结果是一致的。

总结

卡方独立检验的用途就是检验两个组别的分布是否有没有区别,也就是两组数据是否来自同一分布。它主要先假设没有区别,然后计算出"没有区别"时的期望与事实值的差异出现的概率,如果概率过小,说明"没有区别"是小概率事件,则拒绝假设,否则接受假设。



图标 评论
添加评论