xgboost原理推导和python实现

        本文经过学习陈天奇博士的slides和一些官方文档梳理了xgboost原理和推导过程,仅仅是初步梳理,还有不少问题须要进一步研究,总体感受Xgboost很强大,集合了CART、boosting、bagging的优势,包括树的剪枝、行采样、列采用、正则化项等html

二.Xgboost基本原理

英文:http://xgboost.readthedocs.io/en/latestnode

中文:http://xgboost.apachecn.org/cn/latestpython

2.1目标函数构成

目标函数通常由两部分组成:训练损失和正则化项算法

1.training loss:度量模型对训练数据集的拟合程度,常见有平方偏差和逻辑损失apache

2.正则化项:度量模型的复杂程度,常见有L2和L1范式,缓存

 

2.2  常见算法结构

岭回归:线性回归、平方偏差、L2范式多线程

Lasso回归:线性回归、平方偏差、L1范式并发

逻辑回归:线性模型、逻辑损失、L2范式app

2.3 回归树

2.3.1 单棵回归树dom

结构以下,每一个节点均有一个预测值

2.3.2 集成回归树

每一个节点预测值是多棵树和,常见的有Adaboost、GBDT等

2.3.3 集成回归树模型

集成回归树是多棵树的线性加权和:模型的损失为全部节点的预测偏差,模型的复杂度有树的个数决定

2.3.4 模型采用加法训练

经过上面的目标函数,模型从常数开始,每次添加一个函数

2.3.5 确认目标函数任务

在t时刻的预测=t-1时刻的预测+t时刻的函数,所以能够肯定目标函数以下图,咱们的任务是找到ft去最小化目标函数

2.4 利用泰勒定理求损失函数的近似值

经过泰勒定理求目标函数的近似值,以下图所示

新目标函数变成以下函数:参与计算的有一阶导数和二阶导数(GBDT仅用一阶导数)

2.5 从新定义树

用叶子得分定义树,每一个样本都落在一个叶子节点上,q(x)表示样本x在某个叶子节点上,wq(x)是该节点的得分

2.6 定义树的复杂度

定义树的复杂度以下:T树的深度,wj2为叶子节点得分

2.7  更新目标函数

用每个叶子节点得分从新组合目标,T独立的二次函数的和

2.8 得分计算

2.9 单棵树的查找算法

1.枚举可能的树结构,2.计算结构得分,3.找到最优结构,用最优节点权重,but可能有无限个树结构

2.10  树贪婪学习

树的深度从0开始,树的每个叶子节点尝试去切分,(切分后目标函数发生改变才会切分)

信息增益(损失函数)=左右子树得分-未切分父节点得分-复杂度

利用年龄<a分红左右两部分

上图中G都是各自区域内的gi总和,根据Gain(max)选择最优分割点。在排序实例上的左到右线性扫描足以决定沿着特征的最佳分割

根据特征划分有无数可能的树结构,所以采用近似算法(特征分位点,候选分割点) 

这里写图片描述

利用one-hot方法能够把类别变量转化为数值变量

2.11  剪枝和正则化

若是最优分割有负增益则中止分割,将一棵树生长到最大深度,以负增益递归地修剪全部的叶子分裂,

3 summary

1.每次迭代增长一个新树,(每次遍历全部可能的切分点,以偏差最小的点开始切分,依次遍历(贪心算法))

2.每次迭代计算一阶和二阶导数(二次函数最优化问题)

 3.经过缩减因子和正则化项减小过拟合

4.Xgboost和GBDT区别

  参考了https://blog.csdn.net/sb19931201/article/details/52557382

1.传统GBDT以CART做为基函数,但xgboost支持线性分类器(booster:gbtree、gblinear),这个时候xgboost至关于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。 

2.传统GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数(g一阶导数,h二阶导数)

3.xgboost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、叶子节点的权重的平方。从Bias-variance tradeoff角度来说,正则项下降了模型variance,使学习出来的模型更加简单,防止过拟合,这也是xgboost优于传统GBDT的一个特性 

4.shrinkage(步长) and column subsampling —仍是为了防止过拟合
(1)shrinkage缩减相似于学习速率,在每一步tree boosting以后增长了一个参数n(权重),经过这种方式来减少每棵树的影响力,给后面的树提供空间去优化模型。(2)column subsampling列(特征)抽样,说是从随机森林那边学习来的,防止过拟合的效果比传统的行抽样还好(行抽样功能也有),而且有利于后面提到的并行化处理算法。

5.split finding algorithms(划分点查找算法):
(1)exact greedy algorithm—贪心算法获取最优切分点 (2)approximate algorithm— 近似算法,提出了候选分割点概念,先经过直方图算法得到候选分割点的分布状况,而后根据候选分割点将连续的特征信息映射到不一样的buckets中,并统计汇总信息。

6.对缺失值的处理。对于特征的值有缺失的样本,xgboost能够自动学习出它的分裂方向。

7.并行化处理 —系统设计模块,块结构设计等

        xgboost工具支持并行。boosting不是一种串行的结构吗?怎么并行的?注意xgboost的并行不是tree粒度的并行,xgboost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值)。xgboost的并行是在特征粒度上的。咱们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(由于要肯定最佳分割点),xgboost在训练以前,预先对数据进行了排序,而后保存为block结构,后面的迭代中重复地使用这个结构,大大减少计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,须要计算每一个特征的增益,最终选增益最大的那个特征去作分裂,那么各个特征的增益计算就能够开多线程进行。

 

