在XGBoost算法原理小结中,我们讨论了XGBoost的算法原理,这一片我们讨论如何使用XGBoost的Python类库,以及一些重要参数的意义和调参思路。

    本文主要参考了XGBoost的Python文档 和 XGBoost的参数文档

1. XGBoost类库概述

    XGBoost除了支持Python外,也支持R,Java等语言。本文关注于Python的XGBoost类库,安装使用"pip install xgboost"即可,目前使用的是XGBoost的0.90版本。XGBoost类库除了支持决策树作为弱学习器外,还支持线性分类器,以及带DropOut的决策树DART,不过通常情况下,我们使用默认的决策树弱学习器即可,本文也只会讨论使用默认决策树弱学习器的XGBoost。

    XGBoost有2种Python接口风格。一种是XGBoost自带的原生Python API接口,另一种是sklearn风格的API接口,两者的实现是基本一样的,仅仅有细微的API使用的不同,主要体现在参数命名上,以及数据集的初始化上面。

2. XGBoost类库的基本使用方式

    完整示例参见我的Github代码

2.1 使用原生Python API接口

    XGBoost的类库的2种接口风格,我们先来看看原生Python API接口如何使用。

    原生XGBoost需要先把数据集按输入特征部分,输出部分分开,然后放到一个DMatrix数据结构里面,这个DMatrix我们不需要关心里面的细节,使用我们的训练集X和y初始化即可。

import pandas as pd
import numpy as np
import xgboost as xgb
import matplotlib.pylab as plt
%matplotlib inline from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split
from sklearn.datasets.samples_generator import make_classification
# X为样本特征,y为样本类别输出, 共10000个样本,每个样本20个特征,输出有2个类别,没有冗余特征,每个类别一个簇
X, y = make_classification(n_samples=10000, n_features=20, n_redundant=0,
n_clusters_per_class=1, n_classes=2, flip_y=0.1)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)
dtrain = xgb.DMatrix(X_train,y_train)
dtest = xgb.DMatrix(X_test,y_test)

    上面的代码中,我们随机初始化了一个二分类的数据集,然后分成了训练集和验证集。使用训练集和验证集分别初始化了一个DMatrix,有了DMatrix,就可以做训练和预测了。简单的示例代码如下:

param = {'max_depth':5, 'eta':0.5, 'verbosity':1, 'objective':'binary:logistic'}
raw_model = xgb.train(param, dtrain, num_boost_round=20)
from sklearn.metrics import accuracy_score
pred_train_raw = raw_model.predict(dtrain)
for i in range(len(pred_train_raw)):
if pred_train_raw[i] > 0.5:
pred_train_raw[i]=1
else:
pred_train_raw[i]=0
print (accuracy_score(dtrain.get_label(), pred_train_raw))

    训练集的准确率我这里输出是0.9664。再看看验证集的表现:

pred_test_raw = raw_model.predict(dtest)
for i in range(len(pred_test_raw)):
if pred_test_raw[i] > 0.5:
pred_test_raw[i]=1
else:
pred_test_raw[i]=0
print (accuracy_score(dtest.get_label(), pred_test_raw))

    验证集的准确率我这里的输出是0.9408,已经很高了。

    不过对于我这样用惯sklearn风格API的,还是不太喜欢原生Python API接口,既然有sklearn的wrapper,那么就尽量使用sklearn风格的接口吧。

2.2 使用sklearn风格接口,使用原生参数

    对于sklearn风格的接口,主要有2个类可以使用,一个是分类用的XGBClassifier,另一个是回归用的XGBRegressor。在使用这2个类的使用,对于算法的参数输入也有2种方式,第一种就是仍然使用和原始API一样的参数命名集合,另一种是使用sklearn风格的参数命名。我们这里先看看如何使用和原始API一样的参数命名集合。

    其实就是使用XGBClassifier/XGBRegressor的**kwargs参数,把上面原生参数的params集合放进去,代码如下:

sklearn_model_raw = xgb.XGBClassifier(**param)
sklearn_model_raw.fit(X_train, y_train, early_stopping_rounds=10, eval_metric="error",
eval_set=[(X_test, y_test)])

    里面的param其实就是2.1节里面定义的:

param = {'max_depth':5, 'eta':0.5, 'verbosity':1, 'objective':'binary:logistic'}

    使用sklearn风格的接口,却使用原始的参数名定义,感觉还是有点怪,所以我一般还是习惯使用另一种风格接口,sklearn风格的参数命名。

