统计推断之假设检验

假设检验是统计推断的另一类重要问题,分为参数假设检验和非参数假设检验。

一、参数假设检验

总体的分布函数形式已知,但其中含有未知参数,为了推断总体的某些性质,提出某些关于总体参数的假设,然后根据样本对所提出的假设作出判断,是接受还是拒绝,这就是所谓的参数假设检验问题。

1、单个总体均值的假设检验

(1)正态总体标准差σ已知的Z检验法
设总体X~N(μ, σ2),其中μ未知,σ已知。X1,X2,X3,……,Xn
是来自总体X的样本。
提出原假设H0:μ=μ0,备择假设H1:μ$\neq$μ0
检验统计量Z计算方法如下
$$ Z = \frac{\overline{X}- \mu_{0}}{\mu/\sqrt{n}} $$
检验的显著性水平为$\alpha$,标准正态分布的上$\alpha/2$分位数记作$z_{\alpha/2}$。
当Z的观测值满足|z|>$z_{\alpha/2}$时,拒绝原假设H0,接受H1;否则,接受H0

例:某车间用一台包装机包装糖果。包得得袋装糖重是一个随机变量,它服从正态分布。当机器正常时,其均值为0.5kg,标准差为0.015kg。某日开工后为检验包装机是否正常,随机地抽取它所包装得糖9袋,称得净重(kg)为
0.497,0.506,0.518,0.524,0.498,0.511,0.520,0.515,0.512
问机器是否正常?
解:按题意总体X~N(μ, σ2),μ未知,σ=0.015已知,要求在显著性水平$\alpha$=0.05下检验假设:
H0:μ=0.5,H1:μ$\neq$0.5
因σ已知,故采用Z检验,检验统计量Z计算如下
$$ z = \frac{\overline{x}-0.5}{σ/\sqrt{n}} = \frac{0.5112-0.5}{0.015/\sqrt{9}} = 2.2444 $$
因$\alpha$=0.05时$z_{\alpha/2}$=1.96,有z>$z_{\alpha/2}$,故拒绝原假设H0,即认为这天包装机工作不正常。

1
2
3
4
5
6
7
8
9
10
11
import numpy as np
from statsmodels.stats.weightstats import ztest

sigma = 0.015
a = np.array([0.497, 0.506, 0.518, 0.524, 0.498, 0.511, 0.520, 0.515, 0.512])

t_stat, p_value = ztest(a, value=0.5) # 计算T统计量的观测值及p值
z_stat = t_stat*a.std(ddof=1)/sigma # 转换为Z统计量的观测值

print('z为:', round(z_stat, 4))
print('p值:', round(p_value, 4))

(2)正态总体标准差σ未知的t检验法
设总体X~N(μ, σ2),其中μ未知,σ未知。X1,X2,X3,……,Xn
是来自总体X的样本。
提出原假设H0:μ=μ0,备择假设H1:μ$\neq$μ0
检验统计量t计算方法如下(S为样本方差)
$$ t = \frac{\overline{X}-\mu_{0}}{S/\sqrt{n}} $$
检验的显著性水平为$\alpha$,自由度为n-1的t分布上$\alpha/2$分位数记作$t_{\alpha/2}(n-1)$。
当t的观测值满足|t|>$t_{\alpha/2}(n-1)$时,拒绝原假设H0,接受H1;否则,接受H0

例:某批矿砂的5个样品中的镍含量(%),经测定为
3.25,3.27,3.24,3.26,3.24
设测定量总体服从正态分布,但参数均未知,问在$\alpha$=0.01下能否接受假设:这批矿砂的镍含量均值为3.25。
解:按题意总体X~N(μ, σ2),μ、σ均未知,要求在显著性水平$\alpha$=0.01下检验假设:
H0:μ=3.25,H1:μ$\neq$3.25
因σ未知,故采用t检验,检验统计量t计算如下
$$ t = \frac{\overline{x}-3.25}{S/\sqrt{n}} = \frac{3.252-3.25}{0.0130/\sqrt{5}} = 0.3430 $$
因$\alpha$=0.01时$t_{\alpha/2}(n-1)$=4.6041,不满足t>$t_{\alpha/2}(n-1)$,故接受原假设H0,即认为这批矿砂镍含量的均值为3.25。

