统计分析 是做什么的?
概述
进行假设检验(t检验、ANOVA、卡方检验)、回归、相关分析和贝叶斯分析,并包含系统的假设检验、效应量和APA风格报告。目标是让分析结果经得起评审的检验:正确的检验方法、验证过的假设、诚实的效应量以及完整的报告。
何时使用此技能
在以下情况下使用此技能:
- 进行统计假设检验(t检验、ANOVA、卡方检验、非参数检验)
- 执行回归或相关分析
- 运行贝叶斯统计分析
- 检查统计假设和诊断
- 计算效应量并进行功效分析
- 以APA格式报告统计结果
- 分析研究中的实验或观测数据
安装
使用 uv 安装此技能所需的库。在生产环境中锁定版本;探索时可以不定版本。
# 核心频率论堆栈(Python 3.10+;推荐3.12+以获得最新的SciPy/ArviZ)
uv pip install "pingouin>=0.6" "scipy>=1.11" "statsmodels>=0.14.6" pandas matplotlib seaborn
# 贝叶斯建模(PyMC 5 + ArviZ)
uv pip install "pymc>=5.0" "arviz>=1.0"
兼容性说明(已验证于pingouin 0.6.1、statsmodels 0.14.6、arviz 1.2,2026年):
- Pingouin 0.6.0 重命名了输出列,移除了特殊字符:
p_val、cohen_d、CI95、p_unc(之前在0.5.x中为p-val、cohen-d、CI95%、p-unc)。以下示例使用当前名称;如果卡在0.5.x版本,请使用连字符形式。 - statsmodels + SciPy:使用
statsmodels>=0.14.6搭配scipy>=1.11以避免在SciPy 1.16+上出现_lazywhere导入错误。 - ArviZ 1.x:
az.summary()现在默认使用 89% 区间(eti89列),宽度参数为ci_prob(而非hdi_prob)。要报告传统的95%可信区间,请传递az.summary(trace, ci_prob=0.95)。 - Pingouin 中已移除单侧贝叶斯因子:
pg.ttest(..., alternative='greater')会静默丢弃BF10列,而pg.bayesfactor_ttest在单侧备择假设时会报错。对于单侧贝叶斯检验,请直接使用PyMC(计算方向性假设的后验概率)或JASP/R的BayesFactor。
有关模型特定API(OLS、GLM、ARIMA),请参阅 statsmodels 技能。有关PyCM工作流,请参阅 pymc 技能。
分析工作流
每一项可靠的分析都遵循相同的流程。跳过步骤是分析被撤回的原因,因此请按顺序进行,并在每一步说明你做了什么。
- 在接触数据之前明确问题。 陈述假设、结果变量和预测变量,以及设计(独立 vs. 配对,组数)。现在就确定一个计划好的检验——在看过结果后选择检验就是p-hacking,即使是无意的。
- 检查数据。 按组:n、均值、SD、中位数、缺失值。在进行任何检验之前,绘制原始数据(直方图或箱线图)。组大小不均等、缺失值、地板/天花板效应和异常值都会改变合适的检验方法——将这些情况告知用户,而不是默默绕过它们。
- 选择检验方法,参考下面的快速指南,对于超出基本设计的(计数、生存时间、信度、析因设计),请参阅
references/test_selection_guide.md。 - 检查假设,使用
scripts/assumption_checks.py。如果假设不成立,切换到补救检验(参见下表),并同时报告原计划和变更情况。 - 运行检验,并始终同时计算效应量——p值说明效应存在;效应量则说明是否值得关注。
- 报告,使用下方的APA模板,包括描述性统计、精确统计量、带有置信区间的效应量以及所进行的假设检验。
如果用户只需要一步(例如,“我需要多少参加者?”),直接跳转到该部分——但还是要确认该计算所依赖的设计假设。
检验选择指南
快速参考:选择正确的检验
全面的指导(计数、生存、信度、析因设计)请使用 references/test_selection_guide.md。快速参考:
比较两组:
- 独立、连续、正态 → 独立样本t检验
- 独立、连续、非正态 → Mann-Whitney U检验
- 配对、连续、正态 → 配对样本t检验
- 配对、连续、非正态 → Wilcoxon符号秩检验
- 二分类结果 → 卡方检验或Fisher精确检验
比较3组及以上:
- 独立、连续、正态 → 单因素方差分析
- 独立、连续、非正态 → Kruskal-Wallis检验
- 配对、连续、正态 → 重复测量方差分析
- 配对、连续、非正态 → Friedman检验
关系:
- 两个连续变量 → Pearson相关(正态)或Spearman相关(非正态)
- 连续结果与预测变量 → 线性回归
- 二分类结果与预测变量 → 逻辑回归
贝叶斯替代方案:
所有检验都有贝叶斯版本,提供关于假设的直接概率陈述、量化证据的贝叶斯因子,并且能够支持零假设。参见 references/bayesian_statistics.md。
假设检验
在解释检验结果之前始终检查假设,并报告检查情况——评审人会关注这些。
使用附带的 scripts/assumption_checks.py 模块。从技能目录(skills/statistical-analysis/)运行Python,或将 scripts/ 添加到 sys.path:
from assumption_checks import comprehensive_assumption_check
# 异常值 + 正态性(按组) + 方差齐性,包含绘图
results = comprehensive_assumption_check(
data=df,
value_col='score',
group_col='group', # 可选:用于组间比较
alpha=0.05
)
对于针对性检查,导入单个函数:
from assumption_checks import (
check_normality, # Shapiro-Wilk + Q-Q图 + 直方图
check_normality_per_group,
check_homogeneity_of_variance, # Levene检验 + 箱线图
check_linearity, # 简单回归的散点图 + 残差图
check_regression_diagnostics, # 完整OLS诊断(见回归部分)
detect_outliers # IQR或z-score方法
)
result = check_normality(data=df['score'], name='测试分数', alpha=0.05, plot=True)
print(result['interpretation'])
print(result['recommendation'])
假设被违反时的处理
正态性违反:
- 轻微违反 + 每组 n > 30 → 继续使用参数检验(稳健)
- 中度违反 → 使用非参数替代方法
- 严重违反 → 变换数据或使用非参数检验
方差齐性违反:
- 对于t检验 → 使用Welch t检验(
pg.ttest默认使用correction='auto'自动应用) - 对于方差分析 → 使用Welch方差分析(
pg.welch_anova)或Brown-Forsythe检验 - 对于回归 → 使用稳健标准误或加权最小二乘法
线性违反(回归):
- 添加多项式项、变换变量或使用非线性模型/GAM
正式检验随着n增大而变得过于敏感:对于 n ≥ 100,应更看重Q-Q图而非Shapiro-Wilk p值。全面指导请参阅 references/assumptions_and_diagnostics.md。
运行统计检验
主要库:
- pingouin:用户友好的检验,默认返回效应量——标准检验首选
- scipy.stats:核心统计检验
- statsmodels:回归、诊断、功效分析
- pymc + arviz:贝叶斯建模和诊断
包含完整报告的T检验
import pingouin as pg
# correction='auto' 在方差不相等时应用Welch校正
result = pg.ttest(group_a, group_b, correction='auto')
# Pingouin >= 0.6 列名
t_stat = result['T'].values[0]
df = result['dof'].values[0]
p_value = result['p_val'].values[0]
cohens_d = result['cohen_d'].values[0]
ci_lower, ci_upper = result['CI95'].values[0] # 均值差的置信区间
print(f"t({df:.0f}) = {t_stat:.2f}, p = {p_value:.3f}, d = {cohens_d:.2f}")
含事后检验的方差分析
import pingouin as pg
aov = pg.anova(dv='score', between='group', data=df, detailed=True)
print(aov)
# 效应量:偏eta平方
eta_p2 = aov['np2'].values[0]
# 如果显著,进行事后检验(Tukey HSD控制族系误差率)
if aov['p_unc'].values[0] < 0.05:
posthoc = pg.pairwise_tukey(dv='score', between='group', data=df)
print(posthoc) # 包含每对的Hedges' g
含诊断的线性回归
import statsmodels.api as sm
from assumption_checks import check_regression_diagnostics
X = sm.add_constant(X_predictors) # 添加截距
model = sm.OLS(y, X).fit()
print(model.summary())
# 4面板残差图 + Shapiro-Wilk、Breusch-Pagan、Durbin-Watson、VIF
diag = check_regression_diagnostics(model)
print(diag['interpretation'])
print(diag['vif'])
# 如果标记了异方差性,报告稳健标准误
robust = model.get_robustcov_results('HC3')
贝叶斯T检验
import pymc as pm
import arviz as az
import numpy as np
with pm.Model() as model:
# 先验
mu1 = pm.Normal('mu_group1', mu=0, sigma=10)
mu2 = pm.Normal('mu_group2', mu=0, sigma=10)
sigma = pm.HalfNormal('sigma', sigma=10)
# 似然
y1 = pm.Normal('y1', mu=mu1, sigma=sigma, observed=group_a)
y2 = pm.Normal('y2', mu=mu2, sigma=sigma, observed=group_b)
# 衍生量
diff = pm.Deterministic('difference', mu1 - mu2)
trace = pm.sample(2000, tune=1000)
# ArviZ 1.x 默认使用89%区间;为报告显式请求95%
print(az.summary(trace, var_names=['difference'], ci_prob=0.95))
# 直接概率陈述(这就是单侧问题的回答方式)
prob_greater = np.mean(trace.posterior['difference'].values > 0)
print(f"P(mu1 > mu2 | data) = {prob_greater:.3f}")
# ArviZ 1.x 移除了 az.plot_posterior;使用 plot_dist(在0.x上,plot_posterior仍然有效)
az.plot_dist(trace, var_names=['difference'], ci_prob=0.95)
将先验尺度调整为数据(例如,sigma=10 适用于SD接近10的结果;使用观测到的SD作为指导)并在报告中说明先验。
效应量
效应量量化幅度;p值仅指示存在性。 每次检验都报告效应量。完整指南请参见 references/effect_sizes_and_power.md。
快速参考:常见效应量
| 检验 | 效应量 | 小 | 中 | 大 |
|---|---|---|---|---|
| T检验 | Cohen's d | 0.20 | 0.50 | 0.80 |
| 方差分析 | η²_p | 0.01 | 0.06 | 0.14 |
| 相关 | r | 0.10 | 0.30 | 0.50 |
| 回归 | R² | 0.02 | 0.13 | 0.26 |
| 卡方检验 | Cramér's V | 0.07 | 0.21 | 0.35 |
基准是约定俗成的,并非定律——一个“小”效应可能极其重要(药物副作用),而一个“大”效应可能微不足道。需结合上下文解释。
计算效应量
Pingouin 随其检验返回效应量(pg.ttest 返回 cohen_d,pg.anova 返回 np2,pg.pairwise_tukey 返回 hedges;pg.corr 的 r 本身就是一个效应量)。
效应量的置信区间
报告效应量的置信区间以显示其精度。使用 pg.compute_esci(注意:pg.compute_effsize_from_t 仅返回点估计——它 不 返回置信区间):
import pingouin as pg
d = pg.compute_effsize(group_a, group_b, eftype='cohen')
ci_lower, ci_upper = pg.compute_esci(stat=d, nx=len(group_a), ny=len(group_b),
eftype='cohen', confidence=0.95)
print(f"d = {d:.2f}, 95% CI [{ci_lower:.2f}, {ci_upper:.2f}]")
功效分析
先验功效分析(研究规划)
在收集数据前确定所需样本量:
from statsmodels.stats.power import tt_ind_solve_power, FTestAnovaPower
# T检验:检测 d = 0.5 需要每组多少样本?
n_required = tt_ind_solve_power(
effect_size=0.5,
alpha=0.05,
power=0.80,
ratio=1.0,
alternative='two-sided'
)
print(f"每组所需样本量: {n_required:.0f}")
# 单因素方差分析:检测 Cohen's f = 0.25 需要多少样本?
# 注意:参数是 k_groups;effect_size 是 Cohen's f(f = sqrt(eta2/(1-eta2)));
# solve_power 返回 TOTAL 样本量,而非每组样本量。
import math
anova_power = FTestAnovaPower()
n_total = anova_power.solve_power(
effect_size=0.25,
k_groups=3,
alpha=0.05,
power=0.80
)
print(f"所需总样本量: {math.ceil(n_total)} (每组 {math.ceil(n_total / 3)})")
敏感性分析(事后)
确定研究能够检测到的效应量:
# 每组 n=50,在80%功效下能检测到多大的效应?
detectable_d = tt_ind_solve_power(
effect_size=None, # 求解此值
nobs1=50,
alpha=0.05,
power=0.80,
ratio=1.0,
alternative='two-sided'
)
print(f"研究能检测到 d >= {detectable_d:.2f}")
注意:事后“观测功效”(根据观测到的效应计算功效)是循环论证且具有误导性的——它是p值的确定性函数。如果研究已完成且有人询问功效,请改为进行敏感性分析。
详细指导请参见 references/effect_sizes_and_power.md。
报告结果
遵循 references/reporting_standards.md 的APA风格。每份报告需要:
- 描述性统计:所有组/变量的平均值(M)、标准差(SD)、样本量(n)
- 检验统计量:检验名称、统计量、自由度、精确p值(如
p = .034,而非p < .05;仅在低于.001时使用p < .001) - 效应量:带有置信区间
- 假设检验:运行了哪些检验、结果以及采取的行动
- 所有计划内的分析:包括不显著的结果——省略它们就是摘樱桃。
示例报告模板
独立样本T检验
A组(n = 48, M = 75.2, SD = 8.5)的得分显著高于
B组(n = 52, M = 68.3, SD = 9.2),t(98) = 4.21,p < .001,
Cohen's d = 0.79,95% CI [0.38, 1.19]。
正态性假设通过Shapiro-Wilk检验(p > .05)得到满足;
方差齐性通过Levene检验(F = 0.82, p = .367)得到满足。
单因素方差分析
单因素方差分析显示三组间差异显著:F(2, 147) = 6.83,p = .001,
η²_p = 0.08,90% CI [0.02, 0.16]。
Tukey HSD事后检验显示,处理组(M = 22.4, SD = 4.1)
与对照组(M = 18.7, SD = 3.9)之间存在显著差异,
p = .012,Hedges' g = 0.91,95% CI [0.49, 1.33]。
贝叶斯T检验
贝叶斯独立样本t检验表明有实质性证据支持
A组(M = 102.3, SD = 15.2)均值大于
B组(M = 94.1, SD = 14.8),
后验概率 P(μ_A > μ_B | 数据) = 0.97。
均值差的后验中位数为 8.2,
95% 可信区间 [1.7, 14.9]。
先验设为 μ ~ Normal(0, 10²),σ ~ HalfNormal(10)。
补充说明
- 初始数据检查阶段始终包括可视化(直方图、箱线图)和分组描述性统计。
- 在分析报告中明确说明p值是否已针对多重比较进行校正以及采用了何种校正方法。
- 当选择不同检验方法时,解释选择背后的理由。
- 不显著的结果(p > .05)应以精确p值(如
p = .234)报告,并提供效应量和置信区间。 - 避免使用显著性星号(
*);提供完整的统计报告。 - 使用
FTestAnovaPower时注意其名称拼写。 - 对于更专业的设计,请参阅相关参考文件;此技能侧重于标准检验。