抽样


文档摘要

抽样 抽样(sampling)决定了我们如何收集数据,也就直接决定了我所能得出的每一个结论的质量。本文件涵盖随机抽样、分层抽样、整群抽样和系统抽样、抽样分布、大数定律以及自助法,这些方法对 ML 中的训练/测试集划分和数据集构建至关重要。 在理想世界里,你会去测量你所关心的群体的每一个成员。但在实践中,这几乎不可能。你无法调查每一位选民、测试每一只灯泡、扫描每一位病人。所以你抽取一个样本(sample),再用它来了解整体。 总体(population)是你想研究的全部个体或物品的完整集合。样本是你实际观测的那个子集。 参数(parameter)是描述总体的一个数字(例如某个国家所有成年人的真实平均身高)。

抽样

抽样(sampling)决定了我们如何收集数据,也就直接决定了我所能得出的每一个结论的质量。本文件涵盖随机抽样、分层抽样、整群抽样和系统抽样、抽样分布、大数定律以及自助法,这些方法对 ML 中的训练/测试集划分和数据集构建至关重要。

  • 在理想世界里,你会去测量你所关心的群体的每一个成员。但在实践中,这几乎不可能。你无法调查每一位选民、测试每一只灯泡、扫描每一位病人。所以你抽取一个样本(sample),再用它来了解整体。

  • **总体(population)**是你想研究的全部个体或物品的完整集合。样本是你实际观测的那个子集。

  • **参数(parameter)**是描述总体的一个数字(例如某个国家所有成年人的真实平均身高)。

  • **统计量(statistic)**是从你的样本中算出来的一个数字(例如你测量的那 500 个人的平均身高)。统计量被用来估计参数。

  • 你的结论质量完全取决于你如何挑选样本。有偏的样本会导致有偏的结论,无论你的分析多么精巧都无济于事。

  • **抽样框(sampling frame)**是你实际从中抽取样本的全部个体的清单。理想情况下它与总体完全吻合,但现实中总有缺口。

  • 例如,如果你通过电话调查,就会漏掉所有没有电话的人。抽样框与总体之间的差异称为覆盖误差(coverage error)

  • **抽样误差(sampling error)**是样本统计量与总体参数之间天然存在的偏差。

  • 即便是一个完全随机的样本,也不可能和总体丝毫不差。样本越大,抽样误差越小。

  • 抽样大致分两大家族:概率抽样和非概率抽样。

  • **概率抽样(probability sampling)**意味着总体中的每一个成员都有已知的、非零的被选中机会。这让你能够量化不确定性并把结果推广开来。

  • 简单随机抽样(simple random sampling):每个个体被选中的机会相等,且每一种大小为 n 的可能样本都同样可能出现。可以想象把所有名字放进帽子里然后蒙眼抽取。

  • 分层抽样(stratified sampling):根据某个共同特征(例如年龄段、地区)把总体划分成若干互不重叠的组(层,strata),再从每一层里随机抽样。这能保证每个组都被代表到,并且当各层之间差异较大时可以减小方差。

  • 整群抽样(cluster sampling):把总体分成若干组(群,clusters),随机选中其中一些群,然后把被选中群里的所有人都纳入样本。当总体在地理上分布很广时,这样做很实用,比如整校整校地抽样,而不是跨区逐个学生地抽。

  • 系统抽样(systematic sampling):随机选一个起点,然后从清单里每隔 k 个取一个。例如从第 7 个人开始,然后每隔 10 个人取一个(7、17、27……)。实现简单,但如果清单里暗藏某种规律,就可能引入偏差。

三种概率抽样方法并排展示:简单随机抽样、分层抽样和整群抽样

  • **非概率抽样(non-probability sampling)**不给每个成员一个已知的被选中机会。结果无法严格地推广,但这些方法通常更快也更便宜。

  • 方便抽样(convenience sampling):选最容易接触到的人。在购物中心调查路人很方便,但会漏掉那些不来购物的人。

  • 配额抽样(quota sampling):类似分层抽样,但没有随机性。研究者通过从每个组里挑选容易接触到的个体来填满配额(例如 50 名男性和 50 名女性)。

  • 滚雪球抽样(snowball sampling):从几位参与者开始,请他们再去招募其他人。适合用于难以接触的群体(例如研究罕见病),但严重偏向那些社交上更连通的人。

  • 一旦选定抽样方法,一个自然的问题就出现了:如果我换一个样本,会得到不同的统计量吗?几乎肯定会。**抽样分布(sampling distribution)**就是某个统计量(比如样本均值)在所有同等大小的可能样本上的分布。

  • 想象你抽取 1,000 个不同的样本,每个 30 人,然后算每个样本的平均身高。这 1,000 个均值就构成一个分布。有些会比真实的总体均值略高,有些略低,而大多数会聚集在真值附近。

  • 这个抽样分布的标准差称为标准误(standard error)