1
2
3
4
5
6
7
8
9
import numpy as np
from statsmodels.stats.weightstats import ztest

a = np.array([3.25, 3.27, 3.24, 3.26, 3.24])

t_stat, p_value = ztest(a, value=3.25) # 计算T统计量的观测值及p值

print('t为:', round(t_stat, 4))
print('p值:', round(p_value, 4))

2、两个总体均值的假设检验

例:下表分别给出两位文学家马克·吐温(Mark Twain)的8篇小品文以及斯诺特格拉斯(Snodgrass)的10篇小品文中由3个字母组成的单词的比例。
马克·吐温:0.225,0.262,0.217,0.240,0.230,0.229,0.235,0.217
斯诺特格拉斯:0.209,0.205,0.196,0.210,0.202,0.207,0.224,0.223,0.220,0.201
设两组数据分别来自正态总体,且两总体方差相等,但参数均未知。两样本相互独立。问两位作家所写的小品文中包含3个字母组成的单词的比例是否由显著的差异(取$\alpha$=0.05)?
解:按题意总体X服从于N(μ1, σ2),Y服从于N(μ2, σ2),两样本相互独立,要求在显著性水平$\alpha$=0.05下检验假设:
H0:μ12,H1:μ1$\neq$μ2
因σ未知,故采用t检验,检验统计量t计算如下
$$ t = \frac{\overline{X}-\overline{Y}}{\sqrt{\frac{(n_{1}-1)S_{1}^{2}+(n_{2}-1)S_{2}^{2}}{n_{1}+n_{2}-1}}·\sqrt{\frac{1}{n_{1}}+\frac{1}{n_{2}}}} = 3.8781 $$
因$\alpha$=0.05时$t_{\alpha/2}(n_{1}+n_{2}-2)$=2.1199,满足t>$t_{\alpha/2}(n_{1}+n_{2}-2)$,故拒绝原假设H0,即认为两位作家所写的小品文中包含由3个字母组成单词的比例有显著的差异。

1
2
3
4
5
6
7
8
9
10
11
import numpy as np
from statsmodels.stats.weightstats import ttest_ind

a = np.array([0.225, 0.262, 0.217, 0.240, 0.230, 0.229, 0.235, 0.217])
b = np.array([0.209, 0.205, 0.196, 0.210, 0.202, 0.207, 0.224, 0.223, 0.220, 0.201])

t_stat, p_value, df = ttest_ind(a, b, value=0)

print('t为:', round(t_stat, 4))
print('p值:', round(p_value, 4))
print('自由度:', round(df, 4))

二、非参数假设检验

在很多实际问题中,样本数据服从什么分布我们一般是不知道的,这时候就需要进行非参数检验。下面介绍两种非参数检验方法:分布拟合检验和Kolmogorov-Smirnov检验。

1、分布拟合检验

在实际问题中,有时不能预知总体服从什么类型的分布,这时就要根据样本来检验关于分布的假设。这时候要用到$\chi^{2}$检验法。过程如下:
(1)建立待检验假设H0:总体X的分布函数为F(x)
(2)在数轴上选取k-1个分位点,将数轴分为k个区间。令pi为分布函数F(x)的总体X在第i个区间内取值的概率,设mi为n个样本观察值落入第i个区间内的个数,也就是组频数。
(3)选取统计量

$$\chi^{2} = \sum\limits_{i=1}^{k}\frac{(m_{i}-np_{i})^2}{np_{i}} = \sum\limits_{i=1}^{k}\frac{m_{i}^{2}}{np_{i}}-n$$

如果H0为真,则$\chi^{2}$~$\chi^{2}(k-1-r)$
其中,r为分布函数F(x)中未知参数的个数。
(4)对于给定的显著性$\alpha$,确定$\chi_{\alpha}^{2}$
(5)作出判断,若$\chi^{2} < \chi_{\alpha}^{2}$,则接受H0;否则拒绝H0,即不能认为总体X的分布函数为F(x)

