我们将分为5篇文章介绍集成学习,分别是:

  1. 集成学习基础知识:偏差和方差 - 戳此阅读
  2. Bagging -
  3. Boosting - 戳此阅读
  4. Stacking/Blending - 戳此阅读
  5. Voting/Averaging

本文是系列中的第二篇

Bagging是我们要讲的第一种集成学习方法,是Bootstrap Aggregating的缩写。有人把它翻译为套袋法,装袋法,或者自助聚合,没有个统一的叫法,那就直接用它的英文名称。其算法的基本思想是从原始的数据集中抽取数据,形成k个随机的新训练集,然后训练出k个不同的模型。

具体过程如下:

  1. 从原始样本集中通过随机抽取形成k个训练集(如右图所示):每轮抽取n个训练样本(有些样本可能被多次抽取到,而有些样本可能一次都没有被抽中,这叫作有放回的抽取)。这k个训练集是彼此独立的——这个过程也叫作bootstrap(可译为自举或自助采样),它有点像k折验证,但不同之处样本是有放回的。
  2. 每次使用一个训练集通过相同的机器学习算法(如决策树、神经网络等)得到一个模型,k个训练集共得到k个模型。我们把这些模型称为基模型(base estimator),或者基学习器。
  3. 基模型的集成:
  4. 对分类问题:k个模型采用投票的方式得到分类结果;
  5. 对回归问题,计算k个模型的均值作为最后的结果。
    这个过程如下图所示:

Bagging的过程

决策树的聚合

小冰发言:“咖哥,怎么觉得这个Bagging上节课你已经讲过一遍了?咖哥说:很好,你还记得,就代表昨天我没有白讲。多数情况下的Bagging,都是基于决策树的,构造随机森林的第一个步骤其实就是对多棵决策树进行Bagging,我们把它称为树的聚合(Bagging of Trees)。”

树这种模型,具有显著的低偏差、高方差的特点,也就是受数据的影响特别大,一不小心,训练集准确率就接近百分之百了,但是这种效果又不能够移植到其他的数据集里面去。这是很明显的过拟合现象。集成学习的Bagging方法,就从树模型开始,着手解决它太过于精准,又不易泛化的问题。

当然Bagging的原理,并不仅限于决策树,还可以扩展到其他的机器学习算法。因为通过随机抽取数据的方法减少了可能的数据干扰,经过Bagging的模型将会具有较少的方差。

在Sklearn的集成学习库中,有BaggingClassifier和BaggingRegressor这两种Bagging模型,分别适用于分类问题和回归问题。

现在把树的BaggingClassifier应用于第五课中预测银行客户是否会流失的用例,看一看其效果如何。

数据读入和特征工程部分的代码这里就不贴了,同学们可参考我博客里面上载的《零基础学机器学习》随书数据集和源码包中的内容。

# Bagging with a decision tree regressor
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import (f1_score, confusion_matrix) # 导入评估标准
dt = BaggingClassifier(DecisionTreeClassifier()) # 只使用一棵决策树
dt.fit(X_train, y_train) # 拟合模型
y_pred = dt.predict(X_test) # 进行预测
print("决策树测试准确率: {:.2f}%".format(dt.score(X_test, y_test)*100))
print("决策树测试F1分数: {:.2f}%".format(f1_score(y_test, y_pred)*100))
bdt = BaggingClassifier(DecisionTreeClassifier()) #树的Bagging
bdt.fit(X_train, y_train) # 拟合模型
y_pred = bdt.predict(X_test) # 进行预测
print("决策树Bagging测试准确率: {:.2f}%".format(bdt.score(X_test, y_test)*100))
print("决策树Bagging测试F1分数: {:.2f}%".format(f1_score(y_test, y_pred)*100))

上面的代码中的BaggingClassifier指定了DecisionTreeClassifier决策树分类器作为基模型的类型,默认的基模型的数量是10,也就是在Bagging过程中会用Bootstrap方法生成10棵树。

预测结果如下:

决策树测试准确率: 84.00%
决策树测试F1分数: 53.62%
决策树Bagging测试准确率: 85.75%
决策树Bagging测试F1分数: 58.76%