SE = \frac{\sigma}{\sqrt{n}}
  • 注意,标准误随着 n 增大而缩小。样本越大,估计越精确。样本量翻两番,标准误减半。

  • 统计学中最重要的结论是中心极限定理(central limit theorem,CLT)。它说:不管原始总体是什么形状,只要样本量增大,样本均值的分布就会逼近正态分布。

中心极限定理:一个偏斜的总体也能产生近似正态分布的样本均值

  • 更精确地说,如果 X_1, X_2, \ldots, X_n 是来自任意一个均值为 \mu、方差有限为 \sigma^2 的分布的独立观测,那么随着 n 增大:
\bar{X} \approx \text{Normal}\!\left(\mu, \frac{\sigma^2}{n}\right)
  • 中心极限定理是大多数推断性统计得以成立的根基。它让我们即使底层数据并不正态,只要样本足够大,也能用正态分布来近似。

  • 多大才算「足够大」?一个常用的经验法则是 n \ge 30,但这取决于总体偏离正态的程度。对于高度偏斜的分布,可能需要更多。对于大致对称的总体,即便 n = 10 也可能够用。

  • 中心极限定理有三个关键条件:

    • 独立性(independence):每个观测都不能影响其他观测
    • 方差有限(finite variance):总体方差必须存在(这排除了某些特殊的分布)
    • 同分布(identical distribution):所有观测都来自同一个分布

编程练习(使用 CoLab 或 notebook)

  1. 用可视化的方式演示中心极限定理:从一个高度偏斜的分布中抽样,计算样本均值,观察均值直方图如何变成钟形。
import jax import jax.numpy as jnp import matplotlib.pyplot as plt key = jax.random.PRNGKey(0) # 指数分布(非常偏斜) population = jax.random.exponential(key, shape=(100_000,)) fig, axes = plt.subplots(1, 4, figsize=(14, 3)) sample_sizes = [1, 5, 30, 100] for ax, n in zip(axes, sample_sizes): keys = jax.random.split(key, 2000) means = jnp.array([jax.random.choice(k, population, shape=(n,)).mean() for k in keys]) ax.hist(means, bins=40, color="#3498db", alpha=0.7, density=True) ax.set_title(f"n = {n}") ax.set_xlim(0, 4) fig.suptitle("CLT: sample means become normal as n increases", fontsize=13) plt.tight_layout() plt.show()
  1. 比较简单随机抽样与分层抽样。构造一个带有明显分组的总体,展示分层抽样能给出方差更低的估计。
import jax import jax.numpy as jnp key = jax.random.PRNGKey(42) # 总体:两个差异明显的组 group_a = jax.random.normal(key, shape=(500,)) + 10 # 均值约 10 key, subkey = jax.random.split(key) group_b = jax.random.normal(subkey, shape=(500,)) + 20 # 均值约 20 population = jnp.concatenate([group_a, group_b]) # 简单随机抽样:1000 次试验,每次样本量 20 srs_means = [] for i in range(1000): key, subkey = jax.random.split(key) sample = jax.random.choice(subkey, population, shape=(20,), replace=False) srs_means.append(sample.mean()) srs_means = jnp.array(srs_means) # 分层抽样:每组各抽 10 个 strat_means = [] for i in range(1000): key, k1, k2 = jax.random.split(key, 3) s_a = jax.random.choice(k1, group_a, shape=(10,), replace=False) s_b = jax.random.choice(k2, group_b, shape=(10,), replace=False) strat_means.append(jnp.concatenate([s_a, s_b]).mean()) strat_means = jnp.array(strat_means) print(f"Simple Random - Mean: {srs_means.mean():.3f}, Std: {srs_means.std():.3f}") print(f"Stratified - Mean: {strat_means.mean():.3f}, Std: {strat_means.std():.3f}") print(f"Stratified sampling reduced variance by {(1 - strat_means.var()/srs_means.var())*100:.1f}%")
  1. 探索样本量如何影响标准误。把标准误对样本量画出来,验证 1/\sqrt{n} 这个关系。
import jax import jax.numpy as jnp import matplotlib.pyplot as plt key = jax.random.PRNGKey(7) population = jax.random.normal(key, shape=(50_000,)) * 10 + 50 sample_sizes = [5, 10, 20, 50, 100, 200, 500, 1000] std_errors = [] for n in sample_sizes: means = [] for _ in range(500): key, subkey = jax.random.split(key) sample = jax.random.choice(subkey, population, shape=(n,)) means.append(sample.mean()) std_errors.append(jnp.array(means).std()) plt.figure(figsize=(8, 4)) plt.plot(sample_sizes, std_errors, "o-", color="#e74c3c", label="Observed SE") theoretical = population.std() / jnp.sqrt(jnp.array(sample_sizes, dtype=jnp.float32)) plt.plot(sample_sizes, theoretical, "--", color="#3498db", label="σ/√n (theoretical)") plt.xlabel("Sample size (n)") plt.ylabel("Standard error") plt.legend() plt.title("Standard error shrinks with larger samples") plt.show()

发布者: 作者: HenryNdubuaku 转发
评论区 (0)
U