LOADING

加载过慢请开启缓存 浏览器默认开启

常用假设检验方法及 Python 实现

参考文档:https://docs.scipy.org/doc/scipy/tutorial/stats/hypothesis_tests.html

1. 什么是假设检验?

1.1 概念

假设检验(Hypothesis testing),又称统计假设检验,是用来判断样本与样本、样本与总体的差异是由抽样误差引起还是本质差别造成的统计推断方法。显著性检验是假设检验中最常用的一种方法,也是一种最基本的统计推断形式,其基本原理是先对总体的特征做出某种假设,然后通过抽样研究的统计推理,对此假设应该被拒绝还是接受做出推断。常用的假设检验方法包括 Z 检验、t 检验、卡方检验、F 检验等。

参数检验与非参数检验

  • 参数检验
    • 参数检验,是在总体分布已知的情况下,对总体分布的参数如均值、方差等进行推断的方法。
    • 常见的参数检验方法有 T 检验、Z 检验、F 检验、二项分布总体的假设检验等。
  • 非参数检验
    • 由于种种原因,人们往往无法对总体分布形态做简单假定,此时参数检验方法就不适用了。非参数检验,是在总体方差未知或知道甚少的情况下,利用样本数据对总体分布形态等进行推断的方法。非参数检验推断过程中不涉及有关总体分布的参数。
    • 常用的非参数检验的方法有,两个独立样本的K-S检验、W-W检验、U检验等,多个独立样本的H检验、中位数检验等,卡方检验,二项分布检验、拟合优度检验等。

1.2 步骤

假设检验的步骤如下:

  • 确定要进行检验的假设,包括原假设 $H_0$ 和备择假设 $H_1$
  • 选择检验的方法,计算统计量
  • 根据显著性水平,确定用于做出决策的拒绝域
  • 查看样本结果是否位于拒绝域内
  • 做出决策

1.3 其他概念

假设检验的几个重要概念

  • $H_0$(原假设):即要对其进行检验的断言,除非有足够的证据拒绝,否则将接受原假设
  • $H_1$(备择假设):在拒绝原假设之后将要接受的断言,通常与原假设对立
  • $\alpha$(显著性水平):指当原假设为正确时人们却把它拒绝了的概率或风险。它是公认的小概率时间的概率值,必须在每一次统计检验之前确定,通常取 $\alpha=0.05$ 或 $\alpha=0.01$
  • 单尾检验:拒绝域落在可能的数据集的一侧
  • 双尾检验:拒绝域落在可能的数据集的两侧

1.4 双尾检验与单尾检验

使用单位检验还是双尾检验,取决于备择假设的形式:

拒绝域的位置 原假设 $H_0$ 备择假设 $H_1$
双尾 $H_0:\theta = \theta _0$ $H_1:\theta \ne \theta _0$
左单尾 $H_0:\theta \ge \theta _0$ $H_1:\theta < \theta _0$
右单尾 $H_0:\theta \le \theta _0$ $H_1:\theta > \theta _0$

1.5 假设检验的基本思想

小概率事件在一次实验中是几乎不可能发生的,假若在一次实验中事件事实上发生了,那只能认为事件不是来自我们假设的总体,也就是认为我们对总体所作的假设不正确

1.6 假设检验中的两类错误

  • 弃真错误:原假设事实上正确,可是检验统计量的观察值却落入拒绝域,因此否定了本来正确的假设,$p(弃真)=\alpha$
  • 取伪错误:原假设事实上不正确,可是检验统计量的观察值却落入了接受域,因为没有否定本来不正确的原假设。

1.7 P 值

当原假设为真时所取得的样本观察结果或极端结果出现的概率。

如果 P 值很小,说明原假设情况的发生概率很小,而如果出现了,根据小概率原理,我们就有理由拒绝原假设,P 值越小,我们拒绝原假设的理由越充分。

P值 碰巧的概率 对原假设 $H_0$ 统计学意义
$p>0.05$ 碰巧出现的可能性大于 5% 不能否定原假设 $H_0$ 两组差别无显著意义
$p<0.05$ 碰巧出现的可能性小于 5% 可以否定原假设 $H_0$ 两组差别有显著意义
$p<0.01$ 碰巧出现的可能性小于 1% 可以否定原假设 $H_0$ 两组差别有非常显著意义

