Skip to content

元数据卡

  • 前置知识:第3章(EDA)、数学基础 B(概率/统计)
  • 预计时间:50 分钟
  • 核心难度:进阶
  • 阅读模式:高度专注
  • 完成标志:能对两组数据做假设检验并正确解释 p 值和置信区间

你的进度

你用 SQL 查出了具体数字:堡垒 A 的任务完成率是 83%,堡垒 B 是 79%,差 4 个百分点。

但这个差距有意义吗?如果明天再统计一次,结果会不会反过来?你发现了一个更根本的问题——你手里拿到的不等于真相。你看到的 83% 可能只是随机波动。

你需要统计推断——从样本中判断总体。

你的任务

你在 EDA 中发现:采用新训练方案的任务组,成功率似乎比旧方案高 5 个百分点。但这个差异是真实的改进,还是随机波动?你面对的问题可以概括为:我们观察到的差异,有多少是信号,多少是噪音?统计推断给你一套判断框架。


从描述到推断

EDA 告诉你样本是什么样。统计推断帮你回答:样本背后总体的真相是什么。

python
import numpy as np
import pandas as pd
from scipy import stats

# 加载数据
df = pd.read_csv("missions_clean.csv")

# 两组:旧方案 vs 新方案
old = df[df["training"] == "old"]["success_rate"]
new = df[df["training"] == "new"]["success_rate"]

print(f"旧方案: 均值={old.mean():.3f}, 标准差={old.std():.3f}, n={len(old)}")
print(f"新方案: 均值={new.mean():.3f}, 标准差={new.std():.3f}, n={len(new)}")

你看到新方案均值高了 0.05(5 个百分点)。但这 5 个百分点可能来自:

  • 真实效果(训练方案确实更好)
  • 随机抽样(碰巧新方案组的数据点表现更好)
  • 混杂因素(新方案组的任务本身更简单)

统计推断帮你区分前两种可能性。

置信区间

置信区间告诉你:如果重复采样很多次,真实的总体均值有 95% 的概率落在这个区间里。

python
def confidence_interval(data, confidence=0.95):
    n = len(data)
    mean = np.mean(data)
    se = stats.sem(data)  # 标准误 = 标准差 / sqrt(n)
    h = se * stats.t.ppf((1 + confidence) / 2, n - 1)
    return mean - h, mean + h

ci_old = confidence_interval(old)
ci_new = confidence_interval(new)
print(f"旧方案 95% CI: ({ci_old[0]:.3f}, {ci_old[1]:.3f})")
print(f"新方案 95% CI: ({ci_new[0]:.3f}, {ci_new[1]:.3f})")

如果两个置信区间不重叠,那两组存在显著差异。如果重叠,样本量不足以判断差异是否来自真实效果。

假设检验

形式化的判断流程。你提出两个竞争假设:

  • 零假设 H0:两个方案的成功率没有差异(观测到的差异来自随机波动)
  • 备择假设 H1:两个方案的成功率有差异

然后用 t 检验计算 p 值:

python
t_stat, p_value = stats.ttest_ind(new, old, equal_var=False)
print(f"t 统计量: {t_stat:.3f}")
print(f"p 值: {p_value:.4f}")

p 值的意思是:假设零假设为真,你看到当前数据(或更极端的数据)的概率。如果 p 值小于你预设的显著性水平(通常是 0.05),你拒绝零假设,认为差异有统计学意义。

p 值的四个陷阱

  1. p 值不是"零假设为真的概率"。这是最常见的误解。p 值说的是"在零假设下看到当前数据的概率",不是"零假设成立的概率"。

  2. p 值受样本量影响极大。样本量很大时,即使是微不足道的差异也能达到 p < 0.05。样本量很小时,有意义的差异可能 p > 0.05。

  3. 多重比较问题。你在 100 列上做假设检验,期望会有 5 个因随机而显著(显著性水平 0.05)。不做校正的话,你找到的"显著相关"可能只是噪音。

  4. p 值不告诉你效应量。p < 0.001 可能对应的实际差异只有 0.01%。统计显著不等于实际显著。

效应量

p 值告诉你"有没有差异",效应量告诉你"差异多大"。

python
# Cohen's d: 两组均值差 / 合并标准差
def cohens_d(group1, group2):
    n1, n2 = len(group1), len(group2)
    s1, s2 = np.var(group1, ddof=1), np.var(group2, ddof=1)
    pooled_std = np.sqrt(((n1 - 1) * s1 + (n2 - 1) * s2) / (n1 + n2 - 2))
    return (np.mean(group1) - np.mean(group2)) / pooled_std

d = cohens_d(new, old)
print(f"Cohen's d: {d:.3f}")

经验判断:|d| ≈ 0.2 小效应,≈ 0.5 中等,≈ 0.8 大效应。有了效应量,你才能判断差异是否在实际场景中有意义。

决策流程

完整的统计推断决策流程:

  1. 选检验方法:两组独立样本 → t 检验,配对样本 → 配对 t 检验,三组以上 → ANOVA,类别变量 → 卡方检验
  2. 设定显著性水平(通常 α = 0.05)
  3. 计算检验统计量和 p 值
  4. 计算效应量
  5. 报告结果时说明:差异方向、统计显著性(p 值)、实际显著性(效应量)、置信区间
python
# 完整报告
print("========== 统计推断报告 ==========")
print(f"旧方案成功率: {old.mean():.3f} (n={len(old)})")
print(f"新方案成功率: {new.mean():.3f} (n={len(new)})")
print(f"差异: {new.mean() - old.mean():.3f}")
print(f"95% CI 差异: ({ci_old[0]:.3f} ~ {ci_new[0]:.3f})")
print(f"t 检验: t={t_stat:.3f}, p={p_value:.4f}")
print(f"Cohen's d: {d:.3f}")
if p_value < 0.05:
    print("结论: 差异有统计学意义,但需结合效应量判断实际意义")
else:
    print("结论: 当前数据不足以拒绝零假设")

常见陷阱

  • 只看 p 值不看效应量。p = 0.001 但你发现实际差异只有 0.1%,你会怎么做?
  • 假设检验之前不做假设。在数据上反复测试,直到找到显著的 p 值——这是"p-hacking"。
  • 选错检验方法。用独立样本 t 检验分析配对数据,会使你损失统计功效。
  • 把"不拒绝零假设"当作"零假设为真"。样本量不够时你可能只是没有足够的证据。

通关挑战

  • 热身:自己生成两组随机数据(均值相同),跑 100 次 t 检验,统计多少次 p < 0.05。你期望看到多少?
  • 挑战:找一个包含两组数据的真实数据集,做从描述统计到假设检验到效应量的完整分析,写出一份结论报告。
  • 排障:你的假设检验显示 p = 0.06,但经理说"接近显著,就当显著吧"。你怎么解释为什么不能这样做?

验收标准

  • 能解释 p 值的准确含义和常见误解
  • 能根据数据类型选择正确的检验方法
  • 会在报告假设检验结果时给出 p 值和效应量
  • 知道 p-hacking 是什么以及为什么有害

旅人笔记

p 值给答案,效应量给大小,置信区间给范围。三者一起看,不要只取一个。


下一站预告

你已经能从样本推断总体了。但如果你想预测——根据现有数据预测一个新任务的成败——就需要下一章:线性回归。

Built with VitePress | Software Systems Atlas