分层抽样的总结

摘要:本文通过几个例子学习了 matplotlib.animation 画动图的方法
---
对算法,数学,计算机感兴趣的同学,欢迎关注我哈,阅读更多原创文章
我的网站: 潮汐朝夕的生活实验室
我的公众号: 潮汐朝夕
我的知乎: 潮汐朝夕
我的github: FennelDumplings
我的leetcode: FennelDumplings

分层抽样的概念

抽样时,将总体分成互不交叉的层,然后按照一定的比例,从各层独立地抽取一定数量的个体,将各层取出的个体合在一起作为样本,这种抽样方法叫分层抽样。

有几个关键要点

  • 总体个体差异明显,每层的差异比较大,层内个体间的差异比较小
  • 每层可以抽取多少样本,常见的有以下这些方案
    • 如果根据它在总体中占的比例来抽取,就是等比例抽样
    • 也可以对不同的层赋予不同的权重,手动控制各层的抽样规模。
    • 对每一层都分配同样的个体数
    • 各层抽得的样本数与所抽得的总样本数之比等于该层方差与各类方差之和的比
  • 每层抽取样本时,采用简单随机抽样

分层抽样的步骤

(1) 确定总体与样本容量抽取的比例

抽取比例 = 样本容量 / 总体个数

(2) 由分层情况,确定各层抽取的样本数

如果是等比例抽样,各层抽取个数 = 抽取比例 * 各层个数

如果是加权抽样,各层抽取个数自定义

(3) 各层抽取数之和应等于样本容量


等比例分层抽样的例子

一单位有 500 职工,不到 35 岁的有 125 人,35~49 有 280 人,50 以上有 95 人。

为例了解单位职工与身体状况有关的某指标。入后抽取一个容量为 100 的样本。

思路

身体状况与年龄的关系非常大,因此适合分层抽样。

step1:j 确定比例

样本容量 / 总体个数 = 100 / 500 = 1/5

step2: 各层抽取的样本数

每一个层都应该按照 1/5 抽取,各层抽取的个数为

125/5, 280/5, 95/5 = 25, 56, 19

step3: 在各层用简单随机抽样


分层抽样的代码模板 (Pandas)

假设数据中有一个分类型变量 var0,以该变量 df[“var0”] 为依据分层抽样,各层的抽样个数均为 10

# 分层抽样
each_sample_count = 10 # 各层抽样个数
label_unique = np.unique(df['var0']) # 分层依据
df_sample = pd.DataFrame(np.zeros((1, len(df.columns))), columns=df.columns ,dtype=int)
for label in label_unique:
     sample = pd.DataFrame.sample(df[df['var0']==label], each_sample_count)
     df_sample = pd.concat([df_sample,sample])


优点分层抽样的优缺点

  1. 如果层内的具有较低的标准偏差(与总体中的总体标准偏差相比),则分层会产生较小的估计误差。
  2. 对于许多应用,当人口被分组到层中时,测量变得更易于管理。
  3. 分层抽样特别适用于既要对总体参数进行推断也要对各子总体(层)的参数进行推断的情形

评分卡建模数据集切分的例子

在评分卡建模项目中,时间窗口确定之后,数据集也就定了下来,这份数据集相当于是总体。

在建模前,数据集一般分为 3 个子集:开发样本(dev),验证样本(val),时间外样本(OOT)。

一般情况下,时间外样本通常使用整个建模样本中最后一段时间的样本。而开发样本与验证样本使用分层抽样进行划分,目的是保证两个数据集中的负样本占比相同

但是评分卡建模中,从经验上看正负样本数量都应该 >= 1500,且总样本量最好不超过 50000,因为超过 5 万后,模型的效果就不在随着样本量增加而有显著变化了。此时一般需要对正样本做欠采样处理

用分层抽样对好样本欠采样

分层抽样是这里的欠采样的常用方法,保证抽样后,开发样本,验证样本,时间外样本的正负比例相同。

具体的做法是首先根据总体的负样本数,确定一个正样本和负样本想要保留的样本数,正负样本比例也顺便确定了。然后将最后一段时间范围的样本作为时间外样本的候选样本,其余的为训练样本和测试样本的候选样本。

然后按照正负样本比例和两份候选样本的负样本个数,以及训练集验证集的比例,得到训练集、验证集、时间外样本集需要抽样的正样本数,然后进行分层抽样即可。

然后按照正负样本比例和时间内样本的负样本个数,得到需要抽样的正样本数,对时间外样本的候选样本分层抽样后,得到时间外样本;

例子

例如我们有 200000 样本,其中有 5000 负样本(2.5%),195000 正样本。

首先我们确定一个比例,就是负样本占比 10%(2.5% 的四倍)。基于这个比例我们确定负样本取 5000,正样本取 45000,这样负样本占比就是 10% 了。

然后我们选定最后一段时间内的样本作为时间外样本的候选样本,假设这部分样本有 50000,其中 1000 负样本,占比 2%。那么开发样本和测试样本的候选样本就是 150000,其中 4000 负样本,占比 2.67%。

接下来抽样获取时间外样本。由于时间外样本有 1000 负样本,负样本比例 10%,因此我们需要抽样 9000 正样本。

开发样本和测试样本的候选样本我们称为时间内总体,共 150000,其中 4000 负样本。由于负样本比例 10%,因此我们需要从 146000 中抽样 36000。然后将 4000 负样本和 36000 正样本分别按某个测试集比例(例如 0.3) 切割即可。

抽样完成后,数据记录表大致是下面这样