P 值显著性水平 $\alpha$ 在假设检验中密切中密切相关,但它们代表不同的概念。

术语 定义 常见取值 作用
p 值 在原假设($H_0$)为真时,观测到当前数据(或更极端数据)的概率 计算得出(如 0.03) 衡量数据反对原假设的证据强度。
显著性水平 $\alpha$ 研究者预先设定的阈值,用于判断是否拒绝 $H_0$ (即容忍的假阳性错误率) 通常取 0.05 作为决策边界,控制第一类错误(误拒真)的风险

2. 卡方检验

分析变量之间的关联性或差异性

2.1 概念

卡方检验的根本思想在于比较理论频数和实际频数的吻合程度或拟合优度问题。卡方检验分为卡方拟合度检验和卡方独立性检验。

卡方分布 $\chi^2$:若 $n$ 个相互独立的随机变量 $\zeta_1$,$\zeta_2$,…,$\zeta_n$ 均服从标准正态分布(也称独立同分布于标准正态分布),则这 $n$ 个服从标准正态分布的随机变量的平方和构成一新的随机变量,其分布规律称为卡方分布

2.2 核心思想

卡方检验是以卡方分布为基础的一种常用假设检验方法。

原假设 $H_0$ 是:观察频数与期望频数没有差别。

$$\chi^2 = \Sigma \frac{(A-E)^2}{E}=\Sigma^k_{i=1} \frac{(A_i-E_i)^2}{E_i}$$

$A$:某个类别的观察频数
$E$:基于原假设 $H_0$ 计算出的期望频数
$A-E$:残差

求和之前除以期望频数的原因:观察频数与期望频数的差距是相对较大还是较小,取决于期望频数的大小。例如期望频数为1000,观察频数为1040和期望频数为10,观察频数为50,差值均为40,但是显然后者的期望与实际的差距显然大于前者的期望和实际的差距。

$\chi^2$ 是观察频数与期望频数之间距离的一种度量指标,也是假设成立与否的度量指标。如果 $\chi^2$ 值小,就倾向于不拒绝 $H_0$;如果 $\chi^2$ 值大,就倾向于拒绝 $H_0$。至于 $\chi^2$ 在每个具体研究中究竟要大到什么程度才能拒绝 $H_0$,则要借助于卡方分布求出所对应的 P 值来确定。

2.3 卡方分布的用途

  • 检验某个连续变量的分布是否与理论分布一致
  • 检验某个分类变量各类的出现概率是否等于指定概率
  • 检验某两个分类变量是否相互独立。如吸烟是否与呼吸道疾病有关
  • 检验控制某种或某几种分类因素的作用以后,另两个分类变量是否相互独立

卡方拟合优度检验的自由度为 $df=k-1$,其中 $k$ 代表分类变量数
卡方独立性检验的自由度为 $df=(R-1)(C-1)$,$R$ 代表行数,$C$ 代表列数。

2.4 卡方检验的基本步骤

(1)提出假设

  • 原假设(H₀):变量之间无关联(或观测分布符合理论分布)。
  • 备择假设(H₁):变量之间有关联(或观测分布不符合理论分布)。

(2)计算卡方统计量

公式为:
$$\chi^2 = \sum \frac{(O_i - E_i)^2}{E_i}$$

  • $O_i$:实际观测频数
  • $E_i$:理论期望频数(在原假设成立时计算得出)。

(3)确定临界值

根据显著性水平(α,通常取0.05)自由度(df)查卡方分布表:

  • 拟合优度检验:$df = \text{分类类别数} - 1$
  • 独立性检验:$df = (行数-1) \times (列数-1)$

(4)做出决策

  • 若 $\chi^2$ > 临界值,拒绝原假设;
  • 若 $\chi^2$ ≤ 临界值,不拒绝原假设。

适用条件

  • 样本量要求:每个单元格的期望频数 $E_i$ 应 ≥5(若不满足,可用Fisher精确检验)。
  • 变量类型:分类变量(名义或有序),不能用于连续变量。

