一、背景介绍

在 bagging 模型的构建中会集成多个子模型。对于每个子模型的构建,都需要分 别为其进行数据或特征抽样。对每个子模型的抽样,称为一轮,n 个子模型抽样,表示 n 轮。

关于什么是有放回抽样,目前存在两种说法:

说法一:一轮抽样结束后,将所有被抽取的数据一次全部放回,以此进行下一轮抽样;

说法二:在一轮抽样期间,每次抽完一个数据,就立马将该数据放回。如果一轮要抽样 n 个数据,那么就会有 n 次数据的放回动作。

二、实验

1.试验目的

验证以上两种说法,哪一种是正确的

2.试验内容

抽样既可以选择对样本抽样,也可以对样本的特征进行抽样。在本例中,选取对特征进行抽样。

这里以 scikit-learn 内置的红酒数据集(load_wine())为例进行验证,这个数据集里一共有 13 个特征。

下面使用 PyCharm 的开发环境,编写了一个测试页面 有放回抽样.py 如下:

有放回重抽样python 有放回抽样例题_bootstrap


本例中设置 max_features=5,表示每次构建基学习器的时候,随机抽样 5 个特征。默认创建 10 棵子树,也就是循环进行 10 轮特征抽样。

在运行 有放回抽样.py 之前,先做下面的工作:
打开 scikit-learn 的源文件./sklearn/ensemble/bagging.py(快速打开此文件的方法:按住 ctrl 键的同时,将鼠标指向测试页面当中的 BaggingClassifier函数,一旦鼠标变成手指状,进行点击。就会跳转到上面的文件)。

找到此文件中的_generate_bagging_indices()函数,如下所示:

有放回重抽样python 有放回抽样例题_有放回重抽样python_02


这个函数的目的,就是生成每轮抽样当中的随机值。

对这块代码做稍微修改,加一行打印,目的是使它输出每次抽样的特征索引位置(feature indices)

有放回重抽样python 有放回抽样例题_数据_03


回到测试页面 有放回抽样.py,分别做两次测试:

1).第一次测试:设置有放回抽样.py 的 BaggingClassifier 参数 bootstrap_features = True。运行脚本,执行结果如下图所示: 看到 10 轮特征抽样的 feature indecies,每一轮抽样中,多数情况下同一个特征都可能被抽取两次或更多。说明:bootstrap_features = True 表示,在每一轮抽样中,特征被抽完即刻被放回,所以在一轮中,特征可能被反复抽取

有放回重抽样python 有放回抽样例题_数据集_04


2)第二次测试,修改 bootstrap_features = False,执行有放回抽样.py,结果如下图所示。可以看到,在每一轮抽样中,一个特征被抽样了之后就不再被放回了。但是到一下轮抽样时,又是从全部特征里再取样。

所以 bootstrap_features = False 表示数据被抽取后,在当前这一轮就不放回

了。

有放回重抽样python 有放回抽样例题_python_05

总结

对于有放回抽样,说法二是正确的,即在一轮抽样期间,每次抽完一个数据,就立马将该数据放回。如果一轮要抽样 n 个数据,那么就会有 n 次数据的放回动作。