美文网首页
集成学习介绍之二——Boosting算法

集成学习介绍之二——Boosting算法

作者: StataPython数据分析 | 来源:发表于2020-07-02 10:38 被阅读0次

本文作者:王 歌
文字编辑:戴 雯
技术总编:张 邯

我们上一次介绍了集成学习中的Bagging算法以及由它拓展的随机森林,今天我们继续介绍集成学习的另一类——Boosting算法。

1算法介绍

相比于Bagging的并行,Boosting是串行生成的算法,即每一次的训练都是对上一次的修正,更注重上一次训练时出现判断错误的样本,对分错的样本赋予更大的权重。在训练得到n个学习器后再对这些学习器进行加权结合,这就是Boosting的基本思想。Boosting一般有两种更新权重的方法,一是给 样本重新赋权 ,二是 重新在原始样本中按照权重进行有放回抽样
Boosting算法中有几个算法是经常用到的,这也是我们今天要讲解的重点——AdaBoostGBDTXGBoost。这三种算法都是源于Boosting算法的基本思想,下面我们主要介绍这三种算法在Boosting的基础上有哪些差别。
对于 AdaBoost(Adaptive Boosting) 算法,首先从每一轮权值改变的方式设置上,该算法在初始化时,将所有弱学习器的权重都设置为1/N,在后续的迭代中,那些在上一轮迭代中被预测错的样本的权重将增加,最后对得到的所有学习器进行加权组合。为了防止过拟合,还可以在迭代中加入正则化项。AdaBoost不像我们下面介绍的两种方法,它可以自己定义使用的基学习器,在这一点上要更有优势。

GBDT(Gradient Boosting Decision TreeGradient Tree Boosting ,梯度树提升,回归时也简称GBRT,这里统一使用GBDT)并不是通过AdaBoost那样在每一轮迭代中更改权重,而是使用新的分类器去拟合前面分类器预测的残差,使每一次的计算都能减少上一轮的残差,并在残差减少的方向建立新的学习器,也就是在每一轮迭代中对损失函数的负梯度方向构造决策树,该方法将基学习器限定在只能使用CART决策树来进行分类和回归。我们可以通过剪枝或子采样、正则化来防止出现过拟合。所以GBDT的基学习器是决策树,通过梯度提升(Gradient Boosting)进行集成。相比于同样使用决策树为基学习器的随机森林,GBDT 减少了模型的偏差,而随机森林减少的是模型的方差。

XGBoost(eXtreme Gradient Boosting) 算法就是 GBDT的改进,因此使用的依然是决策树作为基学习器。它对GBDT的改进主要是两个方面,一是GBDT将目标函数泰勒公式展开到一阶,而XGBoost将目标函数泰勒公式展开到了二阶,提升了预测效果;二是XGBoost增加了自动处理缺失值特征的策略;三是XGBoost在损失函数中加入了正则项,控制了模型的复杂度,因此XGBoost的表现通常要优于GBDT。

2类参数介绍

在sklearn中AdaBoost算法有两个类,即AdaBoostClassifierAdaBoostRegressor,前者用于分类,后者用于回归。我们这里主要介绍AdaBoostClassifier,由于基学习器主要使用的是默认的决策树算法,因此其中大部分参数我们在上一次以及之前的介绍中已经提到过,不再赘述,另有两个新的参数要了解:
(1)algorithm:设定AdaBoost分类使用的算法,可以选择SAMME和SAMME.R,两者使用的弱学习器权重不同,其中SAMME使用对样本集分类效果作为弱学习器权重,SAMME.R使用了对样本集分类的预测概率作为弱学习器权重,由于SAMME.R使用了连续值,迭代速度一般比SAMME快,默认使用的也是SAMME.R算法;
(2)learning_rate:设定弱学习器的权重缩减系数v,0<v≤1,要达到同样的拟合效果,较小的v比较大的v需要更多次的迭代,默认为1。

GradientBoostingClassifier为GBDT分类算法的类,GradientBoostingRegressor为GBDT的回归类。在GradientBoostingClassifier类中,主要有以下几个新的参数要注意:
(1)subsample:设定训练每个决策树所用到的子样本占总样本的比例,取值为(0,1]这里使用的是不放回抽样,默认取1,即不使用子采样;
(2)init:设定初始化的弱学习器,若我们有先验模型,可以将其作为初始化的学习器;
(3)loss:设定每次结点分裂所使用的最小化损失函数,有对数似然损失函数"deviance"和指数损失函数"exponential"两种选择,默认为"deviance"。

而XGBoost算法要使用xgboost类库来实现。sklearn中没有集成xgboost,因此首先要单独下载安装。xgboost有两种接口,一种是自带的原生python接口,另一种是sklearn接口,两种接口的使用基本一致,得到的结果也是一样的,只是在三个参数名上会稍有不同,并且在导入时,原生接口可直接使用以下命令:

import xgboost as xgb

而sklearn的接口可以使用(若为回归则使用XGBRegressor):