例:根据某市公路交通部门某年上半年交通事故记录,统计得星期一至星期日发生交通事故得次数如下表所示。试检验交通事故的发生次数是否服从离散均匀分布,即交通事故的发生与星期几无关。

星期 1 2 3 4 5 6 7
次数 36 23 29 31 34 60 25

解:(1)设X为”一周内各天发生交通事故的总体”,若交通事故的发生与星期几无关,则X的分布律为P{X=i}=pi=1/7(i=1,2,…,7)那么我们的问题就是检验假设H0:pi=1/7(i=1,2,…,7)
(2)将每天看成一个小区间,设组频数为mi(i=1,2,…,7)
(3)选取统计量
$$\chi^{2} = \sum\limits_{i=1}^{7}\frac{(m_{i}-np_{i})^2}{np_{i}}=\sum\limits_{i=1}^{7}\frac{m_{i}^{2}}{np_{i}}-n$$
其中,n=36+23+29+31+34+60+25=238。
当H0为真时,$\chi^{2}$~$\chi^{2}(7-1)$
(4)对于$\alpha$=0.05,查表得临界值为$\chi_{\alpha}^{2}(6)$=12.592,并且根据样本可计算得到检验统计量$\chi^{2}$的观察值为
$$\chi^{2} = \sum\limits_{i=1}^{7}\frac{m_{i}^2}{238\times\frac{1}{7}}-238=26.9412$$
(5)作出判断,因为$\chi^{2}$=26.941 >$\chi_{0.05}^{2}(6)$=12.5916,所以应拒绝H0,即认为交通事故的发生与星期几有关。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
import scipy.stats as ss

bins = np.arange(1, 8)
mi = np.array([36, 23, 29, 31, 34, 60, 25])

n = mi.sum()
p = np.ones(7)/7
cha = (mi - n*p)**2/(n*p)

st = cha.sum()
bd = ss.chi2.ppf(0.95, len(bins)-1) # 计算上alpha分位数

print('统计量为: {}, 临界值为: {}'.format(st, bd))

例:某车间生成滚珠,随机地抽出了50粒,测得它们得直径(单位:mm)为
15.0,15.8,15.2,15.1,15.9,14.7,14.8,15.5,15.6,15.3,
15.1,15.3,15.0,15.6,15.7,14.8,14.5,15.2,15.9,15.9,
15.2,15.0,15.3,15.6,15.1,14.9,14.2,15.6,15.8,15.2,
15.9,15.2,15.0,15.9,15.8,14.5,14.1,15.5,15.5,15.1,
15.1,15.0,15.3,15.7,15.5,14.5,14.0,15.7,15.6,15.2
经过计算知样本均值为15.0780,样本标准差为0.4282,试问滚珠直径是否服从正态分布N(15.0780, 0.42822)($\alpha$=0.05)?
解:假设H0:滚珠直径X~N(15.0780,0.42822)
找出样本中最大值xmax=15.9和最小值xmin=14.2,然后将区间(-∞,+∞)分成6个区间。
计算得$\chi^{2}$=3.2999,自由度k-r-1=6-2-1=3,查$\chi^{2}$分布表,当$\alpha$=0.05,得临界值$\chi_{0.05}^{2}(3)$=7.8147。
因$\chi^{2}$=3.2999<$\chi_{0.05}^{2}(3)$=7.8147,所以H0成立,即滚珠直径服从正态分布N(15.0780, 0.42822)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as ss

n = 50
k = 8 # 初始小区间划分的个数

a = np.loadtxt("data.txt")
'''
15.0 15.8 15.2 15.1 15.9 14.7 14.8 15.5 15.6 15.3
15.1 15.3 15.0 15.6 15.7 14.8 14.5 14.2 14.9 14.9
15.2 15.0 15.3 15.6 15.1 14.9 14.2 14.6 15.8 15.2
15.9 15.2 15.0 14.9 14.8 14.5 15.1 15.5 15.5 15.1
15.1 15.0 15.3 14.7 14.5 15.5 15.0 14.7 14.6 14.2
'''