2.3 使用sklearn风格接口,使用sklearn风格参数

    使用sklearn风格的接口,并使用sklearn风格的参数,是我推荐的方式,主要是这样做和GBDT之类的sklearn库使用起来没有什么两样了,也可以使用sklearn的网格搜索。

    不过这样做的话,参数定义命名和2.1与2.2节就有些不同了。具体的参数意义我们后面讲,我们看看分类的算法初始化,训练与调用的简单过程:

sklearn_model_new = xgb.XGBClassifier(max_depth=5,learning_rate= 0.5, verbosity=1, objective='binary:logistic',random_state=1)

    可以看到,参数定义直接放在了XGBClassifier的类参数里,和sklearn类似。大家可以看到之前两节我们定义的步长eta,这里变成了另一个名字learning_rate。

    在初始化后,训练和预测的方法就和2.2节没有区别了。

sklearn_model_new.fit(X_train, y_train, early_stopping_rounds=10, eval_metric="error",
eval_set=[(X_test, y_test)])

3. XGBoost类库参数

    在第二节我们已经尝试使用XGBoost类库了,但是对于XGBoost的类库参数并没有过多讨论。这里我们就详细讨论下,主要以2.3节的sklearn风格参数为主来进行讨论。这些参数我会和之前讲的scikit-learn 梯度提升树(GBDT)调参小结中的参数定义对应,这样如果大家对GBDT的调参很熟悉了,那么XGBoost的调参也就掌握90%了。

    XGBoost的类库参数主要包括boosting框架参数,弱学习器参数以及其他参数。

3.1  XGBoost框架参数 

    对于XGBoost的框架参数,最重要的是3个参数: booster,n_estimators和objectve。

    1) booster决定了XGBoost使用的弱学习器类型,可以是默认的gbtree, 也就是CART决策树,还可以是线性弱学习器gblinear以及DART。一般来说,我们使用gbtree就可以了,不需要调参。

    2) n_estimators则是非常重要的要调的参数,它关系到我们XGBoost模型的复杂度,因为它代表了我们决策树弱学习器的个数。这个参数对应sklearn GBDT的n_estimators。n_estimators太小,容易欠拟合,n_estimators太大,模型会过于复杂,一般需要调参选择一个适中的数值。

    3) objective代表了我们要解决的问题是分类还是回归,或其他问题,以及对应的损失函数。具体可以取的值很多,一般我们只关心在分类和回归的时候使用的参数。

    在回归问题objective一般使用reg:squarederror ,即MSE均方误差。二分类问题一般使用binary:logistic, 多分类问题一般使用multi:softmax。

3.2  XGBoost 弱学习器参数

    这里我们只讨论使用gbtree默认弱学习器的参数。  要调参的参数主要是决策树的相关参数如下:

    1)   max_depth: 控制树结构的深度,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,需要限制这个最大深度,具体的取值一般要网格搜索调参。这个参数对应sklearn GBDT的max_depth。

    2) min_child_weight: 最小的子节点权重阈值,如果某个树节点的权重小于这个阈值,则不会再分裂子树,即这个树节点就是叶子节点。这里树节点的权重使用的是该节点所有样本的二阶导数的和,即XGBoost原理篇里面的$H_{tj}$:$$H_{tj} =  \sum\limits_{x_i \in R_{tj}}h_{ti}$$

    这个值需要网格搜索寻找最优值,在sklearn GBDT里面,没有完全对应的参数,不过min_samples_split从另一个角度起到了阈值限制。

    3) gamma: XGBoost的决策树分裂所带来的损失减小阈值。也就是我们在尝试树结构分裂时,会尝试最大数下式:$$ \max \frac{1}{2}\frac{G_L^2}{H_L + \lambda} + \frac{1}{2}\frac{G_R^2}{H_R+\lambda}  - \frac{1}{2}\frac{(G_L+G_R)^2}{H_L+H_R+ \lambda} - \gamma$$

    这个最大化后的值需要大于我们的gamma,才能继续分裂子树。这个值也需要网格搜索寻找最优值。

    4) subsample: 子采样参数,这个也是不放回抽样,和sklearn GBDT的subsample作用一样。选择小于1的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,因此取值不能太低。初期可以取值1,如果发现过拟合后可以网格搜索调参找一个相对小一些的值。

    5) colsample_bytree/colsample_bylevel/colsample_bynode: 这三个参数都是用于特征采样的,默认都是不做采样,即使用所有的特征建立决策树。colsample_bytree控制整棵树的特征采样比例,colsample_bylevel控制某一层的特征采样比例,而colsample_bynode控制某一个树节点的特征采样比例。比如我们一共64个特征,则假设colsample_bytree,colsample_bylevel和colsample_bynode都是0.5,则某一个树节点分裂时会随机采样8个特征来尝试分裂子树。

    6) reg_alpha/reg_lambda: 这2个是XGBoost的正则化参数。reg_alpha是L1正则化系数,reg_lambda是L2正则化系数,在原理篇里我们讨论了XGBoost的正则化损失项部分:$$\Omega(h_t) = \gamma J + \frac{\lambda}{2}\sum\limits_{j=1}^Jw_{tj}^2$$

    上面这些参数都是需要调参的,不过一般先调max_depth,min_child_weight和gamma。如果发现有过拟合的情况下,再尝试调后面几个参数。