8.此外xgboost还设计了高速缓存压缩感知算法,这是系统设计模块的效率提高。 
当梯度统计不适合于处理器高速缓存和高速缓存丢失时,会大大减慢切分点查找算法的速度。 
(1)针对 exact greedy algorithm采用缓存感知预取算法 

 

(2)针对 approximate algorithms选择合适的块大小

9.内置交叉验证:Xgboost容许在每一轮boosting迭代中使用交叉验证,能够方便得到最优boosting迭代次数,而GBM使用网格搜索,只能检测有限个值

5.参数详解

参考:https://zhuanlan.zhihu.com/p/28672955

1. booster [default=gbtree]选择每一次迭代中,模型的种类. 有两个选择:gbtree: 基于树的模型,gblinear: 线性模型

2.silent [default=0] 设为1 则不打印执行信息,设为0打印信息这个是设置并发执行的信息

3.eta [default=0.3]相似于GBDT里面的学习率经过在每一步中缩小权重来让模型更加鲁棒通常经常使用的数值: 0.01-0.2

4.min_child_weight [default=1]这个参数用来控制过拟合,若是数值太大可能会致使欠拟合

5.max_depth [default=6]设置树的最大深度,控制过拟合,若是树的深度太大会致使过拟合

6.max_leaf_node叶子节点的最大值,也是为了经过树的规模来控制过拟合,若是叶子树肯定了,对于2叉树来讲高度也就定了,此时以叶子树肯定的高度为准

7.gamma [default=0]这个值会跟具体的loss函数相关,须要调节,若是分裂可以使loss函数减少的值大于gamma,则这个节点才分裂。gamma设置了这个减少的最低阈值。若是gamma设置为0,表示只要使得loss函数减小,就分裂

8.max_delta_step使用它能够处理类别不平衡问题,若是参数设置为0,表示没有限制。若是设置为一个正值,会使得更新步更加谨慎

9.subsample [default=1]对原数据集进行随机采样来构建单个树。这个参数表明了在构建树时候 对原数据集采样的百分比,相对小点的数值能够防止过拟合,可是太小的数值会致使欠拟合(利用随机森林特征)

10.colsample_bytree [default=1]建立树的时候,从全部的列中选取的比例。e.g:若是设为0.8表示随机抽取80%的列 用来建立树(利用随机森林特征)

11.lambda [default=1]能够用来考虑下降过拟合,L2自己能够防止过度看重某个特定的特征。尽可能考虑尽可能多的特征归入模型。(二阶导数)

12.alpha [default=0]L1正则有助于产生稀疏的数据,这样有助于提高计算的速度(一阶导数)

13.eval_metric对于回归问题默认采用rmse,对于分类问题通常采用error

  • rmse – root mean square error
  • mae – mean absolute error
  • logloss – negative log-likelihood
  • error – Binary classification error rate (0.5 threshold)
  • merror – Multiclass classification error rate
  • mlogloss – Multiclass logloss
  • auc: Area under the curve

14.seed [default=0]为了产生能太重现的结果。由于若是不设置这个种子,每次产生的结果都会不一样

6 python示例

已经介绍了xgboost安装过程和基本原理,接下咱们经过实例看看xgboost强大

import pandas as pd
df=pd.read_excel('bankloan.xls')

print (df.shape)
data=df.ix[:,:8]
flag=df.ix[:,-1]

#训练集和测试集
from sklearn.cross_validation import train_test_split
train_x, test_x, train_y, test_y = train_test_split(data, flag, random_state=0)

# 模型初始化设置
import xgboost as xgb
dtrain=xgb.DMatrix(train_x,label=train_y)
dtest=xgb.DMatrix(test_x)

#booster:
params={'booster':'gbtree',
        'objective': 'binary:logistic',
        'eval_metric': 'auc',
        'max_depth':7,
        'lambda':15,
        'subsample':0.75,
        'colsample_bytree':0.75,
        'min_child_weight':1,
        'eta': 0.025,
        'seed':0,
        'nthread':8,
        'silent':1,
        'gamma':0.15,
        'learning_rate' : 0.01}

watchlist = [(dtrain,'train')]

#建模与预测:NUM_BOOST_round迭代次数和数的个数一致
bst=xgb.train(params,dtrain,num_boost_round=50,evals=watchlist)
ypred=bst.predict(dtest)

# 设置阈值, 输出一些评价指标,>0.5预测为1,其余预测为0
y_pred = (ypred >= 0.5)*1

from sklearn import metrics
print ('AUC: %.4f' % metrics.roc_auc_score(test_y,ypred))
print ('ACC: %.4f' % metrics.accuracy_score(test_y,y_pred))
print ('Recall: %.4f' % metrics.recall_score(test_y,y_pred))
print ('F1-score: %.4f' %metrics.f1_score(test_y,y_pred))
print ('Precesion: %.4f' %metrics.precision_score(test_y,y_pred))
metrics.confusion_matrix(test_y,y_pred)


from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']  
xgb.plot_importance(bst)

结果以下所示:模型的AUC为0.8277,工龄、信用卡负债、负债率三个指标对模型影响较大

至此xgboost基本梳理完成,后续还有不少须要深刻研究,再优化本篇内容,