a = a.flatten()
mu = a.mean()
s = a.std()
print('均值为:', mu)
print('标准差为:', s)
print('最大值为:', a.max())
print('最小值为:', a.min())

bins = np.array([14.2, 14.625, 14.8375, 15.05, 15.2625, 15.475, 15.9])
h = plt.hist(a,bins)
f = h[0]
x = h[1] # 提取各个小区间的频数和小区间端点的取值
print('各区间的频数为:', f, '\n小区间端点值为:', x)

p = ss.norm.cdf(x, mu, s) # 计算各个分点分布函数的取值
dp = np.diff(p) # 计算各小区间取值的理论概率
dp[0] = ss.norm.cdf(x[1], mu, s) # 修改第一个区间的概率值
dp[-1] = 1-ss.norm.cdf(x[-2], mu, s) # 修改最后一个区间的概率值
print('各小区取值的理论概率为:', dp)

st = sum(f**2/(n*dp))-n # 计算卡方统计量的值
bd = ss.chi2.ppf(0.95,k-5) # 计算上alpha分位数
print('统计量为:{},临界值为:{}'.format(st, bd))

2、Kolmogorov-Smirnov检验

Kolmogorov-Smirnov检验的思想是测量经验分布函数Fn(x)和所拟合的分布函数F(x)之间的距离,距离越小,说明拟合效果越好。这个距离被称为经验分布函数统计量,记为Dn

定义Kolmogorov-Smirnov检验统计量
$$D_{n} = \mathop{sup}\limits_{x}|F_{n}(x)-F_(x)|$$

Kolmogorov-Smirnov检验过程如下:
(1)零假设为所指定的分布是可接受的,对立假设为拒绝。
H0:Fn(x)=F(x;θ),H1:Fn(x)≠F(x;θ)
θ是所拟合分布中的参数(或参数向量)
(2)当统计量D的值较大时,说明零假设是不可接受的。当统计量D取较小的值时,说明经验分布函数Fn(x)和所拟合分布函数F(x)之间距离较小,证明零假设是有可能是可接受的。
为了确认到底有多大概率零假设是可以接受的,还要结合p值来看。如果p值较小还是会拒绝零假设。

例:有一批学生的体检数据,检验学生的体重是否服从正态分布。
解:提出假设
$$H_{0} :F(x)=\frac{1}{\sqrt{2\pi}s}e^{-\frac{(x-\mu)^{2}}{2s^{2}}},H_{1} :F(x)\neq\frac{1}{\sqrt{2\pi}s}e^{-\frac{(x-\mu)^{2}}{2s^{2}}}$$
其中,样本均值μ=61.27,样本标准差s=6.8584。调用Python包,得到统计量D的值为0.0590,p值为0.8767(大于0.05),所以接受原假设,认为学生的体重服从正态分布。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as ss

a = np.loadtxt("data.txt")
'''
172 75 169 55 169 64 171 65 167 47
171 62 168 67 165 52 169 62 168 65
166 62 168 65 164 59 170 58 165 64
160 55 175 67 173 74 172 64 168 57
155 57 176 64 172 69 169 58 176 57
173 58 168 50 169 52 167 72 170 57
166 55 161 49 173 57 175 76 158 51
170 63 169 63 173 61 164 59 165 62
167 53 171 61 166 70 166 63 172 53
173 60 178 64 163 57 169 54 169 66
178 60 177 66 170 56 167 54 169 58
173 73 170 58 160 65 179 62 172 50
163 47 173 67 165 58 176 63 162 52
165 66 172 59 177 66 182 69 175 75
170 60 170 62 169 63 186 77 174 66
163 50 172 59 176 60 166 76 167 63
172 57 177 58 177 67 169 72 166 50
182 63 176 68 172 56 173 59 174 64
171 59 175 68 165 56 169 65 168 62
177 64 184 70 166 49 171 71 170 59
'''

w = a[:,1::2]
w = w.flatten()
mu = w.mean()
s = w.std(ddof=1) # 计算样本均值和标准差
print('均值和标准差分别为:', (mu, s))

statVal, pVal = ss.kstest(w, 'norm', (mu,s))
print('统计量和P值分别为:', [statVal, pVal])
0%