查看原文
其他

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

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:王 歌 

文字编辑:戴 雯 

技术总编:张 邯



Stata暑期线上课程火热招生中~

    爬虫俱乐部将于2020年7月11日至14日线上举行为期四天的Stata编程技术定制培训。课程通过案例教学模式,旨在帮助大家在短期内掌握Stata的基本命令、编程、数据处理以及结果输出等技术,并针对最新版Stata中的实用新功能做出详细介绍,包括框架功能(frame:读入多个数据集)等等。同时,此次云端课程提供录播,提供线上答疑。详细培训大纲及报名方式请查看《Stata云端课程来啦》,或点击文末阅读原文直接提交报名信息呦~

另外,应广大学员需求,爬虫俱乐部将于2020年7月25日至28日线上举行Python编程技术训练营,帮助大家在掌握Python基本思想的基础上,学习科学计算技术与网络数据抓取技术,详情可点击《Python云端培训课程开始报名~》Stata和Python一起报名有超值优惠,详情咨询联系人。

导读



我们上一次介绍了集成学习中的Bagging算法以及由它拓展的随机森林(《取长补短、互通有无——集成学习介绍之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 numclass=n'、'multi:softprob numclass=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'、'totalgain'或'totalcover','gain'和'totalgain'分别表示通过计算属性被选作分裂属性时带来的平均增益和总增益来计算重要性,'cover'和'totalcover'则分别通过计算属性被选作分裂时的平均样本覆盖度和总体样本覆盖度来计算重要性,'weight'通过属性被选作分裂特征的次数来计算重要性,可以通过调用booster的get_score方法查看对应的属性权重。

3算法实例

针对我们上面介绍的三个库,我们来实际操作对比一下,这里我们以分类算法为例,使用鸢尾花的数据,首先我们分别输出三种算法的预测值和准确度,程序如下:
from sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitfrom sklearn.ensemble import AdaBoostClassifier, GradientBoostingClassifierfrom xgboost.sklearn import XGBClassifierfrom 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))
预测结果如下图:
可以看到按照既定参数得到的模型中,XGBoost的预测准确度最高。在此基础上我们查看一下XGBoost模型中的属性重要性并输出重要性图,程序如下:
from matplotlib import pyplot as pltfrom xgboost import plot_importanceplot_importance(xgbclf)plt.show()

结果如下图:

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







对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
往期推文推荐

PDF文本信息提取(二)

取长补短、互通有无 ——集成学习介绍之Bagging &随机森林

PDF表格信息提取
神经网络——brain
marktouse标记使用变量
换种视角看问题——支持向量机(SVM)
提取PDF文本信息:入门
毕业季|b站《入海》评论爬取
Stata云端课程来啦
利用广义线性模型实现的分类——Logistic回归
Requests get爬虫之设置headers
数据分析薪资待遇如何?——跟我来,带你看
Vardistinct一键去重计数
从statsmodels到线性回归
Pandas的GroupBy机制
首行数据如何快速转变量名?
文件太多乱乱的?合并一下吧!

关于我们



微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。

此外,欢迎大家踊跃投稿,介绍一些关于stata和python的数据处理和分析技巧。
投稿邮箱:statatraining@163.com
投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存