机器学习之集成学习概念基础

目录

一、集成学习

二、Boosting系列算法

三、Bagging系列算法

四、Stacking算法

五、总结


一、集成学习

集成学习(ensemble learning)通过构建并结合多个机器学习器来完成学习任务,它并不是一种单独的机器学习算法。集成学习也被称为多分类器系统(multi-classifier system),往往被视为一种元算法(meta-algorithm)

在集成学习中,先对个体学习器(如决策树算法、 BP神经网络算法等)进行训练,再通过某种集成策略将它们结合起来。若集成中只包含一种个体学习器,那么这样的集成就是同质集成,其个体学习器也被称为基学习器(base learner)。 集成也可以包含不同类型的个体学习器,例如同时包含决策树和神经网络,这样的集成被称为异质集成,此时个体学习器被称为组件学习器或直接称为个体学习器。

集成学习示意图

集成学习通过将多个学习器进行结合,通常可以获得比单一学习器更优的泛化性能,即可以达到“三个臭皮匠顶个诸葛亮”的效果。集成学习之所以能够获得比所有单个学习器更优的效果,在于它将众多学习器结合起来所使用的策略。

在一般经验中,将多个东西混合在一起,通常取得较为平均的效果,即比其中最好的要差、比其中最差的要好。这是简单平均的方法,即将多个基学习器的预测结果直接融合,求多个预测结果的平均值。在此基础上,也可使用加权平均法,即根据基学习器的准确率,进行加权融合,将准确性高的模型赋予更高的权重。

除平均法外,还有投票法。以下是西瓜书中举的“投票法”的例子:

集成个体应“好而不同”

在(a)、(b)、(c)三个例子中,h1、h2、h3各表示一个机器学习分类器,若测试例子成功分类记为“√”,否则为“×”。若是通过简单的投票法,即少数服从多数。集成学习不一定能够获得比所有单个学习器更优的效果,可以没有提升,甚至比所有单个学习器的效果更差。上例表明:要使集成学习的效果好,个体学习器应具备一定的准确性,并且各个学习器之间具有差异(才可以互补)。这也是为什么常用决策树作为基学习器的原因:由于数据样本扰动对决策树影响较大,因此各个决策树学习器之间存在着较大的差异。

集成学习的分类:

同质集成学习中,按照个体学习器之间是否存在依赖关系可以分为两类。

①Boosting系列算法:个体学习器之间存在强依赖关系,需要串行生成(即先训练完一个,再根据它的表现训练下一个)。

②Bagging系列算法、随机森林算法:个体学习器之间不存在强依赖关系,可以并行生成。

另外,还有Stacking算法,类似于Bagging系列算法,其个体学习器之间是相互独立的,但它多了一步:在生成若干不同的、且独立的基学习器之后,还要通过元学习器(meta-learner)将基学习器的输出组合起来进行训练,以得到最终的预测结果。而Bagging系列算法是通过平均法或投票法的方式将基学习器结合。

二、Boosting系列算法

Boosting系列算法类似于人类的学习方法,例如我们人在学习某个知识时,在一开始掌握得并不牢固,但可以通过后续的查漏补缺来加深记忆。

Boosting系列算法先从初始训练集训练出一个基学习器,再根据其表现来对训练样本分布进行调整,即更新训练样本的权重。使得先前基学习器做错的训练样本在训练下一个基学习器时得到更多关注;如此重复进行,直至基学习器数目达到事先指定的值T,最终将这T个基学习器进行加权结合,各个学习器的权重在训练过程中决定。 

Boosting系列算法中最常见的算法包括AdaBoost算法(Adaptive boosting,自适应增强),GBDT算法(Gradient Boost Decision Tree,梯度提升决策树),XGBoost算法(eXtreme Gradient Boosting,极限梯度提升)。

AdaBoost:

AdaBoost伪代码

首先,对样本权重初始化,D_{1}(x)表示初始样本权重为样本总数m分之一;随后基于当前样本分布D_{t} 从数据集D中训练出分类器 h_{t};再根据分类器h_{t}的误差\epsilon _{t}(分类误差应小于0.5)确定下一轮的样本权重,并更新样本分布。

GBDT:

AdaBoost算法通过增大错分训练样本的权重、调整训练样本分布来改进模型。而GBDT是对AdaBoost进行推广,通过梯度下降法计算负梯度来改进模型,所以可以使用更多种类的目标函数。GBDT算法使用CART回归树作为基学习器,它的每一次迭代是在上一轮分类器的基础上继续训练,去拟合上一轮分类器的预测结果与真实值之间的差值。损失函数可以选择平方损失函数、0-1损失函数、对数损失函数等,如果选择平方损失函数,那么分类器预测结果与真实值之间的差值即常说的残差。

GBDT伪代码

XGBoost: 

XGBoost是梯度提升决策树算法的高效实现,但它与GBDT算法有很多不同之处(做了很多优化)。GBDT只支持CART树作为基学习器,而XGBoost还支持其他的弱学习器,如线性分类器。在算法的优化方式上,GBDT的损失函数只对误差部分做负梯度(一阶泰勒)展开,而XGBoost的损失函数对误差部分做二阶泰勒展开,同时使用一阶二阶导数,更加准确。

而且,XGBoost在处理含有缺失值的特征时,通过枚举所有缺失值在当前节点是进入左子树还是右子树来决定缺失值的处理方式(选择增益最大的方式)。XGBoost在代价函数中还引入了L1和L2正则化项,可以防止过拟合,泛化能力更强。除此之外,还可以通过Shrinkage降低模型优化的速度,逐步逼近最优模型,避免过拟合。

