前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >机器学习入门 13-4 oob(Out-of-Bag)和关于Bagging的更多讨论

机器学习入门 13-4 oob(Out-of-Bag)和关于Bagging的更多讨论

原创
作者头像
触摸壹缕阳光
修改2021-05-07 10:16:40
3.3K0
修改2021-05-07 10:16:40
举报

上一小节介绍了 Bagging 这种集成学习方式,我们不再使用不同的机器学习算法进行集成,而是使用同一种机器学习算法,让这个算法在不同的样本上进行训练,而这些不同的样本是通过对全部样本数据有放回取样得到的,这些在不同样本上训练的子模型有一定的差异性。

OOB

本小节来介绍更多和 Bagging 相关的内容,首先对于 Bagging 这种集成学习来说,有一个非常重要的概念叫做 OOB(Out-of-Bag)。在使用 Bagging 集成学习对样本进行有放回取样,有放回取样很有可能会导致一部分样本取不到,经过严格的数学计算,有放回取样平均大约有 37% 的样本不会被取到。这 37% 的样本通常被称为 OOB(Out-of-Bag)。

在机器学习中,为了能够验证模型的泛化能力,我们使用 train_test_split 方法将全部的样本划分成训练集和测试集两个部分,训练集用于训练模型,而测试集用于验证模型的泛化能力。使用 Bagging 这种集成学习方式,大概有 37% 的样本是取不到的 (这些取不到的样本被称为 Out-of-Bag),因此可以将这部分没有取到的样本做测试/验证(不需要使用 train_test_split 划分出测试集)。

使用sklearn实现OOB

使用 sklearn 实现 Bagging 集成学习,可以通过 oobscore 属性来查看使用 Out-of-Bag 样本作为测试集计算得到的结果。

代码语言:txt
复制
import numpy as np
import matplotlib.pyplot as plt

本小节使用分布呈现交错半圆形的二分类虚拟数据集,使用 sklearn.datasets 包下的 make_moons 函数即可生成这样的虚拟数据集。

代码语言:txt
复制
from sklearn import datasets
    
X, y = datasets.make_moons(n_samples = 500,
                            noise = 0.3,
                            random_state = 42)

在使用 make_moons 函数时指定三个参数:

  • n_samples,生成样本点的总数。默认为 100 个,由于本章需要的数据量相对比较大,因此将 n_samples 设置为 500;
  • noise,加到数据集中的高斯噪声的标准差。默认为 None,noise 的值越小,生成的数据集呈现交错半圆形的分布形状越明显,noise 的值越大,生成的数据集呈现交错半圆形的分布形状越不明显,此时将 noise 设置为相对比较大的 0.3;
  • random_state,随机种子。设置固定的随机种子,能够保证多次试验结果的一致性;

使用散点图将生成的虚拟数据集绘制出来。

代码语言:txt
复制
plt.scatter(X[y == 0, 0], X[y == 0, 1])
plt.scatter(X[y == 1, 0], X[y == 1, 1])
plt.show()

使用 Bagging 集成学习方式集成决策树模型。

代码语言:txt
复制
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import BaggingClassifier

bagging_clf = BaggingClassifier(DecisionTreeClassifier(),
                               n_estimators = 500,
                               max_samples = 100,
                               bootstrap = True, 
                               oob_score = True)

实例化 BaggingClassifier 时传入了五个参数:

  • 集成的每一个模型采用的算法。此时使用决策树算法;
  • n_estimators:集成子模型的个数。此时集成 500 个决策树子模型;
  • max_samples:训练每个子模型的样本个数。此时为 100 个样本,即每个子模型在 100 个样本上训练;
  • bootstrap:集成学习采取的是有放回还是无放回。此时为 True,即采用有放回 Bagging 的方式;
  • oob_score:是否使用 OOB,默认为 False,不使用 OOB。此时为 True,即使用 OOB;

在 sklearn 中使用 OOB,除了需要使用 Bagging 集成学习的方式(boostrap = True)之外,还需要在实例化集成学习时指定 oob_score 参数为 True。指定 oob_score 参数可以简单的理解为是对样本数据的一种标记,标记取到了那些样本,没有取到那些样本。

使用实例化好的 Bagging 集成学习分类器,调用 fit 函数拟合全部样本数据。

代码语言:txt
复制
bagging_clf.fit(X, y)

如果想要查看训练好的模型的整体泛化能力,可以通过 oobscore 属性查看。在 sklearn 的设计理念中,带有下划线的属性不是用户传入的参数,而是经过类计算出的一个结果。

代码语言:txt
复制
bagging_clf.oob_score_
# 0.918

Bagging 的并行化处理