3.3  XGBoost 其他参数

    XGBoost还有一些其他的参数需要注意,主要是learning_rate。

    learning_rate控制每个弱学习器的权重缩减系数,和sklearn GBDT的learning_rate类似,较小的learning_rate意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。所以这两个参数n_estimators和learning_rate要一起调参才有效果。当然也可以先固定一个learning_rate ,然后调完n_estimators,再调完其他所有参数后,最后再来调learning_rate和n_estimators。

    此外,n_jobs控制算法的并发线程数, scale_pos_weight用于类别不平衡的时候,负例和正例的比例。类似于sklearn中的class_weight。importance_type则可以查询各个特征的重要性程度。可以选择“gain”, “weight”, “cover”, “total_gain” 或者 “total_cover”。最后可以通过调用booster的get_score方法获取对应的特征权重。“weight”通过特征被选中作为分裂特征的计数来计算重要性,“gain”和“total_gain”则通过分别计算特征被选中做分裂特征时带来的平均增益和总增益来计算重要性。“cover”和 “total_cover”通过计算特征被选中做分裂时的平均样本覆盖度和总体样本覆盖度来来计算重要性。

4. XGBoost网格搜索调参

    XGBoost可以和sklearn的网格搜索类GridSeachCV结合使用来调参,使用时和普通sklearn分类回归算法没有区别。具体的流程的一个示例如下:

gsCv = GridSearchCV(sklearn_model_new,
{'max_depth': [4,5,6],
'n_estimators': [5,10,20]})
gsCv.fit(X_train,y_train)
print(gsCv.best_score_)
print(gsCv.best_params_)

    我这里的输出是:

    0.9533333333333334

    {'max_depth': 4, 'n_estimators': 10}

    接着尝试在上面搜索的基础上调learning_rate :

sklearn_model_new2 = xgb.XGBClassifier(max_depth=4,n_estimators=10,verbosity=1, objective='binary:logistic',random_state=1)
gsCv2 = GridSearchCV(sklearn_model_new2,
{'learning_rate ': [0.3,0.5,0.7]})
gsCv2.fit(X_train,y_train)
print(gsCv2.best_score_)
print(gsCv2.best_params_)

    我这里的输出是:

    0.9516

    {'learning_rate ': 0.3}

    当然实际情况这里需要继续调参,这里假设我们已经调参完毕,我们尝试用验证集看看效果:

sklearn_model_new2 = xgb.XGBClassifier(max_depth=4,learning_rate= 0.3, verbosity=1, objective='binary:logistic',n_estimators=10)
sklearn_model_new2.fit(X_train, y_train, early_stopping_rounds=10, eval_metric="error",
eval_set=[(X_test, y_test)])

    最后的输出是:

    [9]	validation_0-error:0.0588

    也就是验证集的准确率是94.12%。

    我们可以通过验证集的准确率来判断我们前面网格搜索调参是否起到了效果。实际处理的时候需要反复搜索参数并验证。

    以上就是XGBoost的类库使用总结了,希望可以帮到要用XGBoost解决实际问题的朋友们。

(欢迎转载,转载请注明出处。欢迎沟通交流: liujianping-ok@163.com)  