from xgboost.sklearn import XGBClassifier

一般我们更推荐使用sklearn的接口,我们这里也是以sklearn接口为基础来介绍和演示。除了base_scorelearning_ratemax_depthn_estimatorsn_jobsrandom_statesubsample和前面介绍的类相同的参数外,还有以下参数:

(1)objective:确定使用的目标函数,默认为'binary:logistic',若为回归问题,也可选择'reg:linear'、'reg:logistic',若为二分类,可以选择'binary:logistic'、'binary:logitraw',前者得到概率,后者得到类别,若为多分类,可以选择'multi:softmax num_class=n'、'multi:softprob num_class=n',前者得到类别,后者得到概率;
(2)booster:确定弱学习器类型,默认为gbtree,即CART决策树,也可选择gbliner(线性模型)作为基分类器;
(3)gamma:设定结点分裂所需要的最小损失函数下降值,当损失函数下降值低于这个值时不再向下划分,默认为None;
(4)min_child_weight:设定子结点权重的最小值,小于此值时不再分裂,默认为None;
(5)max_delta_step:设定每棵树权重改变的最大步长,默认为None;
(6)colsample_bytree:训练每棵树时的属性采样比例,默认为None,即不采样使用所有属性;
(7)colsample_bynode:训练某一个树结点时的属性采样比例,默认为None;
(8)colsample_bylevel:训练某一层时的属性采样比例,默认为None;
(9)reg_alpha:设定L1正则化系数,默认为None;
(10)reg_lambda:设定L2正则化系数,默认为None;
(11)scale_pos_weight:类别不平衡时设定负例和正例的比例,默认为None;
(12)importance_type:用来设置如何计算各个属性的重要程度,默认为'gain',还可选择'weight'、'cover'、'total_gain'或'total_cover','gain'和'total_gain'分别表示通过计算属性被选作分裂属性时带来的平均增益和总增益来计算重要性,'cover'和'total_cover'则分别通过计算属性被选作分裂时的平均样本覆盖度和总体样本覆盖度来计算重要性,'weight'通过属性被选作分裂特征的次数来计算重要性,可以通过调用booster的get_score方法查看对应的属性权重。

3算法实例

针对我们上面介绍的三个库,我们来实际操作对比一下,这里我们以分类算法为例,使用鸢尾花的数据,首先我们分别输出三种算法的预测值和准确度,程序如下:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import AdaBoostClassifier, GradientBoostingClassifier
from xgboost.sklearn import XGBClassifier
from sklearn.metrics import accuracy_score

iris_sample = load_iris()
x_train, x_test, y_train, y_test = train_test_split(
    iris_sample.data, iris_sample.target, test_size=0.25, random_state=123)
print('真实值:', y_test)
# AdaBoost分类
adbclf = AdaBoostClassifier(learning_rate=0.1, n_estimators=100)
adbclf.fit(x_train, y_train)
y_adb_pre = adbclf.predict(x_test)
print('AdaBoost预测:', y_adb_pre)
print('AdaBoost准确度:', accuracy_score(y_test, y_adb_pre))
# GBDT分类
gbdtclf = GradientBoostingClassifier(
    max_depth=5, learning_rate=0.7, n_estimators=100)
gbdtclf.fit(x_train, y_train)
y_gbdt_pre = gbdtclf.predict(x_test)
print('GBDT预测:', y_gbdt_pre)
print('GBDT准确度:', accuracy_score(y_test, y_gbdt_pre))
# XGBoost分类
xgbclf = XGBClassifier(max_depth=5, learning_rate=0.7,
                       n_estimators=100, objective='multi:softmax')
xgbclf.fit(x_train, y_train)
y_xgb_pre = xgbclf.predict(x_test)
print('XGBoost预测:', y_xgb_pre)
print('XGBoost准确度:', accuracy_score(y_test, y_xgb_pre))

预测结果如下图:


image

可以看到按照既定参数得到的模型中,XGBoost的预测准确度最高。在此基础上我们查看一下XGBoost模型中的属性重要性并输出重要性图,程序如下:

from matplotlib import pyplot as plt
from xgboost import plot_importance
plot_importance(xgbclf)
plt.show()

结果如下图:


image

由上图可以看到,第四个属性petal width(花瓣宽度)的重要性最高。
相比而言,AdaBoost可以使用各种模型来构建弱学习器,并且不容易发生过拟合,但对异常数据较敏感,容易受到噪声的干扰;GBDT算法则对异常点是鲁棒的,可以处理混合类型的特征,比较适合低维数据,能够处理非线性数据;而XGBoost算法由于是对GBDT的改进,因此它的运算速度和算法都会优于GBDT,不容易发生过拟合,计算量较小。目前在结构化数据上,XGBoost算法的表现会更好,因此也受到各种比赛的欢迎。大家快去试试吧!

相关文章

网友评论

      本文标题:集成学习介绍之二——Boosting算法

      本文链接:https://www.haomeiwen.com/subject/bnulqktx.html