1 什么是Bootstrap采样

先来看看维基百科的定义:
在这里插入图片描述
即Bootstrap的定义是利用有限的样本经由多次重复抽样,建立起充足的样本,在机器学习中解决了样本不足的问题

Bootstrap是非参数统计方法,其实质是对观测信息进行再抽样,进而对总体的分布特性进行统计推断。

2 Bootstrap步骤

它是一种有放回的抽样方法,它是非参数统计中一种重要的估计统计量方差进而进行区间估计的统计方法。其核心思想和基本步骤如下:

  1. 采用重抽样技术从原始样本中抽取一定数量(自己给定)的样本,此过程允许重复抽样
  2. 根据抽出的样本计算给定的统计量T。
  3. 重复上述N次(一般大于1000),得到N个统计量T。
  4. 计算上述N个统计量T的样本方差,得到统计量的方差。

同理,可以估计总体的均值等其余统计量

3 为什么要进行Bootstrap采样

  • 数据集较小时是不错的选择。自助法在数据集较小、难以有效划分训练集和测试集时很有用;将多次随机抽样得到的样本作为训练集,将初始数据作为测试集。
  • 对集成学习方法有帮助。此外,自助法能从初始数据集中产生多个不同的训练集,这对集成学习等方法有很大的好处。
  • 稳健性和效率高。该方法充分利用了给定的观测信息,不需要模型其他的假设和增加新的观测,并且具有稳健性和效率高的特点
  • 但会引入估计偏差。然而,自助法产生的数据集改变了初始数据集的分布,这会引入估计偏差。因此,在初始数据量足够时,留出法和交叉验证法更常用一些。

4 采样的Python实现

4.1 验证样本男女比例是否和总体一致

假设我们总体中有一部分女生,一部分男生,我们想知道他们的比例是否大体相当。那么我们采用bootstrap的步骤则是:

  1. 每次采样10个人,看男女比例。
  2. 重复上述过程10000次,把每次的男女比例求平均,代表最终的男女比例。
import random
import pandas as pd
import numpy as np
from sklearn.utils import resample  

def scalegirl(samples):
    '''
    统计抽样结果中:女性/男性比例
    '''
    count =0.0
    total = samples.size
    for sex in samples:
        if(sex==0):
            count+=1.0
#     print(count)
    return count/(total-count)
 
boy = (np.ones(1000))
girl = (np.zeros(800))
#girl/boy=0.8
 
# print(girl.shape)
all = np.hstack((boy, girl))
scale = 0.0
iter = 10000
for i in range(iter):
    bootstrapSamples = resample(all,n_samples=100,replace=1)
#     print(bootstrapSamples)
    tempscale = scalegirl(bootstrapSamples) # 比例—女性:男性
#     print(tempscale)
    scale+=tempscale
print(scale/iter) # 计算10000次的平均 女/男
0.8131221314168651

结论:

  • 从上个例子中,我们可以看到,通过自采样Bootstrap的方法,从统计角度,得到的女性、男性比例和真实的值非常接近。
  • 有时候我们无法得知真相(比如总体的相关指标),只有通过样本来推断,这时候在小样本场景下的Bootstrap是一个不错的选择!

4.2 模拟boostrap

先生成总体pop,然后从pop中随机抽一个样本出来

np.random.seed(123)
pop = np.random.randint(0,500 , size=1000)
sample = np.random.choice(pop, size=300) #so n=300

根据随机的样本进行重复抽样10000次!并将每次的均值进行保留

sample_mean = []
for _ in range(10000):  #so B=10000
    sample_n = np.random.choice(sample, size=300)
    sample_mean.append(sample_n.mean())

可视化发现均值近似服从正态分布,这也是中心极限定理可以保证的

import matplotlib.pyplot as plt
plt.hist(sample_mean)
(array([1.000e+01, 1.350e+02, 7.070e+02, 2.001e+03, 2.999e+03, 2.591e+03,
        1.236e+03, 2.890e+02, 3.000e+01, 2.000e+00]),
 array([225.00333333, 231.519     , 238.03466667, 244.55033333,
        251.066     , 257.58166667, 264.09733333, 270.613     ,
        277.12866667, 283.64433333, 290.16      ]),
 <a list of 10 Patch objects>)

在这里插入图片描述
重复抽样的均值:

np.mean(sample_mean)
255.73952966666664

总体均值:

pop.mean()
253.241

样本均值:

sample.mean()
255.68

可以发现上述三者基本一致

准备好这10000份数据集,以备后续使用:

sample_total = []
for _ in range(10000):  #so B=10000
    sample_n = np.random.choice(sample, size=300)
    sample_total.append(sample_n)
# 看有多少组数据集
print(len(sample_total))
10000
# 取一个出来看看
print(sample_total[1])
[420 467  76 283  23 491 238  66 334 290 253 135 364 342 190  71 190 356
 148 202 276 113 289 289 243  43 228  86 495 398 113 350 168 460  57 251
 179  96 486 429 132  89  18 430 179 355 181 166  84 427 268 427 103 342
  19 304 259  47 256 441 402  86  71 283 442 270 495 148 385 480 245 253
 366  58 398 403 447 247 438  39  45  47 430 401 333 366 383 377 186  63
  19 308 129 130 113 339 146  89 483 186  17 262 366 219 149 169 179  18
 258 333  89 232  96 362  63 309 368 240   6 363 466 438 481 117 197  22
 311 222 432 482  86 259 135 323 168 262 270 339 466  92 113   8  71  47
 283 493 419 383  76 457 480 157 350 355 401  76 231 491 127 276  89 460
 228 496 493 424 130 204 377 401 365 217 346  22 430 130 284  47 350 284
 158 399 113 199 219 222 258 457 128  18 228 293 385 179 240 154 234 276
 333 152 304  95 451  19 495 113 186 283 460  69 363 325 117 410 190  23
 248 324  86 259 432 140  73  94 140 222  19 258 271 247 180  76   6   6
 444 270 379 243 368 137 193 179 439 394 394 149  76 357  84 103 197 250
 452 289 248 356 452  93  45 325 251 387 232 103 251 232 368 438  82 180
 493 441 290 304 401 290  92 373 427 111 480   8 219 387 248 293 197 183
 199 496 122 130 309 438 199 432 129 370   8  63]

5 参考

  • https://blog.csdn.net/mingyuli/article/details/81223463
  • https://zhuanlan.zhihu.com/p/107978939
  • https://zhuanlan.zhihu.com/p/24851814
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