广告

Python分层抽样与随机抽样实操教程:面向数据分析师的代码与案例

理解分层抽样与随机抽样的原理

分层抽样的定义与目标

在数据分析中,分层抽样是一种先将总体按某些特征划分为若干“层”再从每一层独立抽取样本的抽样方法。目标在于降低估计的方差,提高对总体参数的准确性,尤其在层内同质而层间异质的场景中效果显著。

通过对人口按属性如地区、年龄段或收入水平进行分层,可以实现更均衡的代表性,从而避免某些重要子群体在样本中被过度或不足地表示。此方法在市场调研、公共卫生和教育评估等场景中应用广泛,能够提升推断的稳定性与可解释性。

随机抽样的定义与应用

与分层抽样不同,简单随机抽样(随机抽样)强调从总体中以等概率抽取样本,确保每个单位被选中的机会相等。这种方法的核心优势是实现无偏估计,但在总体异质性较大时,估计方差可能较高。

在实际应用中,有放回与无放回的区别需要被明确:有放回可重复选中同一单位,便于理论分析;无放回则更贴近实际抽样过程,且通常需要根据总体规模来调整样本分配。掌握两者的权衡,有助于设计更高效的采样方案。

在Python中实现分层抽样与随机抽样的环境与数据准备

环境配置与依赖

进行<分层抽样与随机抽样的实操,建议使用 Python、pandas、numpy 等常用库。安装命令如 pip install pandas numpy,确保环境中具备数据处理与随机数生成功能。

本文示例将展示如何在一个虚拟数据集上完成分层抽样与随机抽样的代码实现。通过实际代码可以清晰感知样本分配、权重计算与抽样过程的逻辑。

数据集结构与字段说明

数据集通常包含若干字段,例如 id、地区 region、年龄 age、收入 income、目标变量 target。其中 地区与年龄段等列常作为分层变量,而目标变量则用于后续分析评估。

在进行抽样前,需要对数据进行基本清洗与类型校验,例如缺失值处理、分层变量的离散化(如将年龄分组)以及确保样本容量满足分析需求。

分层抽样的实操代码与示例

分层策略设计

分层抽样的核心步骤是先按分层变量将总体分组,然后在每一层中按份额分配样本数。常见的做法是按比例分配,如 n_h = round(N_h / N * n),其中 N_h 是第 h 层的样本容量,N 为总体容量,n 为总样本数。

设计分层策略时应考虑每层的方差与代表性,确保“信息量大”的层获得合适的样本比重。比例分配在总体分层均衡时效果理想,但当某层样本量很小或方差较大时,可能需要最优分配或分层内再抽样以控制方差。

实现分层抽样的Python代码

下面给出一个简化示例,演示如何从一个数据框中按地区分层并按比例抽样:

import pandas as pd
import numpy as np

# 假设 df 是原始数据,包含列 region, id
df = pd.DataFrame({
    'id': range(1, 101),
    'region': ['East']*25 + ['West']*25 + ['North']*25 + ['South']*25,
    'value': np.random.randn(100)
})

# 总样本数
n = 20

# 计算各层样本容量(比例分配)
N_h = df['region'].value_counts()
N = len(df)
n_h = (N_h / N * n).round().astype(int)

# 分层抽样
samples = []
for region, size in n_h.items():
    group = df[df['region'] == region]
    s = group.sample(n=size, random_state=42, replace=False)
    samples.append(s)

stratified_sample = pd.concat(samples).reset_index(drop=True)

stratified_sample.head(), stratified_sample.shape

在上述代码中,我们对 地区 region 进行分层,按比例分配样本,并保证每层的抽样是独立的。关键点包括对 N_h 的正确计算、n_h 的整数化以及避免样本不足以覆盖某一层的情况。

如果某一层的 n_h 计算为 0,可以调整为至少抽取 1 个样本以维持代表性,或对该层提高权重后再进行抽样。我们需要确保最终的 stratified_sample 能够代表整个总体的结构。

简单随机抽样与有放回/无放回的对比

简单随机抽样的实现

简单随机抽样(SRS)通过在总体中等概率地选取样本来实现。常用的实现方式是 使用 numpy.random.choice,并设置 replace=False 进行无放回抽样,确保没有重复样本。

也可以根据需要设置 replace=True 以实现有放回抽样,适用于当总体样本较小或需要模拟重复观测的场景。无放回通常能更贴近实际分析中的独立样本场景。

简单随机抽样的实现示例

