【小白学机器学习13】实战演练:Python中的t检验全攻略(单样本、独立样本与配对样本)
·
1. 什么是t检验?
t检验是统计学中最常用的假设检验方法之一,主要用于比较两组数据的均值是否存在显著差异。想象一下,你买了一杯标称500ml的奶茶,喝了几口后怀疑分量不足,这时就可以用t检验来判断奶茶的实际容量是否真的少于500ml。
t检验的核心思想是通过样本数据推断总体情况。它基于t分布理论,特别适合小样本(通常n<30)且总体标准差未知的情况。在实际应用中,t检验主要有三种类型:
- 单样本t检验:比较样本均值与已知总体均值(如奶茶容量与标称值)
- 独立样本t检验:比较两个独立组的均值(如男女生的考试成绩)
- 配对样本t检验:比较同一组对象在不同条件下的均值(如服药前后的血压值)
2. 准备工作:Python环境与数据
2.1 安装必要库
在开始前,确保已安装以下Python库:
pip install numpy pandas scipy matplotlib
2.2 模拟数据集
我们创建三个典型场景的数据:
import numpy as np
import pandas as pd
# 单样本数据:饮料净含量(ml)
drinks = np.array([498, 502, 495, 503, 497, 501, 499, 504, 496, 502])
# 独立样本数据:A/B两组测试成绩
group_a = np.array([78, 85, 92, 88, 76])
group_b = np.array([82, 89, 85, 91, 87, 84])
# 配对样本数据:减肥前后体重(kg)
before = np.array([68, 72, 65, 70, 75])
after = np.array([65, 70, 63, 68, 72])
3. 单样本t检验实战
3.1 检验步骤
假设饮料标称500ml,我们想检验实际容量是否不足:
-
假设设立:
- H₀(原假设):μ = 500ml
- H₁(备择假设):μ < 500ml(单侧检验)
-
正态性检验:
from scipy import stats
print(stats.shapiro(drinks)) # p值>0.05则符合正态分布
- 执行检验:
t_stat, p_value = stats.ttest_1samp(drinks, popmean=500, alternative='less')
print(f"t统计量: {t_stat:.3f}, p值: {p_value:.4f}")
3.2 结果解读
当输出结果为:
t统计量: -0.837, p值: 0.2162
由于p值>0.05,不能拒绝原假设,说明没有足够证据表明饮料容量不足500ml。
4. 独立样本t检验实战
4.1 方差齐性检验
比较A/B两组成绩前,先检验方差是否相等:
levene_test = stats.levene(group_a, group_b)
print(f"方差齐性检验p值: {levene_test.pvalue:.3f}")
4.2 执行检验
根据方差齐性结果选择参数:
if levene_test.pvalue > 0.05:
t_result = stats.ttest_ind(group_a, group_b, equal_var=True)
else:
t_result = stats.ttest_ind(group_a, group_b, equal_var=False)
print(f"t统计量: {t_result.statistic:.3f}, p值: {t_result.pvalue:.3f}")
4.3 效应量计算
除了p值,还应报告效应量:
def cohen_d(x, y):
nx, ny = len(x), len(y)
pooled_std = np.sqrt(((nx-1)*np.std(x)**2 + (ny-1)*np.std(y)**2)/(nx+ny-2))
return (np.mean(x)-np.mean(y))/pooled_std
print(f"Cohen's d: {cohen_d(group_a, group_b):.3f}")
5. 配对样本t检验实战
5.1 数据预处理
计算前后差值并检查正态性:
diffs = after - before
print(stats.shapiro(diffs))
5.2 执行检验
t_result = stats.ttest_rel(before, after)
print(f"t统计量: {t_result.statistic:.3f}, p值: {t_result.pvalue:.4f}")
5.3 可视化展示
import matplotlib.pyplot as plt
plt.figure(figsize=(10,5))
plt.plot([1,2], [before.mean(), after.mean()], 'ro-')
plt.errorbar([1,2], [before.mean(), after.mean()],
yerr=[before.std(), after.std()], fmt='o')
plt.xticks([1,2], ["减肥前", "减肥后"])
plt.ylabel("平均体重(kg)")
plt.show()
6. 常见问题与解决方案
6.1 正态性不满足怎么办?
当数据非正态时:
- 尝试数据转换(如对数变换)
- 使用非参数检验(如Wilcoxon检验)
# 单样本替代方案
stats.wilcoxon(drinks - 500)
# 独立样本替代方案
stats.mannwhitneyu(group_a, group_b)
6.2 样本量极小时
当n<15时:
- 增加样本量
- 使用更保守的显著性水平(如α=0.01)
- 考虑贝叶斯t检验
6.3 多重比较问题
进行多次检验时,需校正p值:
from statsmodels.stats.multitest import multipletests
pvals = [0.03, 0.01, 0.005]
print(multipletests(pvals, method='bonferroni')[1]) # 校正后p值
7. 完整案例演示
7.1 业务场景
某电商想验证:
- 新页面转化率是否高于旧页面(独立样本)
- 用户周均访问次数是否大于3次(单样本)
- 促销活动前后客单价变化(配对样本)
7.2 Python实现
# 1. 独立样本检验
old_page = np.random.normal(0.15, 0.03, 100)
new_page = np.random.normal(0.18, 0.04, 120)
print(stats.ttest_ind(new_page, old_page, alternative='greater'))
# 2. 单样本检验
visits = np.random.poisson(3.5, 50)
print(stats.ttest_1samp(visits, popmean=3, alternative='greater'))
# 3. 配对检验
pre_sale = np.random.lognormal(3.5, 0.3, 30)
post_sale = pre_sale * 1.1 + np.random.normal(0, 0.1, 30)
print(stats.ttest_rel(post_sale, pre_sale))
8. 进阶技巧
8.1 功效分析
确定所需样本量:
from statsmodels.stats.power import TTestIndPower
effect_size = 0.5
alpha = 0.05
power = 0.8
analysis = TTestIndPower()
sample_size = analysis.solve_power(effect_size, power=power, alpha=alpha)
print(f"所需样本量: {sample_size:.0f}")
8.2 贝叶斯t检验
import pymc3 as pm
with pm.Model():
mu = pm.Normal('mu', mu=0, sd=10)
obs = pm.Normal('obs', mu=mu, sd=1, observed=diffs)
trace = pm.sample(2000)
pm.plot_posterior(trace)
在实际项目中,t检验结果需要结合业务背景解读。比如p=0.06时,虽然统计学上不显著,但从业务角度可能仍值得关注。建议同时报告置信区间:
ci = stats.t.interval(0.95, len(drinks)-1, loc=drinks.mean(), scale=stats.sem(drinks))
print(f"95%置信区间: ({ci[0]:.2f}, {ci[1]:.2f})")
更多推荐
所有评论(0)