2.5 卡方检验实例与 Python 实现

参考 SciPy 文档:https://docs.scipy.org/doc/scipy/tutorial/stats/hypothesis_chisquare.html

在俄勒冈州的一片古老森林中调查了鸟类的觅食行为。在森林中,44% 的冠层体积是花旗松,24% 是黄松,29% 是大冷杉,3% 是西部落叶松。作者观察了几种鸟类的行为,其中一种是红胸坚果雏。他们对该物种的觅食进行了 189 次观察,记录了 43 次(“23%”)在花旗松中的观察,在黄松中记录了 52 次(“28%”),在大冷杉中记录了 54 次(“29%”)在大冷杉中的观察,在西部落叶松中记录了 40 次(“21%”)的观察。

使用卡方检验,我们可以检验觅食事件的比例等于树冠体积的比例的原假设。该论文的作者认为 p 值小于 1% 是显著的。

使用上述冠层体积和观测事件的比例,我们可以推断出预期的频率。

import numpy as np
f_exp = np.array([44, 24, 29, 3]) / 100 * 189

观察到的觅食频率为:

f_obs = np.array([43, 52, 54, 40])

现在,我们可以将观测到的频率与预期频率进行比较:

from scipy.stats import chisquare
chisquare(f_obs=f_obs, f_exp=f_exp)
Power_divergenceResult(statistic=228.23515947653874, pvalue=3.3295585338846486e-49)

p 值远低于所选的显著性水平。因此,作者认为这种差异是显著的,并得出结论,觅食事件的相对比例与树冠体积的相对比例不同。


3. Z 检验

比较均值差异

3.1 什么是 Z 检验

Z 检验是一种基于正态分布(Z 分布)的统计假设检验方法,主要用于在已知总体标准差(σ)的情况下,检验样本均值是否与总体均值存在显著差异,或者比较两个独立样本的均值差异是否显著。它适用于大样本(通常 $ n \geq 30 $)或总体服从正态分布的情况。

3.2 Z 检验的核心思想

Z 检验通过计算 Z 统计量(Z-Score),衡量样本均值与总体均值的差异是否超出了随机波动的范围:

$$Z = \frac{\text{样本均值} - \text{总体均值}}{\text{标准误差(SE)}}$$

