集成模型:Bagging、Boosting和Stacking

跟我一起机器学习系列文章将首发于公众号:月来客栈,欢迎文末扫码关注!

1 引例

通过前面几篇文章的学习,我们已经了解了机器学习中的多种分类和回归模型。那现在有一个问题就是,哪一个模型最好呢?以分类任务为例,当我们拿到一个需要进行分类的任务时,如果是你你会选择哪种模型进行建模呢?一个狡猾的办法就是挨个都试一下,那这样做有没有道理呢?还别说,我们在实际的情况中真的可能会都去试一下,因为在没有实验之前谁都不会知道真正的结果。假如现在我们对A、C、D这三个模型进行建模,最后得到结果是:A的分类准确率为0.93,B的分类准确率为0.95,C的准确率为0.88。那我们最终应该选择哪一个模型呢?是模型B吗?

假设一共有100个数据样本,数据标签为二分类(正、负两类),如图所示为三个模型的部分分类结果。其中图示中的5个样本,模型A和C均能分类正确,而模型B不能分类正确。如果我们此时将这三个模型一起用于分类任务的预测,并且对于每一个样本的最终输出结果采用基于投票的规则在三个模型的输出结果中进行选择。例如图示中的第1个样本,模型A和C均判定为“负类”只有B判定为“正类“,则最后的输出便为”负类“。那么此时,我们就有可能得到一个分类准确率为1的“混合”模型。

注:在其余的95个样本中,假设根据投票规则均能分类正确

2 集成学习

在机器学习中,基于这种组合思想来提高模型精度的方法被称为集成学习(ensemble learning)。俗话说”三个臭皮匠,赛过诸葛亮“,这句话完美的阐述了集成学习的潜在思想——通过将多个弱的模型结合在一起来提高最终结果的预测精度。

常见的集成模型主要包括以下三种:

  • Bagging;Bagging的核心思想为并行地训练一系列各自独立的同类模型,然后再将各个模型的输出结果按照某种策略进行聚合(例如分类中可采用投票策略,回归中可采用平均策略)。
  • Boosting;Boosting的核心思想为串行地训练一系列前后依赖的同类模型,即后一个模型用来对前一个模型的输出结果进行纠正。
  • Stacking;Stacking的核心思想为并行地训练一系列各自独立的不同类模型,然后通过训练一个元模型(meta-model)来将各个模型的输出结果进行结合。

下面内容我们就来大致了解一下各类集成模型中常见的算法和使用示例。

2.1 Bagging

跟我一起机器学习系列文章将首发于公众号:月来客栈,欢迎文末扫码关注!

Bagging的全称为 bootstrap aggregation,而这两个单词也分别代表了Bagging在执行过程中的两个步骤:①bootstrap samples,②aggregate outputs。也就是Bagging首先从原始数据中随机抽取多组包含若干数量样本的子训练集;然后再分别以不同的子训练集得到不同的基模型进行聚合:
y = 1 M ∑ m = 1 M f m ( x ) (1) y=\frac{1}{M}\sum_{m=1}^Mf_m(x)\tag{1} y=M1m=1Mfm(x)(1)
其中 M M M表示基模型的数量, f m ( x ) f_m(x) fm(x)表示不同的基模型。

同时,由于Bagging的策略是取所有基模型的”平均“值作为最终模型的输出结果,因此Bagging集成方法能够很好的降低模型高方差(过拟合)的情况。因此通常来说,在使用Bagging集成方法的时候,可以尽量使得每个基模型都出现过拟合的现象。

2.1.1 Bagging on sklearn

我们下面以sklearn中实现的BaggingClassifier为例,并对其中的参数进行简单的说明一下。在sklearn中,我么可以通过from sklearn.ensemble import BaggingClassifier来导入bagging集成方法。

    def __init__(self,
                 base_estimator=None,
                 n_estimators=10,
                 max_samples=1.0,
                 max_features=1.0,
                 bootstrap=True,
                 bootstrap_features=False,
                 n_jobs=None,
                 verbose=0):

上面的初始化函数是类BaggingClassifier中的一部分参数,其中base_estimator表示所使用的基模型;n_estimators表示需要同时训练多少个基模型;max_samples表示每个子训练集中最大的样本数量;max_features表示子训练集的最大特征维度(由于是随机抽样,所以不同的子训练集特征维度可能不一样);bootstrap=True表示在每个子训练集中同一个样本可以重复出现;bootstrap_features=False表示在每个子训练集中每个特征维度不能重复出现(如果设置为True,极端情况下所有的特征维度可能都一样)。

如下代码所示为以KNN作为基模型进行Bagging集成的示例用法:

if __name__ == '__main__':
    x_train, x_test, y_train, y_test = load_data()
	bagging = BaggingClassifier(KNeighborsClassifier(n_neighbors=3),
                                n_estimators=5,
                                max_samples=50,
                                max_features=3,
                                bootstrap=True,
                                bootstrap_features=False)
    bagging.fit(x_train, y_train)
    print(bagging.estimators_features_)
    print(bagging.score(x_train, y_train))
    print(bagging.score(x_test, y_test))
#结果:
[array([2, 0, 1]), array([1, 2, 3]), array([2, 3, 1]), 
 array([1, 0, 3]), array([2, 1, 3])]# 5个子训练集不同的特征维度
0.9714285714285714
0.9555555555555556

2.1.2 Bagging on decision tree

正如我们上面说到,在Bagging方法进行模型集成的时候,基模型可以是其他任意模型,自然而然也就可以是决策树了。由于对决策树使用Bagging方法是一个较为受欢迎的研究方向,因此也给它取了另外一个名字随机森林(random forests)。根据Bagging的思想来看,随机森林这个名字也很贴切,一系列的树模型就变成了森林。因此在sklearn中,如果是通过BaggingClassifier来实现Bagging集成,当base_estimator=None时,默认就会采用决策树作为基模型。

如图所示为随机采样后生成的若干决策树模型,可以看到同一个样本在不同树中所归属的节点不同,甚至连类别也可能不同。但是这也充分体现了集成模型的优点,通过”平均“来降低误差。如下所示代码为基于决策树的Bagging集成方法在sklearn中的两种实现方式:

from sklearn.ensemble import BaggingClassifier,RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier

if __name__ == '__main__':
    x_train, x_test, y_train, y_test = load_data()
    bagging = BaggingClassifier(n_estimators=5,
                                max_samples=50,
                                max_features=3,
                                bootstrap=True,
                                bootstrap_features=False)
    bagging.fit(x_train, y_train)
    print(bagging.score(x_test, y_test))

    rfc = RandomForestClassifier(n_estimators=5)
    rfc.fit(x_train,y_train)
    print(rfc.score(x_test,y_test))

2.2 Boosting

Boosting同Bagging一样,都是用于提高模型的泛化能力。不同的是Boosting方法是通过训练一系列串行的模型来达到这一目的。在Boosting的一些列串行基模型中,每个基模型都是对前一个基模型输出结果的改善。如果前一个基模型对某些样本进行了错误的分类,那么后一个基模型就会针对这些错误的结果进行改善。那么在经过一系列串行基模型的拟合后,最终就会得到一个更加准确的结果。因此,Boosting集成方法经常被用于改善模型高偏差的情况(欠拟合现象)

在Boosting集成模型中,两种较为常见的算法分别是AdaBoostGradient Tree Boosting。使用示例可以参见[3]。由于笔者没做过这方面的研究,所以两者的具体原理我们在这里暂不探讨,大家有兴趣可以自行去查找相关资料。

2.3 Stacking

跟我一起机器学习系列文章将首发于公众号:月来客栈,欢迎文末扫码关注!

不同于Bagging和Boosting这两种集成学习方法,Stacking集成方法首先通过训练得到多个基于不同算法的基模型,然后再将通过训练一个元模型来对其它模型的输出结果进行融合。例如我们现在选择以逻辑回归、朴素贝叶斯和KNN作为基模型,以决策树作为元模型。Stacking集成方法的做法为:首先将训练得到前三个基模型;然后再以基模型的输出作为决策树的输入训练元模型;最后以决策树的输出作为真正的分类结果。

如下代码所示为sklearn中实现上述过程的部分代码:

if __name__ == '__main__':
    x_train, x_test, y_train, y_test = load_data()
    estimators = [('logist', LogisticRegression()),
                  ('nb', MultinomialNB()),
                  ('knn', KNeighborsClassifier(n_neighbors=3))]
    stacking = StackingClassifier(estimators=estimators,
                                  final_estimator=DecisionTreeClassifier(),
                                  cv=3)
    stacking.fit(x_train, y_train)
    acc = stacking.score(x_test, y_test)
    print(acc)

#结果:
0.9111111111111111

3 总结

在这篇文章中, 笔者首先通过一个引例大致介绍了什么是集成模型;然后再分别介绍了三种常见的集成模型:Bagging、Boosting和Stacking,其中对于Bagging和Stacking两种集成模型还列举了sklearn中的示例用法。本次内容就到此结束,感谢阅读!

若有任何疑问与见解,请发邮件至moon-hotel@hotmail.com并附上文章链接,青山不改,绿水长流,月来客栈见!

引用

[1] Ensemble Learning to Improve Machine Learning Results, https://blog.statsbot.co/ensemble-learning-d1dcd548e936

[2] Ensemble methods: bagging, boosting and stacking, https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205

[3] Ensemble methods, https://scikit-learn.org/stable/modules/ensemble.html#ensemble

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页