Xgboost 算法原理详解及python 实现
Xgboost 算法(回归树)
1、算法原理
步骤(booststrap sampling):
⽬标函数:Taylor展开:加法训练优化步骤:
⽬标函数进⼀步可表⽰为:
其中表⽰前t-1棵树的复杂度 其中是第t课树,是唯⼀⼀个需要学习的变量,其余都为已知量。是第t棵树的复杂度。前棵树的复杂度
其中和定义如下:1、定义树的复杂度 其中为叶⼦节点数量;为⼀个叶⼦带来的复杂度;为叶⼦节点的范数;为叶⼦节点数量
2、定义⼀棵树: 其中为⼀维向量,代表树各个叶⼦节点权重;代表⼀棵树的结构
obj =(t )L (y ,+∑i =1n i y i (t −1)f )+t x i Ωf (t )+C
f (x +Δx )≈f (x )+f (x )Δx +′f (x )(Δx )21′′2group by的用法及原理详解
⎩⎪⎪⎪⎨⎪⎪⎪⎧=0y i (0)
=f (x )=+f (x )y i (1)
1i y i (0)1i ......=f (x )=+f (x )y i (t )∑k =1t k i y i (t −1)t i obj =(t )l (y ,)+∑i =1n i y i (t )Ωf (t )
∑i =1t Ωf (t )=∑i =1t Ωf (t )+Ωf (t −∑i =1t −11)=Ωf (t )+constatnt Ωf (t −∑i =1t −11)/constant obj =(t )
l (y ,+∑i =1n i y i (t −1)f (x ))+(t )i Ωf (t )+constant =y i (t )+y i (t −1)f (x )(t )i f (x )(t )i Ωf (t )constant t −1obj =(t )[l (y ,)+∑i =1n i y i
(t −1)g f (x )+i t i h f (x )]+21i t 2
i Ωf (t )+constant g i h i {
g =∂l (y ,)
i y (t −1)i y (t −1)h =∂l (y ,)i 2y (t −1)i y (t −1)Ωf (t )=γT +
λw 21∑j =1T j 2T λw j 2L 2j f (x )=t W (w ∈q (x )R ,q :T R →d {1、2.....T })w q q
将所有训练样本,按叶⼦节点进⾏了分组。其中j x_i$,划⼊到⼀个叶⼦节点样本集中
:叶⼦节点所包含样本⼀阶偏导数累加之和(常量);:叶⼦节点所包含样本⼆阶偏导数累加之和(常量)
求解:
分裂指标(分割点在Gain最⼤且⼤于0):
Gain>0则obj下降了;Gain<0分裂失败
2、对数据的要求(⽆需规范化)
不需要归⼀化,能⾃动处理缺失值
3、算法的优缺点⼀、优点:许多策略防⽌过拟合(正则化、Shrinkage、样本抽样与列抽样)⽬标函数利⽤了⼆阶导数(1、增加精度;2、能够⾃定义损失函数。⼆阶泰勒展开可以近似⼤量损失函数)⽀持并⾏化⽀持设置样本权重,该权重体现在⼀阶导数g和⼆阶导数h通过调整权重可以去关注⼀些样本添加了对稀疏数据处理(缺失值处理)
精度⾼
obj (t )=[g f (x )+h f (x )]+Ωf (t )
i =1∑i t i 21i t 2i =[g w +h w ]+γT +λw i =1∑n
i q (x )i 21i q (x )i 221j =1∑T
j
2=[(g )w +(h +λ)w ]+γT j =1∑T i ∈I j ∑i j 21i ∈I j ∑i j 2∑j =1T I =j {i ∣q (x )=i j }将属于第个叶⼦节点所有样本obj =(t )[G w +∑j =1T j j (H +21j λ)w ]+j 2
γT G =j g ∑i ∈I j i j H =j h ∑i ∈I j i j {
w =−(每个叶⼦节点权重score )j ∗H +λj G j
obj =−+γT (第t 棵树带来的最⼩损失)21∑j =1T H +λj G j 2Gain =obj −(obj +obj )L +R L R =[−+γ]−[−++2λ]
21H +H +λL R (G +G )L R 221H +λL (G )
L 2H +λR (G )R 2
虽然利⽤了预排序和近似算法能降低寻最佳分割点的计算量,但在节点分裂过程中仍需要遍历数据集
预排序消耗两倍内存
4、XGB、GBDT、LR与RF
XGB与GBDT的不同之处
1、XGB在⽬标函数中加了正则化项(相当于预剪枝,不易过拟合)
2、XGB不仅⽤了⼀阶导数⽽且还使⽤了⼆阶导数
3、⽀持并⾏化
4、XGB的基分类器除了CART还可以是线性分类器
5、缺失值处理,⾃动学习出他的默认分裂⽅向
6、⽀持列抽样
XGB为什么使⽤泰勒⼆阶展开
1、精准性:更为精准的逼近真实的损失函数
2、可扩展性:损失函数⽀持⾃定义,只需要新的损失函数⼆阶可导
XGB为什么可以并⾏训练
特征维度并⾏:在训练之前,每个特征按特征值进⾏预排序,并存储Block结构,在后⾯查分割点重复使⽤(并⾏查)
XGB为什么快
1、分块并⾏:训练前每个特征值排序并存储Block结构,后⾯查分割点重复使⽤,⽀持并⾏查每个特征分割点
2、候选分割点:每个特征采⽤常数个分位点作为候选分割点
3、CPU cache命中优化:使⽤缓存预取的⽅法,对每个线性分配⼀个连续buffer,读取每个Block中样本的梯度信息并存⼊连续buffer中
4、Block处理优化:Block预先放⼊内存,Block按列进⾏解压缩,将Block划分到不同硬盘来提⾼吞吐
XGB防⽌过拟合的⽅法
L2
1、⽬标函数添加了正则项(叶⼦节点数+叶⼦节点权重正则化)
2、列抽样(训练的时候只⽤⼀部分特征)
3、⼦采样(每轮计算可以不使⽤全部样本)
4、Shrinkage(学习率|步长,为了给后⾯训练流出更多的学习空间)
XGB如何处理缺失值
1、在特征上寻分割点时不考虑缺失值,只考虑non—missing值
2、训练时缺失值⾃定义划分⽅向放到右⼦结点
3、预测时分别划分到左叶⼦节点与右叶⼦节点各计算⼀遍,选择分裂后增益最⼤的⽅向
XGB⼀棵树停⽌⽣长的条件
1、Gain<0停⽌分裂
2、达到树的最⼤深度
3、最⼩样本权重和(引⼊⼀次分裂后,重新计算⽣成左右2个叶⼦结点的样本权重和,如果任意⼀个叶⼦节点的样本权重低于某⼀个阈值,放弃本次分裂)
4、最⼩样本数量(叶⼦)
XGB如何处理不平衡数据
1、采⽤AUC评估模型性能,可以通过scale_pos_weight来平衡正、负样本权重(关注AUC)
2、通过上采样与下采样
3、如果在意正确率,不能平衡数据(破坏真实分布),应该设置max_delta_step为⼀个有限数字帮助收敛(基模型为LR时有效)
GBDT与LR
1、LR可解释性强,可并⾏化,需要⼤量特征⼯程
2、GBDT⾮线性,特征表达能⼒强,⽆法并⾏,易过拟合
3、⾼维稀疏场景下,LR⽐GBDT好
1、正则化
2、Gain的阈值
3、最⼩样本权重和
4、最⼤深度
XGB如何评价特征重要性
1、weight:该特征在所有树中被⽤作分割样本特征的总次数
2、gain:该特征在其出现过的所有树中产⽣平均增益
3、cover:在其出现过的所有树中平均覆盖范围(⼀个特征作为分割点,影响的样本数量。即有多少个样本经过该特征分割到2个⼦节点)
XGB过拟合如何解决
1、控制模型复杂度(max_depth、min_child_weight等参数)
2、增加随机性(subsample和colsample_bytree)
3、减少学习率,同时增加迭代次数(estimator)
RF与GBDT的区别
1、集成学习:RF属于baggig,GBDT属于boosting
2、偏差-⽅差:RF降低⽅差,GBDT降低偏差
3、训练样本:RF抽样,GBDT全部样本
4、并⾏:RF可并⾏,GBDT不可并⾏
5、泛化能⼒:RF不易过拟合,GBDT易过拟合
6、异常值:RF对异常值不敏感,GBDT对异常值敏感
5、python代码实现
导⼊相关包
import numpy as np
import pandas as pd
from sklearn.preprocessing import LabelEncoder#分类变量编码包
ics import roc_auc_score,roc_curve,auc,precision_score,f1_score,accuracy_score,classification_report,recall_score
del_selection import train_test_split
from xgboost.sklearn import XGBClassifier
import matplotlib.pylab as plt
import xgboost as xgb
import os
os.chdir('E:/wyz/Desktop/XGB/')
读取数据并预处理
data = pd.read_excel('ceshi.xlsx',sheet_name ='Sheet2')
#分类变量编码
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
str_variable =list(data.dtypes[data.dtypes.values ==object].index)
for col in str_variable:
data[col]= le.fit_transform(data[col].astype(str))
#划分数据集
y = data_model['target']
x = data_model.drop('target', axis=1)
x_train, x_test, y_train, y_test = train_test_split(x, y,random_state=0,train_size=0.7)
训练
#通过交叉验证的⽅法来获取最优的迭代次数(树的数量)
def modelfit1(alg,train_x,train_y,test_x,test_y,useTrainCV=True,cv_folds=5,early_stopping_rounds=20):
if useTrainCV:
xgb_param = _xgb_params()#获取xgb参数
xgtrain = xgb.DMatrix(train_x.values,label=train_y.values)#传⼊x和y
cvresult = xgb.cv(xgb_param,
xgtrain,#训练数据
num_boost__params()['n_estimators'],#树的数量
nfold=cv_folds,#交叉验证
metrics='auc',#评价指标
early_stopping_rounds=early_stopping_rounds,#连续迭代多少次auc不在下降
# verbose_eval=10,#每隔1轮打印⼀次评价指标
show_stdv=False)#不打印标准差
alg.set_params(n_estimators=cvresult.shape[0])#得到最优的树的数量
#训练集上的拟合
alg.fit(train_x,train_y,eval_metric='auc')#传⼊x和y
#训练集上的预测
train_class = alg.predict(train_x)#输出0和1
train_prob = alg.predict_proba(train_x)[:,1]#输出1的概率
#测试集上的预测
test_class = alg.predict(test_x)#输出0和1
test_prob = alg.predict_proba(test_x)[:,1]#输出1的概率
#准确率与auc
print('训练集准确率: %.4f'%accuracy_score(train_y,train_class))##准确率,预测为类别(normalize=False返回预测正确的个数) print('测试集准确率: %.4f'%accuracy_score(test_y,test_class))#准确率,预测为类别(normalize=False返回预测正确的个数) print('训练集AUC: %.4f'%roc_auc_score(train_y,train_prob))#AUC,预测为概率
print('测试集AUC: %.4f'%roc_auc_score(test_y,test_prob))#AUC,预测为概率
#print(alg.feature_importances_)#变量重要性
return alg
贝叶斯初步优化
#预测结果
del_selection import cross_val_score
from bayes_opt import BayesianOptimization
#定义贝叶斯优化的f
def model_target(learning_rate,n_estimators,max_depth,min_child_weight,subsample,colsample_bytree,reg_alpha,gamma): val = cross_val_score(
XGBClassifier(
learning_rate =learning_rate,#学习率
n_estimators=int(n_estimators),#最多的树的数量
max_depth=int(max_depth),#每棵树的最⼤深度
min_child_weight=min_child_weight,#叶⼦节点最⼩的样本权重和
subsample=subsample,#⾏抽样
colsample_bytree=colsample_bytree,#列抽样
objective='binary:logistic',
reg_alpha=reg_alpha,#正则化
gamma=gamma,#当损失函数减少时才会分裂
scale_pos_weight=1,#数值⼤于0,在样本的类⾮常不均衡时使⽤有助于快速收敛
seed=27),x_train,y_train,scoring='roc_auc',cv=5).mean()
return val
model_bo = BayesianOptimization(
model_target,
{'learning_rate':(0.01,0.01),
'n_estimators':(100,1000),
'max_depth':(2,4),
'min_child_weight':(0,1),
'subsample':(0.6,1),
'colsample_bytree':(0.6,1),
'reg_alpha':(0.001,10),
'gamma':(0.0,0.0)})
model_bo.maximize()
贝叶斯进阶优化
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论