Bagging 这种集成学习的方式是极易进行并行化处理的。我们独立的训练若干的子模型,训练每个子模型的样本的采样过程也是独立的,所以可以非常方便地进行并行化的处理。

对于可以并行化的算法,在 sklearn 中可以传入 n_jobs 参数,传入 n_jobs 的参数值代表算法使用计算机中的几个核,如果传入 -1 则会使用计算机中的所有 CPU 核。

接下来通过 %%time 魔法命令来验证使用 n_jobs 参数进行并行化处理的优势。

代码语言:txt
复制
%%time
bagging_clf = BaggingClassifier(DecisionTreeClassifier(),
                               n_estimators = 500,
                               max_samples = 100,
                               bootstrap = True, 
                               oob_score = True)
bagging_clf.fit(X, y)
# CPU times: user 1.81 s, sys: 27.2 ms, total: 1.84 s
# Wall time: 2.95 s
代码语言:txt
复制
%%time
bagging_clf = BaggingClassifier(DecisionTreeClassifier(),
                               n_estimators=500, max_samples=100,
                               bootstrap=True, oob_score=True,
                               n_jobs=-1)
bagging_clf.fit(X, y)
# CPU times: user 385 ms, sys: 56.1 ms, total: 441 ms
# Wall time: 1.83 s

更多 Bagging 差异化方法

Bagging 创建每个子模型,需要让每个子模型有一定的差异化,前面介绍了通过让每个子模型去看更小的样本数据来产生这种差异化。其实还有其它能够产生差异化的方式:

  • 针对特征进行随机采样的 Random Subspaces
  • 即针对样本,又针对特征进行随机采样 Random Patches

Random Subspaces:针对特征进行随机采样的方式,通常在样本的特征非常多的情况下使用。比如,在图像识别领域中每一张图像上,每一个像素点都代表一个特征,因此每一张图像的特征量非常大,此时可以针对图像特征进行随机采样,这就是所谓的 Random Subspaces。Random Subspaces 翻译为 "随机子空间",这是因为对于整个样本组成的特征空间,针对特征随机采样,相当于在整个特征空间中采样某个子特征空间。

Random Patches:即针对样本,又针对特征进行随机采样。patches 翻译为 "补丁",这个名字其实很形象。样本数据本身就是一个矩阵,矩阵的长代表样本个数,矩阵的列代表样本的特征,$n \times m$ 的样本矩阵表示 $n$ 个样本点,每个样本拥有 $m$ 个特征。Random Patches 在矩阵的行(样本个数)和矩阵的列(样本特征)上进行随机,得到的结果好像和下面这张图一样,看起来好像是一块布上的很多补丁,这些补丁都是随机的,所以被称为 Random Patches 随机补丁。

sklearn 实现 random_subspaces

random_subspaces 为随机采样特征,不对样本进行随机采样,在 sklearn 中不进行样本的随机采样,只需要指定 max_samples 为样本总数即可。

代码语言:txt
复制
random_subspaces_clf = BaggingClassifier(DecisionTreeClassifier(),
                               n_estimators=500, 
                               max_samples=500,
                               bootstrap=True,
                               oob_score=True,
                               max_features=1,
                               bootstrap_features=True)
random_subspaces_clf.fit(X, y)
random_subspaces_clf.oob_score_
# 0.83

使用 sklearn 实现对特征空间的随机采样,可以在实例化集成学习分类器时指定 max_features 和 bootstrap_features 两个参数。

  • max_features:随机的特征个数,本例中的样本一共有两个特征,为了演示将随机的特征个数设置为 1,即随机采样 1 个样本特征;
  • bootstrap_features:对样本特征的采样是采用有放回采样还是无放回采样;

sklearn 实现 Random Patches

Random Patches 既针对样本,又针对特征进行随机采样。

代码语言:txt
复制
random_patches_clf = BaggingClassifier(DecisionTreeClassifier(),
                               n_estimators=500, 
                               max_samples=100,
                               bootstrap=True,
                               oob_score=True,
                               max_features=1,
                               bootstrap_features=True)
random_patches_clf.fit(X, y)
random_patches_clf.oob_score_
# 0.854

通过实验结果可以发现,既针对样本,又针对特征进行随机采样的 Random Patches,相比于仅对特征进行随机采样的 Random Subspaces,准确率提高了一些。这也从侧面验证了,添加对样本的随机采样,增大了每个子模型的差异性。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • OOB
    • 使用sklearn实现OOB
    • Bagging 的并行化处理
    • 更多 Bagging 差异化方法
      • sklearn 实现 random_subspaces
        • sklearn 实现 Random Patches
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档