在这里比较了只使用一颗决策树和经过Bagging之后的树这两种算法预测效果,可以看到Bagging of Trees的准确率及F1分数明显占优势。在没有调参的情况下,其测试集的F1分数达到58.76%。当然因为Bagging过程的随机性,每次测试的分数都稍有不同。

如果用Grid Search再进行参数优化:

from sklearn.model_selection import GridSearchCV # 导入网格搜索工具
# 使用网格搜索优化参数
bdt_param_grid = {'base_estimator__max_depth' : [5,10,20,50,100],'n_estimators' : [1, 5, 10, 50]}
bdt_gs = GridSearchCV(BaggingClassifier(DecisionTreeClassifier()),param_grid = bdt_param_grid, scoring = 'f1',n_jobs= 10, verbose = 1)
bdt_gs.fit(X_train, y_train) # 拟合模型
bdt_gs = bdt_gs.best_estimator_ # 最佳模型
y_pred = bdt.predict(X_test) # 进行预测
print("决策树Bagging测试准确率: {:.2f}%".format(bdt_gs.score(X_test, y_test)*100))
print("决策树Bagging测试F1分数: {:.2f}%".format(f1_score(y_test, y_pred)*100))

F1分数可能会进一步上升:

决策树Bagging测试准确率: 86.75%
决策树Bagging测试F1分数: 59.47%

代码中的base_estimator__max_depth,中的base_estimator表示Bagging的基模型,即决策树分类器DecisionTreeClassifier,因此两个下划线后面的参数max_depth隶属于决策树分类器,指的是树的深度。而n_estimators参数则隶属于BaggingClassifier,指的是Bagging过程中树的个数。

准确率为何会提示?其中的关键正是降低了模型的方差,增加了泛化能力,因为每一棵树都是在原始数据集上的不同子集上进行训练的,这是以偏差的小幅增加为代价的,但是最终的模型应用于测试集后,性能对大幅提升。

从树的聚合到随机森林

当我们说到集成学习,最关键的一点是里面各个基模型的相关度要小,差异性要大。异质性越强,集成的效果越好。两个准确率都是99%的模型,但是里面预测结果都一致,也就没有提高的余地了。

那么对树的集成,关键在于这一捆树里面每颗树的差异性是否够大。

在树的聚合中,每一次树分叉时,都会遍历所有的特征,找到最佳的分支方案;而随机森林在此算法基础上的改善就是在树分叉时,增加了对特征选择的随机性,而并不总是考虑全部的特征。这个小小的手法,就在较大程度上进一步提高了各棵树的差异。

假设树分叉时选取的特征数为m,m这个参数值通常遵循下面的规则:

  • 对于分类问题,m 可以设置为特征数的平方根,也就是如果特征是36,那么m大概是6。
  • 对于回归问题,m可以设置为特征数的三分之一,也就是如果特征是36,那么m大概是12。

在Sklearn的集成学习库中,也有RandomForestRegressor和RandomForestClassifier两种随机森林模型,分别适用于分类问题和回归问题。
下面用随机森林分类器解决同样的问题,看一下预测效率:

from sklearn.ensemble import RandomForestClassifier # 导入随机森林分类器
rf = RandomForestClassifier() # 随机森林模型
# 使用网格搜索优化参数
rf_param_grid = {"max_depth": [None],"max_features": [1, 3, 10],"min_samples_split": [2, 3, 10],"min_samples_leaf": [1, 3, 10],"bootstrap": [True,False],"n_estimators" :[100,300],"criterion": ["gini"]}
rf_gs = GridSearchCV(rf,param_grid = rf_param_grid, scoring="f1", n_jobs= 10, verbose = 1)
rf_gs.fit(X_train,y_train) # 拟合模型
rf_gs = rf_gs.best_estimator_ # 最佳模型
y_pred = rf_gs.predict(X_test) # 进行预测
print("随机森林测试准确率: {:.2f}%".format(rf_gs.score(X_test, y_test)*100))
print("随机森林测试F1分数: {:.2f}%".format(f1_score(y_test, y_pred)*100))