好样本坏样本样本合计
数量(总体)1950005000200000
占比(总体)97.5%2.5%100%
数量(时间内总体)1460004000150000
占比(时间内总体)97.33%2.67%100%
数量(训练集抽样)25200280028000
占比(训练集抽样)90%10%100%
权重(训练集抽样)4.05561-
加权(训练集抽样)1022002800105000(训练集占比0.7)
数量(测试集抽样)10800120012000
占比(训练集抽样)90%10%100%
权重(测试集抽样)4.05561-
加权(测试集抽样)43800120045000(测试集占比0.3)
数量(时间外总体)49000100050000
占比(时间外总体)98.0%2.0%100%
数量(时间外抽样)9000100010000
占比(时间外总体)90%10%100%
权重(时间外抽样)5.441-
加权(时间外抽样)49000100050000

例子2

上面的例子中为了看的清楚,数据取的都很整。这里把数据做的乱一点再看一下。

总体数据为 230257,负样本 8139(占比 3.53%),分出时间外样本后:
时间外候选样本 33115,负样本 1034(占比 3.12%)
开发测试候选样本 197142,负样本 7105(占比 3.60%)

依然取负样本比例 10%,测试集比例 0.3,分层抽样后,数据记录表大致如下(注意负样本也做了一定采样,因此抽样后,负样本也是有权重的)

好样本坏样本样本合计
数量(总体)2221188139230257
占比(总体)96.47%3.53%100%
数量(时间内总体)1900377105197142
占比(时间内总体)96.40%3.60%100%
数量(训练集抽样)26945304529990
占比(训练集抽样)89.85%10.15%100%
权重(训练集抽样)4.937431.631856-
加权(训练集抽样)1330394969138008(训练集占比0.7)
数量(测试集抽样)11544130912853
占比(训练集抽样)89.82%10.18%100%
权重(测试集抽样)4.937461.63178-
加权(测试集抽样)56998213659134(测试集占比0.3)
数量(时间外总体)32081103433115
占比(时间外总体)96.88%3.12%100%
数量(时间外抽样)65116467157
占比(时间外总体)90.97%9.03%100%
权重(时间外抽样)4.92721.600619-
加权(时间外抽样)32081103433115

### R语言中分层抽样的实现方法 #### 基本原理 分层抽样是一种统计学上的抽样技术,其核心思想是将总体划分为若干个互不重叠的子集(即“层”),并从每一层中独立地抽取样本。这种方法能够提高样本对总体特征的代表性[^1]。 在R语言中,可以通过多种方式实现分层抽样。以下是具体的实现方法及其示例代码: --- #### 方法一:使用基础包 `base` 进行分层抽样 通过手动定义每层的比例或固定数量,利用 `sample()` 函数完成分层抽样操作。 ```r # 创建模拟数据框 set.seed(123) # 设置随机种子以便结果可重复 data <- data.frame( group = rep(c("A", "B", "C"), each = 10), # 定义三个层次 A, B, C value = rnorm(30) # 随机生成数值列 ) # 查看原始数据结构 print(data) # 计算各层比例并按比例抽样 proportions <- table(data$group) / nrow(data) # 各层所占比例 n_sample <- round(proportions * 5) # 抽取总样本量为5,按比例分配到各层 # 执行分层抽样 stratified_sample <- do.call(rbind, lapply(unique(data$group), function(g) { data[sample(which(data$group == g), size = n_sample[g]), ] })) # 输出抽样结果 print(stratified_sample) ``` 上述代码展示了如何基于不同层的比例进行分层抽样,并最终得到一个具有代表性的样本集合[^2]。 --- #### 方法二:借助第三方库 `dplyr` 和 `tidyr` 对于更复杂的场景,可以结合现代数据分析工具包如 `dplyr` 来简化流程。 ```r library(dplyr) # 使用 dplyr 的 group_by() 和 sample_n() 或 sample_frac() stratified_sample_dplyr <- data %>% group_by(group) %>% # 按照 'group' 列分组 sample_n(size = 2) # 每组抽取2个样本 # 如果希望按照百分比而非绝对数,则替换为 sample_frac() # stratified_sample_dplyr <- data %>% # group_by(group) %>% # sample_frac(size = 0.2) # 每组抽取20%的样本 # 显示结果 print(stratified_sample_dplyr) ``` 此方法更加直观易读,尤其适用于大规模复杂数据集的操作[^4]。 --- #### 方法三:调用专门的抽样函数 (如 `sampling::strata`) 如果需要更高精度或者更多选项支持,推荐使用专业的抽样包 `sampling` 中提供的功能强大的 `strata()` 函数。 ```r # 安装并加载 sampling 包 if (!require(sampling)) install.packages("sampling") library(sampling) # 设定目标样本大小向量 size_vector <- c(A = 3, B = 2, C = 1) # 每一层分别抽取的数量 # 调用 strata 函数执行分层抽样 result_sampling <- strata(data, stratanames = "group", size = size_vector, method = "srswor") # 提取出具体被选中的记录索引号以及对应的内容 selected_indices <- getdata(data, result_sampling[, "ID_unit"]) print(selected_indices) ``` 这里采用了简单随机无放回的方式 (`srswor`) 对指定层数目进行了精确控制[^3]。 --- ### 总结 综上所述,在R语言中有三种主要途径可用于实施分层抽样——分别是依靠内置的基础命令组合而成的方法;依赖流行扩展包所提供的便捷接口形式;还有就是引入专用领域内的高级算法模块来达成目的。这三种路径各有优劣之处,使用者可以根据实际情况选取最合适的方案加以应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法题刷刷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值