集成学习介绍之二——Boosting算法
本文作者:王 歌
文字编辑:戴 雯
技术总编:张 邯
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
算法中有几个算法是经常用到的,这也是我们今天要讲解的重点—— AdaBoost
、 GBDT
和 XGBoost
。这三种算法都是源于 Boosting
算法的基本思想,下面我们主要介绍这三种算法在 Boosting
的基础上有哪些差别。对于 AdaBoost(Adaptive Boosting) 算法,首先从每一轮权值改变的方式设置上,该算法在初始化时,将所有弱学习器的权重都设置为1/N,在后续的迭代中,那些在上一轮迭代中被预测错的样本的权重将增加,最后对得到的所有学习器进行加权组合。为了防止过拟合,还可以在迭代中加入正则化项。AdaBoost不像我们下面介绍的两种方法,它可以自己定义使用的基学习器,在这一点上要更有优势。
2类参数介绍
在sklearn中AdaBoost算法有两个类,即 AdaBoostClassifier
和 AdaBoostRegressor
,前者用于分类,后者用于回归。我们这里主要介绍 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
from xgboost.sklearn import XGBClassifier
一般我们更推荐使用sklearn的接口,我们这里也是以sklearn接口为基础来介绍和演示。除了 base_score
、 learning_rate
、 max_depth
、 n_estimators
、 n_jobs
、 random_state
、 subsample
和前面介绍的类相同的参数外,还有以下参数:
(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_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))
from matplotlib import pyplot as plt
from xgboost import plot_importance
plot_importance(xgbclf)
plt.show()
结果如下图:
由上图可以看到,第四个属性petal width(花瓣宽度)的重要性最高。相比而言,AdaBoost可以使用各种模型来构建弱学习器,并且不容易发生过拟合,但对异常数据较敏感,容易受到噪声的干扰;GBDT算法则对异常点是鲁棒的,可以处理混合类型的特征,比较适合低维数据,能够处理非线性数据;而XGBoost算法由于是对GBDT的改进,因此它的运算速度和算法都会优于GBDT,不容易发生过拟合,计算量较小。目前在结构化数据上,XGBoost算法的表现会更好,因此也受到各种比赛的欢迎。大家快去试试吧!
PDF文本信息提取(二)
取长补短、互通有无 ——集成学习介绍之Bagging &随机森林
关于我们
微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。