测试集预测结果:

随机森林测试准确率: 86.65%
随机森林测试F1分数: 59.48%

这个结果显示随机森林的预测效率比起树的聚合有进一步提高。

从随机森林到极端随机森林

从树的聚合到随机森林,增加了树生成过程中的随机性,降低了方差。顺着这个思路更进一步,就形成了另一个算法叫极端随机森林,它也叫更多树(Extra Trees)。

这么多种“树”让小冰和同学们听的有点呆了。咖哥笑道:“你们看决策树这个算法本身虽然不突出,但是经过集成,衍生出了多少强大的算法。而且这儿还没说完呢,后面还有。”

上面说了,随机森林算法在树分叉时随机选取m个特征作为考量,对于每一次分叉,它还是会遍历所有的分支可能,然后选择基于这些特征的最优分支。这本质上仍属于贪心算法(greedy algorithm),即在每一步选择中都采取在当前状态下最优的选择。而极端随机森林变得更不贪心,它甚至不去考察所有的分叉,而是随机的选择一些分叉,从中拿到一个最优解。

下面用极端随机森林分类器来解决同样的问题:

from sklearn.ensemble import ExtraTreesClassifier # 导入极端随机森林模型
ext = ExtraTreesClassifier() # 极端随机森林模型
# 使用网格搜索优化参数
ext_param_grid = {"max_depth": [None],"max_features": [1, 3, 10],"min_samples_split": [2, 3, 10],"min_samples_leaf": [1, 3, 10],"bootstrap": [True,False],"n_estimators" :[100,300],"criterion": ["gini"]}
ext_gs = GridSearchCV(et,param_grid = ext_param_grid, scoring="f1", n_jobs= 4, verbose = 1)
ext_gs.fit(X_train,y_train) # 拟合模型
ext_gs = ext_gs.best_estimator_ # 最佳模型
y_pred = ext_gs.predict(X_test) # 进行预测
print("更多树测试准确率: {:.2f}%".format(ext_gs.score(X_test, y_test)*100))
print("更多树测试F1分数: {:.2f}%".format(f1_score(y_test, y_pred)*100))

测试集预测结果:

更多树测试准确率: 86.10%
更多树测试F1分数: 56.97%

关于随机森林和极端随机森林的性能,有如下几个观点:

  1. 随机森林算法在绝大多数情况下,是优于极端随机森林算法的;
  2. 极端随机森林因为不需要考虑所有分支可能性,它的运算效率往往要高过随机森林,也就是说速度比较快;
  3. 对于某些数据集,极端随机森林可能拥有更强的泛化功能。但是很难知道具体什么情况下会出现这样的结果,因此不妨各种算法都试试。

比较决策树、树的聚合、随机森林、极端随机森林的效率

刚才的示例代码使用的都是上述算法的分类器版本。咱们再用一个实例来比较决策树、Bagging of Trees、随机森林,以及随机极端森林在处理回归问题上的优劣。

处理回归问题,要选择各种工具的Regressor(回归器)版本,而不是Classifier(分类器)。

这个示例是从Yury Kashnitsky 发布在Kaggle上的一个Notebook的基础上修改后形成,其中展示了4种树模型拟合一个随机函数曲线(含有噪声)的情况,其目的是比较四种算法中哪个对原始函数曲线的拟合最好。

用例的完整代码如下:

# 导入所需的库
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from sklearn.ensemble import (RandomForestRegressor, BaggingRegressor, ExtraTreesRegressor)
from sklearn.tree import DecisionTreeRegressor # 生成需要拟合的数据点——多次函数曲线
def compute(x):return 1.5 * np.exp(-x ** 2) + 1.1 * np.exp(-(x - 2) ** 2)
def f(x):x = x.ravel()return compute(x)
def generate(n_samples, noise):X = np.random.rand(n_samples) * 10 - 410 – 4X = np.sort(X).ravel()y = compute(X) + np.random.normal(0.0, noise, n_samples)X = X.reshape((n_samples, 1))return X, y
X_train, y_train = generate(250, 0.15)
X_test, y_test = generate(500, 0.15)# 用决策树回归模型拟合
dtree = DecisionTreeRegressor().fit(X_train, y_train)
d_predict = dtree.predict(X_test)
plt.figure(figsize=(20, 12))
# ax.add_gridspec(b=False)
plt.grid(b=None)
plt.subplot(2,2,1)
plt.plot(X_test, f(X_test), "b")
plt.scatter(X_train, y_train, c="b", s=20)
plt.plot(X_test, d_predict, "g", lw=2)
plt.title("Decision Tree, MSE = %.2f" % np.sum((y_test - d_predict) ** 2))# 用树的Bagging拟合
bdt = BaggingRegressor(DecisionTreeRegressor()).fit(X_train, y_train)
bdt_predict = bdt.predict(X_test)
# plt.figure(figsize=(10, 6))
plt.subplot(2,2,2)
plt.plot(X_test, f(X_test), "b")
plt.scatter(X_train, y_train, c="b", s=20)
plt.plot(X_test, bdt_predict, "y", lw=2)
plt.title("Bagging for Trees, MSE = %.2f" % np.sum((y_test - bdt_predict) ** 2));# 用随机森林回归模型
rf = RandomForestRegressor(n_estimators=10).fit(X_train, y_train)
rf_predict = rf.predict(X_test)
# plt.figure(figsize=(10, 6))
plt.subplot(2,2,3)
plt.plot(X_test, f(X_test), "b")
plt.scatter(X_train, y_train, c="b", s=20)
plt.plot(X_test, rf_predict, "r", lw=2)
plt.title("Random Forest, MSE = %.2f" % np.sum((y_test - rf_predict) ** 2));# 用计算随机森林模型
et = ExtraTreesRegressor(n_estimators=10).fit(X_train, y_train)
et_predict = et.predict(X_test)
# plt.figure(figsize=(10, 6))
plt.subplot(2,2,4)
plt.plot(X_test, f(X_test), "b")
plt.scatter(X_train, y_train, c="b", s=20)
plt.plot(X_test, et_predict, "purple", lw=2)
plt.title("Extra Trees, MSE = %.2f" % np.sum((y_test - et_predict) ** 2));

从下图的输出中不难看出,曲线越平滑,过拟合越小,机器学习算法也就越接近原始函数曲线本身,损失也就越小。

Bagging——四种算法之比较

对于后三种集成算法,每次训练得到的MSE都是不同的,因为算法内部均含有随机成分。经过集成学习后,较之单棵决策树,三种集成学习算法都显著的降低了在测试集上的MSE。

本文经作者授权,节选自人民邮电出版社的机器学习小白入门书《零基础学机器学习》,这本书专门为希望轻松快乐学习机器学习和深度学习技术的您而量身定做。喜欢的读者可以直接去京东购买呦!:)作者谢谢您的支持与赞赏!

https://item.jd.com/12763913.html
http://product.dangdang.com/29159728.html

上一篇: 集成学习基础 - 方差与偏差
下一篇: 集成学习精讲之Boosting

总结一下:Bagging,是并行地生成多个基模型,利用基模型的独立性,然后通过平均或者投票来降低模型的方差。后面我们还要继续介绍Boosting,Stacking / Blending,以及Voting / Averaging这些算法