XGBoost类库使用小结的更多相关文章

  1. scikit-learn Adaboost类库使用小结

    在集成学习之Adaboost算法原理小结中,我们对Adaboost的算法原理做了一个总结.这里我们就从实用的角度对scikit-learn中Adaboost类库的使用做一个小结,重点对调参的注意事项做 ...

  2. scikit-learn K近邻法类库使用小结

    在K近邻法(KNN)原理小结这篇文章,我们讨论了KNN的原理和优缺点,这里我们就从实践出发,对scikit-learn 中KNN相关的类库使用做一个小结.主要关注于类库调参时的一个经验总结. 1. s ...

  3. scikit-learn 朴素贝叶斯类库使用小结

    之前在朴素贝叶斯算法原理小结这篇文章中,对朴素贝叶斯分类算法的原理做了一个总结.这里我们就从实战的角度来看朴素贝叶斯类库.重点讲述scikit-learn 朴素贝叶斯类库的使用要点和参数选择. 1. ...

  4. scikit-learn 逻辑回归类库使用小结

    之前在逻辑回归原理小结这篇文章中,对逻辑回归的原理做了小结.这里接着对scikit-learn中逻辑回归类库的我的使用经验做一个总结.重点讲述调参中要注意的事项. 1. 概述 在scikit-lear ...

  5. XGBoost算法原理小结

    在两年半之前作过梯度提升树(GBDT)原理小结,但是对GBDT的算法库XGBoost没有单独拿出来分析.虽然XGBoost是GBDT的一种高效实现,但是里面也加入了很多独有的思路和方法,值得单独讲一讲 ...

  6. scikit-learn决策树算法类库使用小结

    之前对决策树的算法原理做了总结,包括决策树算法原理(上)和决策树算法原理(下).今天就从实践的角度来介绍决策树算法,主要是讲解使用scikit-learn来跑决策树算法,结果的可视化以及一些参数调参的 ...

  7. Lua5.1 升级 Lua5.3 升级 小结

    Lua的版本差异确实是比较让人头疼的事情,之前在移动端一直采用Android下使用LuaJit,Ios下使用Lua5.1.这次升级到Xlua(lua5.3版本)主要有两方面的原因:一是ulua后续维护 ...

  8. 集成学习值Adaboost算法原理和代码小结(转载)

    在集成学习原理小结中,我们讲到了集成学习按照个体学习器之间是否存在依赖关系可以分为两类: 第一个是个体学习器之间存在强依赖关系: 另一类是个体学习器之间不存在强依赖关系. 前者的代表算法就是提升(bo ...

  9. web安全之机器学习入门——3.1 KNN/k近邻

    目录 sklearn.neighbors.NearestNeighbors 参数/方法 基础用法 用于监督学习 检测异常操作(一) 检测异常操作(二) 检测rootkit 检测webshell skl ...

随机推荐

  1. 解决eclipse中找不到jar包问题

    当使用eclipse导入外部的web工程时,有时会提示HttpServletRequest, ServletActionContext找不到的情况,解决办法: (注:我已经引用了struts2的jar ...

  2. OpenGL(二十四) VAO、VBO和着色器使用示例

    1. 新建一个工程,新建一个头文件Shader.h,内容如下: #ifndef _SHADER_H_ #define _SHADER_H_ #include <vector> #inclu ...

  3. A Byte of Python (for Python 3.0) 下载

    在线阅读:http://www.swaroopch.org/notes/Python_en:Table_of_Contents 英文版 下载地址1:http://files.swaroopch.com ...

  4. Scatter matrix(散布矩阵)

    n 个 m 维的样本,Xm×n=[x1,x2,-,xn],样本均值定义为: x¯=1n∑i=1nxi 散列矩阵定义为如下的半正定矩阵: S=∑j=1n(xj−x¯)(xj−x¯)T=∑j=1n(xj− ...

  5. C# TSF 输入法的获取

    原文 C# TSF 输入法的获取 起因: 「添雨跟打器」中存在一个问题.在 windows 8/10 里面,输入法就获取不到了.我一直没有去管这样的问题.但是也大致知道,可能是 TSF 架构的问题. ...

  6. 第四十天 阿乐在其中—Android小游戏的飞机(四)加入敌人

    8月9日,晴. "江城如画里,山晓望晴空. 雨水夹明镜.双桥落彩虹. 人烟寒橘柚,秋色老梧桐." 上篇已经让飞机载入子弹和音效及背景音乐,本篇主要加入敌机. 本篇要用到的几个函数解 ...

  7. debian 下py2.7 安装mysql模块

    先安装pip 然后用pip安装 setuptools 安装模块的时候会报错 python setup.py install sh: mysql_config: command not found Tr ...

  8. 反编译 war 包成传统项目的方法

    需求 项目老大让外包做了官网,不甚满意,想自己搞搞,遂叫我反编译他们发过来的 war 包. 方法 第一步:解压 war 包其实就是 zip 压缩包,用 zip 解压. 第二步:反编译 查看 war 包 ...

  9. Web应用程序和网站的区别

    1项目就是一个应用程序.在VS中查看的时候,项目中建立的一般处理程序,有两个文件,网站只有一个.写个代码测试,发现在代码层次上没有2再有就是项目中的一般处理程序有命名空间,而网站中的没有.WEB网站每 ...

  10. facebook javascript api 使用

    官方api文档:http://developers.facebook.com/docs 先简单的介绍下创建一个app(https://developers.facebook.com/apps),