ThinkStats2 项目解析:效应量(Effect Size)的统计分析与可视化
引言
在统计学中,效应量(Effect Size)是衡量两组数据差异程度的重要指标。与仅关注统计显著性的p值不同,效应量能告诉我们差异的实际大小。本文将基于ThinkStats2项目中的案例,深入解析效应量的计算方法及其实际意义。
准备工作
首先我们需要导入必要的Python库并设置随机种子以保证结果可复现:
import numpy
import scipy.stats
import matplotlib.pyplot as plt
from ipywidgets import interact, interactive, fixed
import ipywidgets as widgets
# 设置随机种子
numpy.random.seed(17)
案例背景:男女身高差异分析
我们将使用美国行为风险因素监测系统(BRFSS)的数据,分析成年男女的身高差异。假设:
- 男性身高服从均值为178cm,标准差为7.7cm的正态分布
- 女性身高服从均值为163cm,标准差为7.3cm的正态分布
mu1, sig1 = 178, 7.7
male_height = scipy.stats.norm(mu1, sig1)
mu2, sig2 = 163, 7.3
female_height = scipy.stats.norm(mu2, sig2)
可视化身高分布
定义一个辅助函数来评估概率密度函数(PDF):
def eval_pdf(rv, num=4):
mean, std = rv.mean(), rv.std()
xs = numpy.linspace(mean - num*std, mean + num*std, 100)
ys = rv.pdf(xs)
return xs, ys
绘制两个分布曲线:
xs, ys = eval_pdf(male_height)
plt.plot(xs, ys, label='男性', linewidth=4, color='C0')
xs, ys = eval_pdf(female_height)
plt.plot(xs, ys, label='女性', linewidth=4, color='C1')
plt.xlabel('身高 (cm)')
plt.legend()
从图中可以直观看到两个分布有明显的差异。
生成随机样本
从这两个分布中各生成1000个随机样本:
male_sample = male_height.rvs(1000)
female_sample = female_height.rvs(1000)
计算样本统计量:
male_mean, male_std = male_sample.mean(), male_sample.std()
female_mean, female_std = female_sample.mean(), female_sample.std()
效应量的度量方法
1. 均值差异
最直观的方法是计算两组均值的绝对差异:
difference_in_means = male_mean - female_mean
# 结果约为15cm
但这种方法有两个问题:
- 难以直观判断差异大小
- 依赖于测量单位,不便跨研究比较
2. 相对差异
将差异表示为均值的百分比:
relative_diff = difference_in_means / male_mean * 100
# 结果约为8.4%
但相对差异取决于选择哪个均值作为基准。
3. 分布重叠度
计算两个分布的重叠区域可以更直观理解差异大小:
# 计算阈值(两分布交点)
thresh = (male_std*female_mean + female_std*male_mean) / (male_std + female_std)
# 计算误分类率
male_below = sum(male_sample < thresh)
female_above = sum(female_sample > thresh)
misclassification = (male_below + female_above) / 2000
# 结果约为0.2
这意味着如果仅凭身高判断性别,错误率约为20%。
4. 优势概率
随机选取一男一女,男性更高的概率:
(male_sample > female_sample).mean()
# 结果约为0.92
5. Cohen's d值
最常用的标准化效应量指标:
def CohenEffectSize(group1, group2):
diff = group1.mean() - group2.mean()
n1, n2 = len(group1), len(group2)
var1, var2 = group1.var(), group2.var()
pooled_var = (n1*var1 + n2*var2)/(n1+n2)
return diff / numpy.sqrt(pooled_var)
CohenEffectSize(male_sample, female_sample)
# 结果约为1.9
效应量可视化工具
创建一个交互式工具帮助理解不同d值的含义:
def plot_pdfs(cohen_d=2):
control = scipy.stats.norm(0, 1)
treatment = scipy.stats.norm(cohen_d, 1)
# 绘图代码...
slider = widgets.FloatSlider(min=0, max=4, value=2)
interact(plot_pdfs, cohen_d=slider)
通过滑动条可以直观看到不同d值对应的分布重叠情况和优势概率。
效应量的选择指南
- 均值差异:单位有意义时使用
- 相对差异:需要比例解释时使用
- 重叠度/误分类率:面向普通读者解释
- 优势概率:直观的概率解释
- Cohen's d:学术研究标准化比较
结论
ThinkStats2项目通过这个案例展示了多种效应量度量方法及其适用场景。在实际应用中,应根据受众和目的选择合适的指标。技术性强的研究可能偏好Cohen's d,而面向大众的解释可能更适合使用误分类率或优势概率等更直观的指标。
理解效应量对于科学研究和数据分析至关重要,它帮助我们超越统计显著性,关注实际差异的大小和意义。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考