分类型数据也称为频数数据。在数据样本中,落入某一个特定分组的样本数量为频数。
单因素频数表:当分组的维度只有1(图一);
列联表数据:分组的维度为2(图二)。
分类型数据的检验有很多:卡方检验、Fisher检验、McNermr检验、Cochran’s Q检验等等。其中,卡方检验与Fisher检验是分类数据检验中最常见的检验。在正式学习对分类数据进行假设检验时,先来了解一下卡方检验与Fisher检验(尤其是卡方检验)的作用与原理。
卡方检验与Fisher检验都是分析频数表中绝对频数与期望频数的偏差程度,对于它们而言,检验的两个假设分别为
H
0
:
绝对频数与期望频数没有差别
↔
H
1
:
绝对频数与期望频数存在差别
H_0:\text{绝对频数与期望频数没有差别}\leftrightarrow H_1:\,\text{绝对频数与期望频数存在差别}
H0:绝对频数与期望频数没有差别↔H1:绝对频数与期望频数存在差别
那么,绝对频数和期望频数是什么呢?
如果绝对频数与期望频数的差值越小,则两者越接近,我们越不能拒绝原假设。基于此,卡方检验构造了下述检验统计量:
T
e
s
t
s
t
a
t
i
s
t
i
c
s
=
∑
i
(
o
i
−
e
i
)
2
e
i
Test\,\,statistics=\sum_i{\frac{\left( o_i-e_i \right) ^2}{e_i}}
Teststatistics=i∑ei(oi−ei)2
而该统计量近似服从卡方分布(在大样本下):
T
e
s
t
s
t
a
t
i
s
t
i
c
s
∼
χ
f
2
Test\,\,statistics\sim \chi _{f}^{2}
Teststatistics∼χf2
其中,
f
f
f为自由度。对于有n个格子的单因素频数表而言,
f
=
n
−
1
f=n-1
f=n−1;对于
r
×
c
r\times c
r×c的双因素列联表而言,
f
=
(
r
−
1
)
(
c
−
1
)
f=\left( r-1 \right) \left( c-1 \right)
f=(r−1)(c−1)
p值计算规则为:
p
v
a
l
u
e
=
P
(
χ
f
2
>
T
e
s
t
s
t
a
t
i
s
t
i
c
s
)
pvalue=P\left( \chi _{f}^{2}>Test\,\,statistics \right)
pvalue=P(χf2>Teststatistics)
注意:卡方检验中的检验统计量是近似服从而非精确服从卡方分布,只有在大样本下(绝对频数与期望频数都很大)的情况下,卡方检验的精确度才高,而在小样本下,卡方检验的效用不及Fisher检验。相比于卡方检验这种“近似的”检验,Fisher检验是一种精确的检验,但是它的计算要比卡方检验复杂。
【卡方检验的适用范围】
卡方检验适用于单因素频数表、双因素频数表中的
2
×
2
2\times 2
2×2与
r
×
c
r\times c
r×c列联表。
单因素频数表
2
×
2
2\times 2
2×2列联表
2. 样本总量
∑
o
i
>
40
\sum{o_i}>40
∑oi>40,且所有期望频数
e
i
>
5
e_i>5
ei>5,可使用Pearson卡方检验
3. 样本总量
∑
o
i
>
40
\sum{o_i}>40
∑oi>40,但存在期望频数
1
<
e
i
<
5
1
4. 若样本总量
∑
o
i
<
40
\sum{o_i}<40
∑oi<40,或存在期望频数
1
<
e
i
1
r
×
c
r\times c
r×c列联表
5. 表中期望频数
e
i
<
5
e_i<5
ei<5的格子不能超过1/5。
6. 不得出现期望频数
1
<
e
i
1
【Fisher检验的适用范围】
Fisher检验仅仅适用于双因素频数表中的
2
×
2
2\times 2
2×2列联表。
Fisher检验在
2
×
2
2\times 2
2×2列联表中适用范围内很广,弥补了卡方检验的缺点。
【总结】卡方检验在多种频数表中都可以应用,但要注意绝对频数与理论频数是否过低;Fisher检验只适用于 2 × 2 2\times 2 2×2列联表,但是在该表中的精确度与适用性都优于卡方检验。因此在 2 × 2 2\times 2 2×2列联表中,推荐使用Fisher检验;在其他表格中使用卡方检验。
开始使用卡方检验与Fisher检验,对特定的问题进行假设检验。首先看单因素频数表的检验,常见的问题有:适度性检验与分布的拟合优度检验。
适度性检验的目的是:检验多项式实验得到的绝对频数与“期望值”是否存在显著差异。
在单因素频数表中,这个期望值就是表格的观测总数除以格子数:
e
x
p
e
c
t
e
d
F
r
e
q
u
e
n
c
y
=
∑
o
i
i
expectedFrequency=\frac{\sum{o_i}}{i}
expectedFrequency=i∑oi
在前面的120次掷骰子的实验中,每个数字的期望值就是120/6=20。
Example.10 你和你的5个朋友们租了一个公寓一起生活。大家每天晚上都通过抽签决定某一个人去洗碗。经过几十天下来,你们统计了这段时间每个人的洗碗次数,如下图所示
需求:检验一下这个洗碗次数的分布是否合理。本质上就是“每个人的实际洗碗次数与期望洗碗次数是否存在显著差异”,我们便可以使用适度性检验。
obs1 = [20,12,10,8,10,6]
chi = stats.chisquare(obs1) # 若理论频数是期望,则我们只需要输入实际频数即可。
chi
# Power_divergenceResult(statistic=10.727272727272728, pvalue=0.057063677925693244)
p值大于0.05,不能拒绝原假设。
单因素频数表检验的另外一个重要的应用场景就是分布的拟合优度检验。
设样本
x
i
x_i
xi是来自一个潜在总体
F
(
x
)
F(x)
F(x),分布拟合优度检验所检验的问题是:通过这些样本
x
i
x_i
xi判断潜在总体
F
(
x
)
F(x)
F(x)是否等同于一个假设的理论分布
F
0
(
x
)
F_0(x)
F0(x)。原假设为
H
0
:
F
(
x
)
=
F
0
(
x
)
H_0: F\left( x \right) =F_0\left( x \right)
H0:F(x)=F0(x)
其中,理论分布
F
0
(
x
)
F_0(x)
F0(x)必须是一个分布函数已知的分布。分布可以分为离散分布与连续分布。
既然样本来自一个离散分布,那么理论分布
F
0
(
x
)
F_0(x)
F0(x)也应当是一个离散分布。
设总体
X
X
X为取有限个值
a
1
a_1
a1,
a
2
a_2
a2,……的离散随机变量。
记
P
(
X
∈
A
i
)
=
p
i
(
i
=
1
,
2
,
⋯
,
r
)
P\left(X \in A_{i}\right)=p_{i}(i=1,2, \cdots, r)
P(X∈Ai)=pi(i=1,2,⋯,r)为理论分布
F
0
(
x
)
F_0(x)
F0(x)在该分类下的“比例”,显然,我们用这个比例乘样本个数
n
n
n,所得到的
n
p
i
np_i
npi就是样本在这个分布下的期望频数
e
i
e_i
ei,如果样本的潜在总体
F
(
x
)
F(x)
F(x)服从理论总体
F
0
(
x
)
F_0(x)
F0(x),样本实际落入类
A
i
A_i
Ai的实际频数
o
i
o_i
oi应当接近于期望频数
n
p
i
np_i
npi,原假设便转换为了
H
0
:
o
i
=
n
p
i
H_0: o_i=np_i
H0:oi=npi
这恰巧就是卡方分布所检验的内容。于是我们便可以是用卡方分布进行分布拟合优度检验。
总结:使用卡方分布进行拟合优度检验的步骤:
分类。根据实际频数 o i o_i oi确定类别,若某个变量取值下样本的个数大于5,则直接将该取值作为一个单独的类;若小于5,则与相邻的取值合并为一个类。
计算理论分布 F 0 ( x ) F_0(x) F0(x)在该分类规则下,每个分类中的理论频数 n p i np_i npi。
进行卡方检验。
理解离散分布拟合优度检验的过程。
【Example.11 】
我们验证卢瑟福实验的数据是否服从一个泊松分布。以下数据观测的是一枚放射性
α
\alpha
α物质在单位时间内放射的质点数,实验重复2608次。
我们对该数据进行泊松分布的拟合优度检验。提示:我们用极大似然估计法计算出泊松分布参数
λ
=
3.87
\lambda =3.87
λ=3.87
import numpy as np
import pandas as pd
from scipy import stats
# 原始数据
data = {'counts': list(range(15)),
'observe':[57,203,383,525,532,408,273,139,45,27,10,4,2,0,0]}
df = pd.DataFrame(data)
# 将实际频数小于5的类别合并
df.iloc[11,1]=6
df=df[:12]
注意:这里的counts=11实际上是大于等于11的类,因此在计算它的 p i p_i pi时,不应当计算为 p i = P ( X = 11 ) p_i=P\left( X=11 \right) pi=P(X=11),而应当是 p i = P ( X ⩾ 11 ) = 1 − P ( X < 11 ) p_i=P\left( X\geqslant 11 \right) =1-P\left( X<11 \right) pi=P(X⩾11)=1−P(X<11)。
# 根据自变量count的值计算每个自变量对应的理论频率
Poiss=stats.poisson(mu=3.87)
df['prop']=Poiss.pmf(df['counts']) # pmf函数可以根据输入的自变量,输出对应的概率(也就是理论频率)
# 上述“注意”的修正
df.iloc[11, 2]=1-Poiss.cdf(10) # 修正:由于数据框中counts=11实际上是大于等于11,因此在这里修正counts大于11对应的概率
# cdf函数为左侧累积概率函数
# 用理论频率乘样本数,就可以得到理论频数
df['T_counts']=2608*df['prop']
# 用卡方检验,比较实际频数与理论频数的差别,就可以检验出数据是否服从泊松分布
chi=stats.chisquare(df['observe'], df['T_counts'], ddof=1) # 若理论频数不是“期望值”,则需要输入我们自己定义的理论频数
# p值约为0.225,不能拒绝原假设,因此我们可以认为样本的总体服从泊松分布。
样本为连续分布的情况要复杂一些,因为变量
X
X
X的取值是不可数的,因此我们不能直接将某个取值作为一个类。一般采取的方法是:选
r
−
1
r-1
r−1个实数
a
1
<
⋯
<
a
r
−
1
a_1<\cdots
(
−
∞
,
a
1
]
,
(
a
1
,
a
2
]
,
⋯
,
(
a
r
−
1
,
∞
)
\left( -\infty ,\left. a_1 \right] \right. \,\,, \left( \left. a_1,a_2 \right] \,\,, \cdots \,\,, \left( a_{r-1},\left. \infty \right) \right. \right.
(−∞,a1],(a1,a2],⋯,(ar−1,∞)
以这些区间为类,记录样本落入这些区间的个数,并计算这些区间在分布
F
0
(
x
)
F_0(x)
F0(x)下的累积概率,往后的步骤就与前面离散分布检验的步骤一样了。
列联表检验常见的应用是两个特征的独立性检验与一致性检验,这两种检验虽然问题不同,但是检验的原理是完全一样的:即比较绝对频数与表格中每个格子的“期望值”的差异。
在列联表中,每个单元格个期望值计算非常简单:单元格所在行的行样本数乘单元格所在列的列样本数再除以样本总数,即有
expectedFrequency
=
RowTotal
×
ColumnTotal
n
\text { expectedFrequency }=\frac{\text { RowTotal } \times \text { ColumnTotal }}{n}
expectedFrequency =n RowTotal × ColumnTotal
我们以这个列联表为例
单元格男性右利手的期望值为52*87/100=45.2。
独立性检验的是两个特征之间是否独立,一个变量作行,一个变量为列。
以上述的男女性/左右利手问题为例,我们可以检验性别特征与左右利手特征是否独立。
obs1=np.array([[43, 9], [44, 4]])
print(obs1)
# 定义一个函数,使它可以输出连续性校正/未校正卡方检验的p值,以及期望频数表
def chiSquare(data):
from scipy.stats import chi2_contingency
chi2_corrected = stats.chi2_contingency(data, correction=True) # 连续性校正
chi2_uncorrected = stats.chi2_contingency(data, correction=False) # 非连续性校正
print('Pearson卡方检验的p值为:{}'.format(chi2_uncorrected[1]))
print('连续性校正的卡方检验的p值为:{}'.format(chi2_corrected[1]))
print('-----------------------------------------------')
print('期望频数表:')
print(chi2_corrected[3])
chiSquare(obs1)
'''
Pearson卡方检验的p值为:0.1824670652605479
连续性校正的卡方检验的p值为:0.300384770390566
-----------------------------------------------
期望频数表:
[[45.24 6.76]
[41.76 6.24]]
'''
由于期望频数都大于5,因此我们应该使用非校正的卡方检验。p值约为0.3,无法拒绝原假设,即两种特征独立。
def fisherExact(data,significance=0.05):
from scipy.stats import fisher_exact
fisher_pvalue=fisher_exact(data)[1]
if fisher_pvalue<significance:
print('在显著性水平{0:}下,可以拒绝原假设(p={1:.4f})'.format(significance,fisher_pvalue))
else:
print('在显著性水平{0:}下,不可以拒绝原假设(p={1:.4f})'.format(significance,fisher_pvalue))
fisherExact(obs1)
# 在显著性水平0.05下,不可以拒绝原假设(p=0.2392)
confidence是置信水平,significance是显著性水平,置信区间采用置信水平,假设检验是显著性水平。
统一性检验的问题是:两个或两个以上总体的某一特征分布,也就是各类别的比例是否统一或相近。
Example.12 某公司想了解南京和北京的市民对最低生活保障的满意程度是否相同,调查结果如下所示
在这个例子中,我们分析的是南京与北京这两个总体的一个特征“最低生活保障的满意程度”分布是否统一。
obs2=np.array([[100,110],[150,160],[180,170],[170,160]])
print(obs2)
chiSquare(obs2)
"""
[[100 110]
[150 160]
[180 170]
[170 160]]
Pearson卡方检验的p值为:0.708463710032442
连续性校正的卡方检验的p值为:0.708463710032442
-----------------------------------------------
期望频数表:
[[105. 105.]
[155. 155.]
[175. 175.]
[165. 165.]]
"""
由于期望频数都大于5,因此我们应该使用非校正的卡方检验。p值约为0.7,无法拒绝原假设,即两个城市的市民对最低生活保障的满意程度是相同的。
一个淘宝网购商家搜集了一年中每天的订单数 X X X,除去春节期间及双十一前后外,按330天记,数据如下
请用卡方分布验证订单数是否泊松分布。已知:通过极大似然估计得知泊松分布参数 λ = 5.3 \lambda=5.3 λ=5.3
Task | 内容 | 时间 |
---|---|---|
Task01 | 假设检验1:方法论与一元数值检验 | 8-13 —— 8-18周四 |
Task02 | 假设检验2:多元数值向量检验 | 8-19 —— 8-20周六 |
Task03 | 假设检验3:分类数据检验 | 8-21 —— 8-22周一 |
Task04 | 应用随机过程与仿真系统 | 8-23 —— 8-25周四 |
Task05 | 金融量化分析与随机模拟 | 8-26 —— 9-28周日 |
[1] https://github.com/Git-Model/Modeling-Universe/tree/main/Data-Story