集成学习精讲02 - Bagging方法:多个基模型的聚合(SAP大神黄佳新作《零基础学机器学习》节选)相关推荐

  1. 集成学习精讲之Boosting - SAP大神黄佳新作《零基础学机器学习》节选

    Boosting的意思就是提升,这是一族通过训练弱学习模型的肌肉将其提升为强学习模型的算法.要想在机器学习竞赛中追求卓越,Boosting是一种必须的存在.这是一个属于高手的技术. 图片来源于网上,侵 ...

  2. 集成学习精讲01 - SAP大神黄佳新作《零基础学机器学习》节选

    球赛中,防守方的联防策略是非常有效的,几个队员彼此照应,随时协防.换位.补位,护送等,相互帮助,作为一个整体作战,而集成学习,就是机器学习里面的协同作战!如果你训练出一个模型比较弱,又训练出一个模型还 ...

  3. 【零基础学机器学习 3】机器学习类型简介:监督学习 - 无监督学习 - 强化学习

  4. 集成学习-3.voting与bagging

    参考文献ensemble-learning 1. 投票法的思路 投票法是集成学习中常用的技巧,可以帮助我们提高模型的泛化能力,减少模型的错误率.举个例子,在航空航天领域,每个零件发出的电信号都对航空器 ...

  5. 机器学习 集成学习篇——python实现Bagging和AdaBOOST算法

    机器学习 集成学习篇--python实现Bagging和AdaBOOST算法 摘要 Bagging算法 Adaboost算法 摘要 本文通过python实现了集成学习中的Bagging和AdaBOOS ...

  6. ML《集成学习(一)Bagging 和 Random Forest》

    今天一起来学习集成学习,其中的Bagging和随机森林(Random Forest). 一:bootstrap 二:Bagging 三:随机森林(Random Forest)

  7. 基于集成学习的小麦赤霉病高光谱图像识别方法研究

    基于集成学习的小麦赤霉病高光谱图像识别方法研究 1.研究思路 [1]深度学习方法,通过构建深度神经网络模型对小麦赤霉病进行识别.构建四个不同结构的深度神经网络模型,并对这四个模型进行结构分析. [2] ...

  8. 研究型论文_基于双层异质集成学习器的入侵检测方法

    文章目录 基于双层异质集成学习器的入侵检测方法 论文摘要 论文解决的问题 1.模型体系结构 2.数据降维 3.交叉验证策略 4.分类评估算法 5.多分类器集成算法 6.总结 参考文献 基于双层异质集成 ...

  9. python自学需要哪些基础知识-零基础学Python应该学习哪些入门知识及学习步骤安排...

    众所周知,Python以优雅.简洁著称,入行门槛低,可以从事Linux运维.Python Web网站工程师.Python自动化测试.数据分析.人工智能等职位!就目前来看,Python岗位人才缺口高达4 ...

最新文章

  1. 利用栈的特性,将十进制数转换成八进制数
  2. 利用tcpdump抓取mysql sql语句
  3. 台式计算机属于,pc机属于什么型计算机
  4. Python将文字转拼音
  5. 将JINQ与JPA和H2一起使用
  6. Swipper.js实现轮播功能
  7. 让Kubernetes成为数据中心操作系统的一等公民
  8. 网络监视工具nethogs命令
  9. 为什么PHP能够受到大家追捧和喜爱,又为什么饱受嘲讽?
  10. Unity Editor 查找资源依赖、反向查找资源依赖Dependencies
  11. 开源项目推荐:SCADA组态软件Qt,kanzi,C#,MFC和WEB大全(收藏版)
  12. 吴恩达机器学习笔记-无监督学习
  13. 华为商店的软件可以鸿蒙,鸿蒙到底想要什么?是维护渠道的霸权还是万物互联?...
  14. 面对满天繁星似的知识.如何做到老虎吃天
  15. 激活 visio Premium 2010 vol 版本
  16. 网页上的文字不能复制怎么办?
  17. 如何给电脑硬盘分区?
  18. Docker Note [vaynexiao]
  19. OpenGL 图形库的使用(二十五)—— 高级OpenGL之帧缓冲Framebuffers
  20. 如何成为一门领域的专家2

热门文章

  1. 3DMAX快捷键整理
  2. Swift - 使用原生库进行 JSON 解析和生成
  3. 计算机数学课程标准,小学数学课程标准解读
  4. java 银行利息_java银行利息
  5. 计算机能够自动完成运算或处理过程的基础是,计算机文化基础题库.doc
  6. 将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的“a“改为“b“(封装成一个方法)
  7. asus笔记本x44h
  8. 哈佛导师经典评论:不要轻易和少妇上床(转贴)
  9. 产品推广合作扁平化通用PPT模板
  10. 维纶触摸屏--串口和以太网穿透设置