以下示例展示如何从整个数据集中执行简单随机抽样:

import pandas as pd
import numpy as np

df = pd.DataFrame({'id': range(1, 101), 'feature': np.random.randn(100)})

n = 20

# 无放回简单随机抽样
sample_no_replacement = df.sample(n=n, random_state=0, replace=False)

# 有放回简单随机抽样
sample_with_replacement = df.sample(n=n, random_state=0, replace=True)

sample_no_replacement.shape, sample_with_replacement.shape

从结果可以看到,无放回抽样不会出现重复样本,而有放回抽样可能包含重复项。对于需要独立同分布假设的分析,通常优先选择 无放回 的方案。

值得注意的是,SRS 的方差在总体结构较为均衡时较低,但当某些子群体差异较大时,SRS 可能导致对某些子群体表示不足,因此在实际应用中常与分层抽样结合,形成更稳定的估计。

案例:数据分析师的分层与随机抽样应用场景

实际案例1:用户调查数据的分层抽样

在一个面向不同地区用户的满意度调查中,人口分布在东部、西部、北部和南部不均匀。通过分层抽样,我们先按地区划分层,然后在每个层内按比例抽样,从而确保每个地区都获得足够的样本以反映真实差异。

在实现过程中,我们可以将地区作为分层变量,并将样本容量按地区人口比例进行分配。这样既能控制总体估计的方差,又能避免某些区域被低估。

以下代码片段展示了如何在包含 region 与满意度字段的数据集中执行分层抽样并输出结果,用于后续的满意度分析与比对。

# 假设 df 包含 region 区域与 score 满意度列
df = pd.DataFrame({
    'id': range(1, 301),
    'region': np.repeat(['East','West','North','South'], 75),
    'score': np.random.uniform(1, 5, 300)
})

n = 60
N_h = df['region'].value_counts()
N = len(df)
n_h = (N_h / N * n).round().astype(int)

samples = []
for region, size in n_h.items():
    grp = df[df['region'] == region]
    s = grp.sample(n=size, random_state=123, replace=False)
    samples.append(s)

survey_sample = pd.concat(samples).reset_index(drop=True)
survey_sample.groupby('region')['score'].mean()

通过上述步骤,不同地区的样本均衡性得到提升,后续的满意度分析也更具可比性。该方法有助于避免区域偏倚,提高对总体的推断力。

实际案例2:市场研究数据的随机抽样对比

在市场研究中,研究者可能需要对某一新产品的潜在用户进行滚动抽样。随机抽样用于快速获得初步样本,但若总体包含明显的子群体差异,单一的随机样本可能不足以覆盖多样性。

组合方案可以先使用 分层抽样获得各子群体的代表性样本,再在每个层内进行随机抽样,以兼具代表性与分析灵活性。这样既保留了分层优势,又保留了随机性的好处。

下面的示例展示了从一个包含性别、地区、年龄的多属性数据集中,先进行分层抽样再在每层内进行简单随机抽样的混合方法。

# 假设 df 包含 region、gender、age、购买意愿 purchase
df = pd.DataFrame({
    'id': range(1, 501),
    'region': np.random.choice(['East','West','North','South'], 500),
    'gender': np.random.choice(['Male','Female'], 500),
    'age': np.random.randint(18, 65, 500),
    'purchase': np.random.binomial(1, 0.25, 500)
})

# 将年龄分组作为辅助分层变量
df['age_group'] = pd.cut(df['age'], bins=[17, 25, 35, 45, 55, 65], labels=['18-25','26-35','36-45','46-55','56-65'])

# 以 region 与 age_group 组成两级分层
strata = df.groupby(['region', 'age_group']).size()

N = len(df)
n = 150  # 总样本数
n_h = (strata / N * n).round().astype(int)

samples = []
for (region, age_group), size in n_h.items():
    grp = df[(df['region'] == region) & (df['age_group'] == age_group)]
    if len(grp) >= size:
        s = grp.sample(n=size, replace=False)
        samples.append(s)
    else:
        # 层样本不足,取整层的所有样本
        samples.append(grp)

mixed_sample = pd.concat(samples).reset_index(drop=True)
mixed_sample.groupby(['region', 'age_group'])['purchase'].mean()

通过这种组合方法,研究人员可以在保持分层结构的同时引入随机性,从而在市场分析中获得更稳健的推断结果。案例分析显示,分层+随机的组合往往能够更好地揭示不同区域与年龄段之间的购买倾向差异。

广告

后端开发标签