上一小节介绍了 Bagging 这种集成学习方式,我们不再使用不同的机器学习算法进行集成,而是使用同一种机器学习算法,让这个算法在不同的样本上进行训练,而这些不同的样本是通过对全部样本数据有放回取样得到的,这些在不同样本上训练的子模型有一定的差异性。
本小节来介绍更多和 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 实现 Bagging 集成学习,可以通过 oob_score_ 属性来查看使用 Out-of-Bag 样本作为测试集计算得到的结果。
import numpy as np
import matplotlib.pyplot as plt
本小节使用分布呈现交错半圆形的二分类虚拟数据集,使用 sklearn.datasets 包下的 make_moons 函数即可生成这样的虚拟数据集。
from sklearn import datasets
X, y = datasets.make_moons(n_samples = 500,
noise = 0.3,
random_state = 42)
在使用 make_moons 函数时指定三个参数:
使用散点图将生成的虚拟数据集绘制出来。
plt.scatter(X[y == 0, 0], X[y == 0, 1])
plt.scatter(X[y == 1, 0], X[y == 1, 1])
plt.show()
使用 Bagging 集成学习方式集成决策树模型。
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 时传入了五个参数:
在 sklearn 中使用 OOB,除了需要使用 Bagging 集成学习的方式(boostrap = True)之外,还需要在实例化集成学习时指定 oob_score 参数为 True。指定 oob_score 参数可以简单的理解为是对样本数据的一种标记,标记取到了那些样本,没有取到那些样本。
使用实例化好的 Bagging 集成学习分类器,调用 fit 函数拟合全部样本数据。
bagging_clf.fit(X, y)
如果想要查看训练好的模型的整体泛化能力,可以通过 oob_score_ 属性查看。在 sklearn 的设计理念中,带有下划线的属性不是用户传入的参数,而是经过类计算出的一个结果。
bagging_clf.oob_score_
# 0.918
Bagging 这种集成学习的方式是极易进行并行化处理的。 我们独立的训练若干的子模型,训练每个子模型的样本的采样过程也是独立的,所以可以非常方便地进行并行化的处理。
对于可以并行化的算法,在 sklearn 中可以传入 n_jobs 参数,传入 n_jobs 的参数值代表算法使用计算机中的几个核,如果传入 -1 则会使用计算机中的所有 CPU 核。
接下来通过 %%time 魔法命令来验证使用 n_jobs 参数进行并行化处理的优势。
%%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
%%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 创建每个子模型,需要让每个子模型有一定的差异化,前面介绍了通过让每个子模型去看更小的样本数据来产生这种差异化。其实还有其它能够产生差异化的方式:
Random Subspaces:针对特征进行随机采样的方式,通常在样本的特征非常多的情况下使用。比如,在图像识别领域中每一张图像上,每一个像素点都代表一个特征,因此每一张图像的特征量非常大,此时可以针对图像特征进行随机采样,这就是所谓的 Random Subspaces。Random Subspaces 翻译为 "随机子空间",这是因为对于整个样本组成的特征空间,针对特征随机采样,相当于在整个特征空间中采样某个子特征空间。
Random Patches:即针对样本,又针对特征进行随机采样。patches 翻译为 "补丁",这个名字其实很形象。样本数据本身就是一个矩阵,矩阵的长代表样本个数,矩阵的列代表样本的特征,
的样本矩阵表示
个样本点,每个样本拥有
个特征。Random Patches 在矩阵的行(样本个数)和矩阵的列(样本特征)上进行随机,得到的结果好像和下面这张图一样,看起来好像是一块布上的很多补丁,这些补丁都是随机的,所以被称为 Random Patches 随机补丁。
random_subspaces 为随机采样特征,不对样本进行随机采样,在 sklearn 中不进行样本的随机采样,只需要指定 max_samples 为样本总数即可。
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 两个参数。
Random Patches 既针对样本,又针对特征进行随机采样。
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,准确率提高了一些。这也从侧面验证了,添加对样本的随机采样,增大了每个子模型的差异性。
References:
本文分享自 AI机器学习与深度学习算法 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!