ThinkStats2项目中的随机抽样与统计推断实践指南
随机抽样基础概念
在统计学中,随机抽样是从总体中选取样本的基本方法,它允许我们通过对样本的分析来推断总体特征。ThinkStats2项目通过Python实现了一系列随机抽样和统计推断的实践案例,帮助我们理解这一核心统计概念。
准备工作环境
首先我们需要导入必要的Python库并设置随机数种子以保证结果可复现:
import numpy as np
import scipy.stats
import matplotlib.pyplot as plt
from ipywidgets import interact
设置随机数种子:
np.random.seed(18) # 确保每次运行结果一致
女性体重分布建模
项目中使用BRFSS数据,发现美国女性体重(kg)服从对数正态分布:
# 创建对数正态分布对象
female_weight = scipy.stats.lognorm(0.23, 0, 70.8)
print(f"均值: {female_weight.mean():.1f} kg, 标准差: {female_weight.std():.1f} kg")
可视化这个分布:
xs = np.linspace(20, 160, 100)
ys = female_weight.pdf(xs)
plt.plot(xs, ys)
plt.xlabel('体重 (kg)')
plt.ylabel('概率密度')
plt.title('美国女性体重分布')
plt.show()
抽样与样本统计量
创建随机样本
定义生成样本的函数:
def make_sample(n=100):
"""从已知分布生成随机样本"""
return female_weight.rvs(n)
生成并检查样本:
sample = make_sample(100)
print(f"样本均值: {sample.mean():.1f} kg, 样本标准差: {sample.std():.1f} kg")
计算抽样分布
定义计算样本统计量的函数:
def sample_stat(sample):
"""计算样本统计量(此处为均值)"""
return sample.mean()
def compute_sampling_distribution(n=100, iters=1000):
"""模拟多次实验,收集样本统计量"""
return np.array([sample_stat(make_sample(n)) for _ in range(iters)])
运行模拟:
sample_means = compute_sampling_distribution(n=100, iters=1000)
分析抽样分布
可视化样本均值的分布:
plt.hist(sample_means, bins=30, alpha=0.7)
plt.xlabel('样本均值 (n=100)')
plt.ylabel('频数')
plt.title('样本均值的抽样分布')
plt.show()
计算标准误差和置信区间:
std_err = sample_means.std()
conf_int = np.percentile(sample_means, [5, 95])
print(f"标准误差: {std_err:.2f} kg")
print(f"90%置信区间: [{conf_int[0]:.2f}, {conf_int[1]:.2f}] kg")
交互式探索样本大小影响
创建交互式可视化函数:
def plot_sampling_distribution(n, xlim=None):
"""绘制不同样本量下的抽样分布"""
stats = compute_sampling_distribution(n)
se = stats.std()
ci = np.percentile(stats, [5, 95])
plt.hist(stats, bins=30, alpha=0.7)
plt.xlabel('样本统计量')
if xlim: plt.xlim(xlim)
plt.text(0.05, 0.9, f'CI [{ci[0]:.2f}, {ci[1]:.2f}]', transform=plt.gca().transAxes)
plt.text(0.05, 0.8, f'SE {se:.2f}', transform=plt.gca().transAxes)
plt.show()
创建交互控件:
interact(plot_sampling_distribution,
n=widgets.IntSlider(min=10, max=1000, value=100),
xlim=fixed([55, 95]))
扩展其他统计量
我们可以轻松扩展这个框架来计算其他统计量的抽样分布:
- 标准差:
def sample_std(sample):
return sample.std()
- 中位数:
def sample_median(sample):
return np.median(sample)
- 百分位数:
def sample_percentile(sample, p=10):
return np.percentile(sample, p)
重抽样技术
当总体分布未知时,我们可以使用重抽样技术:
class Resampler:
"""实现自助法重抽样"""
def __init__(self, sample):
self.sample = sample
self.n = len(sample)
def resample(self):
"""有放回地重抽样"""
return np.random.choice(self.sample, self.n, replace=True)
def compute_sampling_dist(self, stat_func, iters=1000):
"""计算统计量的抽样分布"""
return np.array([stat_func(self.resample()) for _ in range(iters)])
使用示例:
# 从原始样本创建重抽样器
resampler = Resampler(female_sample)
# 计算均值的抽样分布
mean_dist = resampler.compute_sampling_dist(np.mean)
# 计算标准差的抽样分布
std_dist = resampler.compute_sampling_dist(np.std)
两样本比较
比较男女体重差异:
# 生成男性样本
male_weight = scipy.stats.lognorm(0.20, 0, 87.3)
male_sample = male_weight.rvs(100)
# 计算差异
mean_diff = male_sample.mean() - female_sample.mean()
print(f"平均差异: {mean_diff:.1f} kg")
# Cohen's d效应量
def cohens_d(group1, group2):
diff = group1.mean() - group2.mean()
pooled_var = (len(group1)*group1.var() + len(group2)*group2.var()) / (len(group1)+len(group2))
return diff / np.sqrt(pooled_var)
print(f"Cohen's d: {cohens_d(male_sample, female_sample):.2f}")
实践建议
-
样本量选择:随着样本量增大,标准误差减小,但减小速度与√n成反比
-
统计量选择:
- 均值对异常值敏感
- 中位数更稳健但效率较低
- 根据研究问题选择合适的统计量
-
重抽样次数:
- 通常1000次足够
- 计算密集型统计量可适当减少
- 需要高精度时可增加
-
结果解释:
- 置信区间反映估计的不确定性
- 标准误差衡量估计的精确度
- 效应量提供标准化差异度量
通过ThinkStats2项目的这些实践,我们能够深入理解抽样分布的概念,掌握统计推断的基本方法,为实际数据分析工作打下坚实基础。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考