分层抽样

  |  

摘要: 分层抽样

【对算法,数学,计算机感兴趣的同学,欢迎关注我哈,阅读更多原创文章】
我的网站:潮汐朝夕的生活实验室
我的公众号:算法题刷刷
我的知乎:潮汐朝夕
我的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

1
2
3
4
5
6
7
# 分层抽样
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) 切割即可。

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

好样本 坏样本 样本合计
数量(总体) 195000 5000 200000
占比(总体) 97.5% 2.5% 100%
数量(时间内总体) 146000 4000 150000
占比(时间内总体) 97.33% 2.67% 100%
数量(训练集抽样) 25200 2800 28000
占比(训练集抽样) 90% 10% 100%
权重(训练集抽样) 4.0556 1 -
加权(训练集抽样) 102200 2800 105000(训练集占比0.7)
数量(测试集抽样) 10800 1200 12000
占比(训练集抽样) 90% 10% 100%
权重(测试集抽样) 4.0556 1 -
加权(测试集抽样) 43800 1200 45000(测试集占比0.3)
数量(时间外总体) 49000 1000 50000
占比(时间外总体) 98.0% 2.0% 100%
数量(时间外抽样) 9000 1000 10000
占比(时间外总体) 90% 10% 100%
权重(时间外抽样) 5.44 1 -
加权(时间外抽样) 49000 1000 50000

例子2

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

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

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

好样本 坏样本 样本合计
数量(总体) 222118 8139 230257
占比(总体) 96.47% 3.53% 100%
数量(时间内总体) 190037 7105 197142
占比(时间内总体) 96.40% 3.60% 100%
数量(训练集抽样) 26945 3045 29990
占比(训练集抽样) 89.85% 10.15% 100%
权重(训练集抽样) 4.93743 1.631856 -
加权(训练集抽样) 133039 4969 138008(训练集占比0.7)
数量(测试集抽样) 11544 1309 12853
占比(训练集抽样) 89.82% 10.18% 100%
权重(测试集抽样) 4.93746 1.63178 -
加权(测试集抽样) 56998 2136 59134(测试集占比0.3)
数量(时间外总体) 32081 1034 33115
占比(时间外总体) 96.88% 3.12% 100%
数量(时间外抽样) 6511 646 7157
占比(时间外总体) 90.97% 9.03% 100%
权重(时间外抽样) 4.9272 1.600619 -
加权(时间外抽样) 32081 1034 33115

Share