三、Bagging系列算法

上面提到过,想得到泛化性能强的集成,集成中的个体学习器应尽可能相互独立,但在现实任务中无法做到。不过可以用另一种方式来实现:将训练数据集采样获得若干个不同的子数据集,再分别训练出一个基学习器。如此一来,由于训练数据不同,获得的基学习器也会具有较大的差异。但还要注意,若子数据集的规模太小,基学习器可能不足以进行有效学习,所以我们可考虑使用相互有交叠的采样子集。

Bagging(Bootstrap Aggregating)算法中使用自助采样法(Bootstrap sample)对数据集进行采样。即在给定训练集中进行有放回的均匀抽样,每选中一个样本后再将其放回初始数据集,使得下次采样时该样本仍有可能被选中。经过若干次随机采样操作后有的样本会在采样集里多次出现,而有的则可能从未出现。在对所有基学习器的预测输出进行结合时,Bagging算法通常对分类任务使用简单投票法,对回归任务使用简单平均法。

Bagging算法伪代码

其中,D_{bs}表示自助采样所产生的样本分布。

随机森林:

随机森林(Random Forest , RF)是Bagging算法的一个拓展变体,RF在以决策树为基学习器构建 Bagging 集成的基础上,进一步在决策树的训练过程中引入了随机属性选择。具体来说,传统决策树在选择划分属性时是在当前结点的属性集合(假定有d个属性)中选择一个最优属性。而在RF中,对基决策树的每个结点,先从该结点的属性集合中随机选择一个包含k个属性的子集,然后再从这个子集中选择一个最优属性用于划分。当k=d时,RF算法中的基决策树构建与传统决策树相同;当k=1,则是完全随机选择1个属性用于划分。一般推荐k=log_{2}d.

RF算法在很多现实任务中展现出强大的性能,虽然它对Bagging做了一点小改动——在Bagging基学习器通过样本扰动获得“多样性”的基础上,还通过属性扰动提升个体学习器之间的差异性。当随机森林只存在少量基学习器时,往往性能较差,但随着基学习器个数增加,RF算法的性能逐渐提升。

四、Stacking算法

在上面提到过,集成学习中将多个基学习器结合的方式可以基于简单平均或投票的方法,但通常鲁棒性较差。当训练数据很多时,一种更为强大的结合策略是使用"学习法",即通过另一个学习器来进行结合。Stacking是学习法的典型代表,其个体学习器被称为初级学习器,而用于结合的学习器称为次级学习器或元学习器(meta-learner)。

Stacking算法伪代码

在训练阶段,次级学习器的训练集是利用初级学习器产生的(若直接用初级学习器的训练集,容易过拟合)。一般是通过使用交叉验证或留一法,用初级学习器训练过程中未使用的样本来产生次级学习器的训练样本。

在Sklearn中已实现了stacking模型:StackingClassifier。下面通过鸢尾花数据集来验证stacking比单模型的效果提升。

import warnings
warnings.filterwarnings('ignore')
import itertools
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from xgboost import XGBClassifier
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from mlxtend.classifier import StackingClassifier
from sklearn.model_selection import cross_val_score, train_test_split
from mlxtend.plotting import plot_learning_curves
from mlxtend.plotting import plot_decision_regions

#加载数据
iris = datasets.load_iris()
X, y = iris.data[:, 1:3], iris.target


clf1 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=3, min_child_weight=2, subsample=0.7,
                     colsample_bytree=0.6, objective='binary:logistic')
clf2 = RandomForestClassifier() 
clf3 = SVC(C=0.1, probability=True)
lr = LogisticRegression()
sclf = StackingClassifier(classifiers=[clf1, clf2, clf3], 
                          meta_classifier=lr)


label = ['XGB', 'RF', 'SVC', 'Stacking']
clf_list = [clf1, clf2, clf3, sclf]
    
fig = plt.figure(figsize=(10,8))
gs = gridspec.GridSpec(2, 2)
grid = itertools.product([0,1],repeat=2)


clf_cv_mean = []
clf_cv_std = []
for clf, label, grd in zip(clf_list, label, grid):
        
    scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')
    print("Accuracy: %.2f (+/- %.2f) [%s]" %(scores.mean(), scores.std(), label))
    clf_cv_mean.append(scores.mean())
    clf_cv_std.append(scores.std())
        
    clf.fit(X, y)
    ax = plt.subplot(gs[grd[0], grd[1]])
    fig = plot_decision_regions(X=X, y=y, clf=clf)
    plt.title(label)


plt.show()

输出结果如下:

Accuracy: 0.94 (+/- 0.06) [XGB]
Accuracy: 0.95 (+/- 0.05) [RF]
Accuracy: 0.93 (+/- 0.04) [SVC]
Accuracy: 0.93 (+/- 0.06) [Stacking]

五、总结

集成学习可以用于解决分类问题、回归问题、特征选取问题等等,在各类竞赛中十分常见,XGBoost更是收到众多数据科学家的喜爱,堪称数据竞赛打榜上分神器。融合多个不同的模型,以获得比单模型更优的预测结果,这就是集成学习的强大能力。上面提到的平均法(简单平均、加权平均)、投票法(简单投票、加权投票)以及Stacking都是对多个基学习器的结合策略。平均法和投票法简单而高效,但对模型的融合效果一般不如Stacking方法,不过Stacking方法要实现多个模型的训练,常常要花费大量的时间。在不同任务中,应结合实际情况选取集成策略。

参考资料:

1、周志华:《机器学习》

猜你喜欢

转载自blog.csdn.net/weixin_44458771/article/details/127047573
今日推荐