卡方检验主要用来对总体方差进行检验以及对分类数据的频数进行分析的统计方法,在讲卡方检验前,我们先看一下卡方分布的概念以及特点。
设随机变量X1,X2,...,Xn相互独立,且Xi(i=1,2,...n)服从标准正太分布N(0,1),则他们的平方和服从自由度为n的
分布。
卡方分布具有以下特点:
1. 分布的数学期望为:
2. 分布的方差为:
3. 分布还具有可加性,即若
,
,且独立,则
卡方分布示意图:
下面是生成两个变量rvs1,rvs2并且服从标准正太分布,再求出平方和x2,通过直方图显示x2,可以看到整体分布服从卡方分布。
from scipy import stats
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sbn
np.random.seed(123)
rvs1 = stats.norm.rvs(loc=0,scale=1,size=100)
rvs2 = stats.norm.rvs(loc=0,scale=1,size=100)
x2 = rvs1*rvs1+rvs2*rvs2
fig = plt.figure(1)
plt.clf()
sbn.histplot(x2 ,color='r',bins=10,kde=True)
fig.savefig('mlp_pictures/fig.png')
总体方差检验:
上个章节我们讲了t检验,t检验主要是检验总体的均值,这节主要讲卡方检验,卡方检验主要检验总体方差。例如,在质量检验中,质量标准可以通过不同的标准来衡量,有些属于均值标准,如质量、尺寸、强度等。有些属于方差标准,如尺寸的方差、质量的方差、强度的方差,方差可以反应质量的稳定性,方差越大说明质量波动越大,方差越小说明质量比较稳定。
对方差进行检验与对均值进行检验一样,区别主要是所使用的统计量不同,方差检验所使用的是卡方统计量,对一个方差为σ2的正太总体反复抽样,每次抽样的样本方差为s2,可以得到下面的公式:
通过公式推导证明,s2除以σ2将服从分布,即
例子:某厂商生产出一批鞋子,按照设计要求,厂商生产鞋子27cm的误差上下不超过1cm,如果达到设计要求,表明机器的稳定性非常好。现从该机器生产的鞋子中挑选出25双,分别进行测定(用样本测量值减去27cm),得到下面的结果:
试以a=0.05的显著性水平检验该机器的性能是否达到设计要求。
H0:σ2<=1
H1: σ2>1
由上图的样本数据可以算出s2=0.8409,故
查卡方分布表可知,,故不能拒绝原假设H0,可以认为该机器的性能达到设计要求。
卡方检验应用:
统计数据类型有分类数据(定类)、顺序数据和数值型(定量)数据。分类数据是对事物进行分类的结果,虽然用数值表示,但不同的数值表示不同的意思,例如研究新药对病人治疗疗效的关系,药就是一个分类数据,可以分为“新药”和“老药”,比如1代表新药,2代表老药,疗效可以分为“有效”和“无效”,1代表有效,2代表无效。这类问题是在汇总数据的基础上进行分析的,数据汇总的结果表现为频数。
因为检验可以用来对分类数据的频数进行分析统计,因此
可以用于测定两个分类变量之间的相关程度,用fa表示实际频数,ft表示理论频数,则
统计量可以写成:
例子,为了解新药对糖尿病的疗效,将90名糖尿病患者随机分为两组,实验组用新药治疗,对照组用老药治疗,下图是观察的结果。
建立假设:
H0:实验组与对照组总体有效率相等。
H1:实验组与对照组总体有效率不等。
上图的a,b,c,d分别是统计的实际频数(fa,b,c,d),现在根据公式求得理论频数ft。
ft11=(38*60)/90=25.33,我们知道总共有效数量是60,用60/90得到有效概率,再乘以对照组38,得到对照组理论有效频数。
ft12=(38*30)/90=12.66,我们知道总共无效数量是30,用30/90得到无效概率,再乘以对照组38,得到对照组理论无效频数。
ft21=(52*60)/90=34.66,我们知道总共有效数量是60,用60/90得到有效概率,再乘以实验组52,得到实验组理论有效频数。
ft22=(52*30)/90=17.33,我们知道总共无效数量是30,用30/90得到无效概率,再乘以实验组52,得到实验组理论无效频数。
自由度v=(行数2-1)*(列数2-1)=(2-1)(2-1)=1。自由度1,X20.05=3.84, 11.03>3.84, P<0.05,拒绝H0。
到目前为止,我们学习了T检验,卡方检验,方差后面会讲到。这里就先列出他们的不同点和相同点,如下图所示,当X组别等于2组时,方差检验和T检验可以相互替代。
测试代码:
import pandas as pd
import numpy as np
from scipy import stats
observe=np.array([18,20,42,10])
expect=np.array([25.33,12.66,34.66,17.33])
chi_squared_stat = ((observe-expect)**2/expect).sum()
print(chi_squared_stat)
crit = stats.chi2.ppf(q=0.95,df=1)
print(crit)
P_value = 1-stats.chi2.cdf(x=chi_squared_stat,df=1)
print(P_value)