LionKing数据科学专栏

购买普通会员高级会员可以解锁网站精华内容且享受VIP服务的优惠

想要查看更多数据科学相关的内容请关注我们的微信公众号知乎专栏

卡方检验($\chi^2$ test)

卡方检验的应用

卡方分布可以解决两类问题:

  1. 拟合度检验:假设有$n$个样本被分入$K$个类别$C_1, \ldots, C_K$,想要检验这$K$个类别的概率是否为$p_1, \ldots, p_K$。
  2. 独立性检验:假设有两种事件$A$和$B$,其中$A$的可能结果为$A_1, \ldots, A_{K_1}$,$B$的可能结果为$B_1, \ldots, B_{K_2}$,现在观测了$n$个样本属于$A$中的哪一类和$B$中的哪一类,现要检验一个样本属于$A$中的哪一类和属于$B$中的哪一类是否独立。

拟合度检验的一个常见应用是业界中为了做A/B测试将用户随机地分成若干组,希望尽可能地均匀。可以使用拟合度检验检验$C_1, \ldots, C_K$的概率是否均为$\frac{1}{K}$。

独立性检验的一个常见应用是A/B测试中对于类别型变量的分析。假设旧版产品和新版产品都有$K$个链接可以点击,我们想要检验用户点击各个链接的概率是否依赖于该用户使用的产品版本,那么可以考虑$A$:用户使用的产品版本和$B$:哪一个链接被点击,进行$A$和$B$的独立性检验。

卡方分布

若$Y_1, \ldots, Y_k$是独立的标准正态变量,则它们的平方和$$X = \sum_{i=1}^{k}Y_i^2$$服从自由度(degrees of freedom)为$k$的卡方分布,记作$X \sim \chi^2_k$。

拟合度检验(test of goodness of fit)

假设$n$个样本被分入$K$个类别$C_1, \ldots, C_K$,其中每个类别的样本个数分别为$O_1, \ldots, O_K$。希望检验每个类别的概率是否为$p_1, \ldots, p_K$,其中$p_1 + \ldots + p_K = 1$。

若零假设成立,则$O_i$是$n$个样本被分到第$i$类的个数。由于每个样本分到$C_i$的概率均为$p_i$且相互独立,$O_i \sim Bin(n, p_i)$

根据中心极限定理(Central Limit Theorem),$\frac{O_i - np_i}{\sqrt{np_i(1 - p_i)}} \approx N(0, 1)$。

因此,$\frac{O_i - np_i}{\sqrt{np_i}} \approx N(0, 1) \Rightarrow \sum_{i=1}^{K}\left(\frac{O_i - np_i}{\sqrt{np_i}}\right)^2 = \sum_{i=1}^{K}\frac{(O_i - np_i)^2}{np_i} \approx \chi^2_K$。

由于这些变量并非两两独立,而是满足$\sum_{i=1}^{K}O_i = n$,因此需要减小一个自由度:

$$T = \sum_{i=1}^{K}\frac{(O_i - np_i)^2}{np_i}$$近似服从$\chi^2_{K - 1}$。

$\mathbb{E}[O_i] = np_i \triangleq E_i$为期望的类别$i$的个数,$O_i$为观测的类别$i$的个数,卡方拟合度检验可以写作

$$T = \sum_{i=1}^{K}\frac{(O_i - E_i)^2}{E_i} \approx \chi^2_{K - 1}$$对于较大的$n$成立。

严谨的推导需要较复杂的数学知识,这里证明$\mathbb{E}[T] = K - 1$。

需要购买普通会员高级会员登录后刷新该页面查看

我们在$T$大于卡方分布的$1 - \alpha$分位数时拒绝零假设,即认为$p_1, \ldots, p_K$不是各个类别的概率。

独立性检验(test of independence)

假设有$A$有$A_1, \ldots, A_{K_1}$这些可能结果,$B$有$B_1, \ldots, B_{K_2}$这些可能结果。

$n$个样本中,出现$A_i$和$B_j$的有$N_{i, j}$个。则$$n = \sum_{i=1}^{K_1}\sum_{j=1}^{K_2}N_{i, j}$$

$A_i$的出现概率估计为$p_i = \frac{\sum_{j=1}^{K_2}N_{i, j}}{n}$,$B_j$的出现概率估计为$q_j = \frac{\sum_{i=1}^{K_1}N_{i, j}}{n}$。

假设两者独立,则同时出现$A_i$和$B_j$的概率为$p_iq_j$,因此期望同时出现$A_i$和$B_j$的样本个数为$E_{i, j} = np_iq_j$。

考虑统计量$$T = \sum_{i=1}^{K_1}\sum_{j=1}^{K_2}\frac{(O_{i, j} - E_{i, j})^2}{E_{i, j}}$$

在$n$足够大时,$T$近似服从自由度为$(K_1 - 1)(K_2 - 1)$的卡方分布。

我们在$T$大于卡方分布的$1 - \alpha$分位数时拒绝零假设,即认为$A$和$B$不独立。

Python实现

在Python中,我们通过scipy包很容易可以进行卡方检验。

对于拟合检验,我们考虑检验一个六个面的骰子是否各个面均匀。

from scipy import stats
import numpy as np

# 生成数据
np.random.seed(10)
n = 10000
K = 6
Os = np.zeros(K, dtype=int)
for i in range(n):
    k = np.random.randint(0, K)
    Os[k] += 1
    Es = np.ones(K) / K * n

# 检验观测是否吻合骰子均匀
p_val = stats.chisquare(Os, Es).pvalue
print('p值为%.4f' % (p_val, ))
        
输出:

p值为0.0927
	

输出的p值为0.0927 > 0.05,因此我们不拒绝骰子均匀的零假设。

对于独立性检验,我们检验两个六个面的骰子是否独立。

from scipy import stats
import numpy as np

# 生成数据
np.random.seed(10)
n = 10000
K_1 = 6
K_2 = 6
Os = np.zeros((K_1, K_2), dtype=int)
for i in range(n):
    k_1 = np.random.randint(0, K_1)
    k_2 = np.random.randint(0, K_2)
    Os[k_1][k_2] += 1

# 检验观测两个骰子是否独立
T, p_val, dof, Es = stats.chi2_contingency(Os, correction=False)
print('p值为%.4f' % (p_val, ))
print('自由度为%d' % (dof, ))
        
输出:

p值为0.3413
自由度为25
	

p值为0.3413 > 0.05,因此不拒绝两个骰子独立的零假设。

   

更多练习题请见假设检验练习题

更多关于假设检验的讨论见本网站论坛的假设检验版面

更多面试问题见面试真题汇总

想要查看更多数据科学相关的内容请关注我们的微信公众号知乎专栏