其中:

  • 标准误差(SE) = $ \frac{\sigma}{\sqrt{n}} $(单样本 Z 检验)
  • $\sigma$ = 总体标准差(若未知,可用样本标准差 $ s $ 近似,但严格来说应使用 T 检验

Z值越大,说明样本均值与总体均值的差异越显著。

3.3 Z 检验的适用场景

Z检验主要用于以下情况:

  1. 单样本 Z 检验

    • 检验单个样本的均值是否等于某个已知的总体均值。
    • 例如:某工厂生产的灯泡寿命声称平均为 1200 小时,抽样检测 30 个灯泡,检验其均值是否真的等于 1200 小时。
  2. 两独立样本Z检验

    • 比较两个独立样本的均值是否有显著差异。
    • 例如:比较两种教学方法对学生考试成绩的影响。
  3. 比例检验(Z检验的变体)

    • 检验样本比例是否等于某个理论比例(如投票支持率是否超过 50%)。

3.4. Z检验的计算步骤

(1)单样本Z检验

假设

  • $ H_0: \mu = \mu_0 $(样本均值等于总体均值)
  • $ H_1: \mu \neq \mu_0 $(双侧检验)或 $ \mu > \mu_0 $ / $ \mu < \mu_0 $(单侧检验)

计算公式
$$Z = \frac{\bar{X} - \mu_0}{\sigma / \sqrt{n}}$$

  • $\bar{X}$ = 样本均值
  • $\mu_0$ = 假设的总体均值
  • $\sigma$ = 总体标准差
  • $n$ = 样本量

决策

  • 计算得到的Z值与临界Z值(如 $ Z_{0.05} = 1.96 $)比较,或直接看p值:
    • 若 $ |Z| > Z_{\alpha/2} $,拒绝 $ H_0 $(差异显著)。
    • 若 p值 < α(如 0.05),拒绝 $ H_0 $。

(2)两独立样本Z检验

假设

  • $ H_0: \mu_1 = \mu_2 $(两样本均值无差异)
  • $ H_1: \mu_1 \neq \mu_2 $(有差异)

计算公式
$$Z = \frac{(\bar{X}_1 - \bar{X}_2) - 0}{\sqrt{\frac{\sigma_1^2}{n_1} + \frac{\sigma_2^2}{n_2}}}$$

  • $\bar{X}_1, \bar{X}_2$ = 两样本均值
  • $\sigma_1, \sigma_2$ = 两总体标准差(若未知,可用样本标准差近似)
  • $n_1, n_2$ = 两样本量

决策

  • 比较Z值与临界值,或看p值是否小于α。

3.5. Z检验的Python实现(SciPy)

单样本Z检验

import numpy as np
from scipy import stats

# 样本数据
sample = np.array([102, 105, 98, 97, 100, 103, 99, 101, 104, 102])
mu0 = 100  # 假设的总体均值
sigma = 3  # 已知的总体标准差

# 计算Z统计量和p值
z_score = (np.mean(sample) - mu0) / (sigma / np.sqrt(len(sample)))
p_value = 2 * (1 - stats.norm.cdf(abs(z_score)))  # 双侧检验

print(f"Z值: {z_score:.4f}, p值: {p_value:.4f}")
if p_value < 0.05:
    print("拒绝H0,均值显著不同")
else:
    print("不拒绝H0,均值无显著差异")

两独立样本Z检验

# 两样本数据
sample1 = np.array([102, 105, 98, 97, 100])
sample2 = np.array([99, 101, 104, 102, 103])
sigma1, sigma2 = 3, 3  # 已知两总体标准差

# 计算Z统计量
mean_diff = np.mean(sample1) - np.mean(sample2)
se = np.sqrt((sigma1**2 / len(sample1)) + (sigma2**2 / len(sample2)))
z_score = mean_diff / se
p_value = 2 * (1 - stats.norm.cdf(abs(z_score)))

print(f"Z值: {z_score:.4f}, p值: {p_value:.4f}")
if p_value < 0.05:
    print("两样本均值显著不同")
else:
    print("两样本均值无显著差异")

杂谈:为什么 SciPy 没有专门写 ztest 函数?

  • 历史原因:SciPy 早期设计更关注通用科学计算,统计功能由 statsmodels 补充
  • 实际需求:Z 检验严格依赖已知总体标准差,但现实中更常见的是未知 $\sigma$ 的情况(此时 T 检验更合适)
  • 替代方案scipy.stats.ttest_1samp (单样本T检验)在样本量较大时结果接近Z检验

4. T 检验

用于判断样本均值与总体均值是否存在显著差异。

4.1 什么是 T 检验(T-Test)

T 检验是一种基于 t 分布 的统计假设检验方法,用于判断 样本均值是否与总体均值(或另一组样本均值)存在显著差异。与Z检验不同,T检验适用于 总体标准差未知小样本(n < 30) 的情况,是实际科研和数据分析中最常用的检验之一。

4.2 T检验的核心思想

T 检验通过计算 t 统计量(t-score),衡量样本均值与参考值(总体均值或另一组样本均值)的差异是否显著:
$$t = \frac{\text{样本均值} - \text{参考值}}{\text{标准误差(SE)}}$$
其中:

  • 标准误差(SE) = $ \frac{s}{\sqrt{n}} $(s为样本标准差,n为样本量)
  • 自由度(df) = $ n - 1 $(单样本 T 检验)

t 值越大,说明差异越显著。

4.3 T检验的适用场景

T检验主要分为三类:

  1. 单样本T检验(One-Sample T-Test)

    • 检验 单个样本的均值 是否等于某个理论值或已知总体均值。
    • 示例:某药物声称能降低血压至120 mmHg,测量10名患者服药后的血压,检验均值是否等于120。
  2. 独立样本T检验(Independent Two-Sample T-Test)

    • 比较 两组独立样本的均值 是否有显著差异。
    • 示例:比较两种教学方法对学生考试成绩的影响(A组 vs. B组)。
  3. 配对样本T检验(Paired T-Test)

    • 比较 同一组样本在不同条件下的均值差异(如前后测)。
    • 示例:10名运动员训练前后的跑步成绩对比。

4.4 T检验 vs. Z检验的关键区别

特征 T检验 Z检验
总体标准差 未知(用样本标准差s估计) 已知
样本量要求 小样本(n < 30)或大样本 大样本(n ≥ 30)
分布 t分布(自由度依赖) 标准正态分布(Z分布)
应用频率 更常用(现实σ通常未知) 较少用(需已知σ)

4.5 T检验的计算步骤

(1)单样本T检验(最常见)

假设

  • $ H_0: \mu = \mu_0 $(样本均值等于理论值)
  • $ H_1: \mu \neq \mu_0 $(双侧检验)

公式
$$t = \frac{\bar{X} - \mu_0}{s / \sqrt{n}}$$

  • $\bar{X}$:样本均值
  • $\mu_0$:理论均值
  • $s$:样本标准差
  • $n$:样本量

决策

  • 计算t值后,查t分布表或直接比较p值:
    • 若 $ |t| > t_{\alpha/2, df} $ 或 p值 < α(如0.05),拒绝H₀。

(2)独立样本T检验

假设

  • $ H_0: \mu_1 = \mu_2 $(两样本均值无差异)
  • $ H_1: \mu_1 \neq \mu_2 $(有差异)

公式(假设两总体方差相等):
$$t = \frac{\bar{X}_1 - \bar{X}_2}{\sqrt{\frac{s_p^2}{n_1} + \frac{s_p^2}{n_2}}}, \quad s_p^2 = \frac{(n_1-1)s_1^2 + (n_2-1)s_2^2}{n_1 + n_2 - 2}$$

  • $s_p^2$:合并方差
  • 若方差不齐(需先做 Levene 检验),使用 Welch’s T检验(修正自由度)。

(3)配对样本T检验

假设

  • $ H_0: \mu_{\text{前}} = \mu_{\text{后}} $(前后无差异)
  • $ H_1: \mu_{\text{前}} \neq \mu_{\text{后}} $(有差异)

公式
$$t = \frac{\bar{D}}{s_D / \sqrt{n}}$$

  • $\bar{D}$:配对差异的均值
  • $s_D$:配对差异的标准差

4.6 Python实现(SciPy)

(1)单样本T检验

from scipy.stats import ttest_1samp
import numpy as np

sample = np.array([102, 105, 98, 97, 100, 103])
mu0 = 100  # 理论均值

t_stat, p_value = ttest_1samp(sample, mu0)
print(f"t值: {t_stat:.3f}, p值: {p_value:.3f}")
if p_value < 0.05:
    print("拒绝H0,均值显著不同")
else:
    print("不拒绝H0")

(2)独立样本T检验

from scipy.stats import ttest_ind

group1 = np.array([20, 22, 19, 18, 21])
group2 = np.array([18, 17, 20, 16, 15])

# 默认假设方差齐性(equal_var=True)
t_stat, p_value = ttest_ind(group1, group2)
print(f"t值: {t_stat:.3f}, p值: {p_value:.3f}")

(3)配对样本T检验

from scipy.stats import ttest_rel

before = np.array([70, 72, 68, 75, 71])
after = np.array([68, 70, 65, 73, 69])

t_stat, p_value = ttest_rel(before, after)
print(f"t值: {t_stat:.3f}, p值: {p_value:.3f}")

4.7 注意事项

  1. 正态性假设

    • 小样本时,数据应近似正态分布(可通过Shapiro-Wilk 检验或Q-Q图验证)。
    • 大样本(n ≥ 30)时,因中心极限定理,可放宽正态性要求。
  2. 方差齐性

    • 独立样本T检验需检验两组方差是否相等(如 Levene 检验),若不等需用 Welch’s T检验(ttest_ind(..., equal_var=False))。
  3. 效应量

    • 除了p值,应报告效应量(如 Cohen’s d),衡量差异的实际重要性。