机器学习:xgboost原生库接口(陈天奇) && xgboost的sklearn接口

2,283 阅读11分钟

0/参数网址

blog.csdn.net/momokofly/a… blog.csdn.net/Amanda_pyth… blog.csdn.net/qq_36535820…

xgboost包含原生接口和 sklearn 风格接口两种,并且二者都实现了分类和回归的功能。
回归:label是个连续值
分类:label是离散值,二分类和多分类

1/xgboost原生库接口

陈天奇创造了XGBoost算法后,很快就和一群机器学习爱好者建立了专门的XGBoost库,名为xgboost
xgboost是一个独立的、开源的,并且专门提供梯度提升树以及XGBoost算法应用的算法库。
它和sklearn类似,有一个详细的官方网站可以提供学习资料,并且可以与C、Python、R、Julia等语言连用,但需要单独安装和下载。
安装或者更新xgboost原生库:
    pip install xgboost             # 安装xgboost库
    pip install --upgrade xgboost   # 更新xgboost库
使用xgboost原生库:
    import xgboost as xgb

建模流程:

图片.png

从上图可以知道,xgboost原生库训练模型用的是train()函数,预测用的是predict()函数。
xgboost原生库必须先使用字典设置好参数,再用train()函数把参数集传入,然后再进行训练。
(sklearn是把所有的参数都写在类中)

xgboost原生库之所以要提前把参数写在一个字典中,是因为xgboost算法的参数实在是太多了,
如果全部写在xgb.train()函数中,不太美观,而且容易出错。

DMatrix()类:用于封装数据,它是XGBoost自定义的一个数据矩阵类,
            目的是这种定义方式可以优化存储和运算速度。
            如果你想使用xgboost原生接口,你就必须把你的数据传入这个DMatrix()类,
            然后把数据转化成必要的形式,然后通过train()函数进行模型的训练。
    import xgboost as xgb
    from sklearn.datasets import load_boston

    boston_data = load_boston()
    X = boston_data.data
    y = boston_data.target

    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=420)
    
    # 原生接口和sklearn接口不同的一个地方是:
    # 原生接口的数据,需要通过xgb.DMatrix()函数进行转化
    dtrain = xgb.DMatrix(X_train, label=y_train)
    dtest = xgb.DMatrix(X_test, label=y_test)
    
    # params:弱评估器(booster)有关的参数
    params = {
        'eta': 0.1, # 学习率
        'max_depth':5 # 树的最大深度
    }
    
    num_round = 20 # 迭代轮数

    xgb_model = xgb.train(params=params,             # 设置模型参数
                          dtrain=dtrain,             # dtrain:训练数据集,包括特征和标签
                          num_boost_round = num_round  # 迭代轮数
                   ) 

    y_pred = xgb_model.predict(dtest)
    mean_squared_error(y_test, y_pred)
    
    # 也可以一边训练,一边测试 
    xgb_model = xgb_model.train(
                 params=params, 
                 dtrain=dtrain, 
                 num_boost_round = num_round, 
                 evals=[(dtrain, 'train'),(dtest, 'test')] # evals:验证数据集
    )  
    ```


    XGBoost原生接口必须先使用字典设定参数集,再使用train()将参数输入,进行训练;
    
    以下是xgboost.train()函数的使用方法:
    params {eta, 
            gamma, 
            max_depth, 
            min_child_weight, 
            max_delta_step, 
            subsample, 
            colsample_bytree, 
            colsample_bylevel,
            colsample_bynode, 
            lambda, 
            alpha, 
            tree_method_string, 
            sketch_eps, 
            scale_pos_weight, 
            updater, 
            refresh_leaf, 
            process_type, 
            grow_policy, 
            max_leaves, 
            max_bin, 
            predictor, 
            num_parallel_tree}
    
    xgboost.train(params, 
                  dtrain, 
                  num_boost_round = 10, 
                  evals = (), 
                  obj = None, 
                  feval = None, 
                  maximize = False, 
                  early_stopping_rounds = None, 
                  evals_result = None, 
                  verbose_eval = True, 
                  xgb_model = None, 
                  callbacks = None, 
                  learning_rates = None)
     
    
    xgboost原生接口,数据需要经过:
          输入数据标准化(xgboost.DMatrix),
          label标准化(LabelEncoder().fit_transform),
          输出结果反标签标准化(LabelEncoder().inverse_transform).
    训练调用train()预测调用predict()

2/xgboost中的sklearn中的接口

from xgboost.sklearn import XGBClassifier   # 分类
from xgboost.sklearn import XGBRegressor    # 回归

XGBRegressor(max_depth = 3, 
             learning_rate = 0.1, 
             n_estimators = 100, 
             silent = True, 
             objective = ‘reg:linear’, 
             booster = ‘gbtree’, 
             n_jobs = 1, 
             nthread = None, 
             gamma = 0, 
             min_child_weight = 1, 
             max_delta_step = 0, 
             subsample = 1,
             colsample_bytree = 1, 
             colsample_bylevel = 1, 
             reg_alpha = 0, 
             reg_lambda = 1, 
             scale_pos_weight = 1, 
             base_score = 0.5, 
             random_state = 0, 
             seed = None, 
             missing = None, 
             importance_type = ‘gain’, ∗ ∗ ** ∗∗kwargs)
  
xgboost原生库和sklearn中的接口,输入的参数有点不同,但是看起来很接近。
比如xgboost原生库中的字典params中的eta参数,其实就是XGBRegressor中的learning_rate,步长。
他们虽然名字不同,但是功能是一样的。只是sklearn的开发团队很友好的把参数名称调整成了和sklearn中其它算法类似的样子。
from xgboost.sklearn import XGBRegressor    # 回归
from sklearn.datasets import load_boston 
from sklearn.metrics import r2_score,mean_squared_error,mean_absolute_error,
                  accuracy_score,precision_score, recall_score 
from sklearn.model_selection import train_test_split 
import math 


# 数据准备
boston_data = load_boston() 
X = boston_data.data 
y = boston_data.target 

# 划分训练集,测试集合
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=420)

# 先实例化一个模型
xgb_reg = XGBRegressor(n_estimators = 20, #迭代次数 l
                       earning_rate = 0.1, #学习率 
                       max_depth=5 )

# 然后通过fit()训练模型
# sklearn接口不同对数据进行格式的转化
xgb_reg.fit(X_train, y_train) 
ypred = xgb_reg.predict(X_test) 
mean_squared_error(y_test, ypred)
math.sqrt(mean_squared_error(y_test, ypred))

# 设置eval_set参数,可以一边训练,一边测试 
reg.fit(X_train, y_train, eval_set = [(X_train, y_train), (X_test, y_test)])

3/xgboost的3大核心

集成算法本身
弱学习期
计算速度(开启的线程数)

图片.png

图片.png

图片.png

4/弱学习器的数量的作用,产生的影响论:

首先,XGB中的树的数量决定了模型的学习能力,树的数量越多,模型的学习能力越强。
只要XGB中树的数量足够了,即便只有很少的数据,模型也能够学到训练数据100%的信息,所以XGB也是天生过拟合的模型。但在这种情况下,模型会变得非常不稳定。

第二,XGB中树的数量很少的时候,对模型的影响较大,当树的数量已经很多的时候,对模型的影响比较小,只能有微弱的变化。当数据本身就处于过拟合的时候,再使用过多的树能达到的效果甚微,反而浪费计算资源。当唯一指标 R 2 R^2 R2或者准确率给出的n_estimators看起来不太可靠的时候,可以改造学习曲线来帮助选择参数。

第三,树的数量提升对模型的影响有极限,最开始,模型的表现会随着XGB的树的数量一起提升,但到达某个点之后,树的数量越多,模型的效果会逐步下降,这也说明了暴力增加n_estimators不一定有效果。

这些都和随机森林中的参数n_estimators表现出一致的状态。
在随机森林中总是先调整n_estimators,当n_estimators的极限已达到,才考虑其他参数,
但XGB中的状况明显更加复杂,当数据集不太寻常的时候会更加复杂,这是要给出的第一个超参数,因此还是建议优先调整n_estimators,一般都不会建议一个太大的数目,300以下为佳。

5/subsample参数的作用

首先参数是每棵树用来训练的数据的数占总数据的比例。
可以减少过拟合。

6/总结

xgboost原生库的运算速度和参数设定,都要比sklearn简单。
所有,总的来说,还是建议大家用xgboost原生库,import xgboost as xgb
先划分训练集和测试集
然后转化数据格式。
训练使用train(),预测使用predict()

训练集上的表现展示了模型的学习能力,测试集上的表现展示了模型的泛化能力,通常模型在测试集上的表现不太可能超过训练集,因此希望测试集的学习曲线能够努力逼近训练集的学习曲线。

7/区别

两种使用方式的区别:
建模流程略有不同:原生库的数据必须封装在DMatrix()中,再进行训练;sklearnAPI没有数据封装的过程;
原生XGBoost库的大部分参数通过params参数传递;sklearnAPI没有params这个参数,所有参数都是直接在类里面赋值,比如XGBRegressor()回归类,XGBClassifier()分类类。
原生XGBoost库的train()函数即可用来处理分类问题,也可用来处理回归问题,具体是处理什么问题,是通过params参数中的objective参数来指定的。
sklearnAPI分别封装了分类函数与回归函数,XGBRegressor()回归类,XGBClassifier()分类类。

8/如何衡量模型的好坏

# 计算准确率
# 包括正样本和负样本,所有的样本都要计算准确率
from sklearn.metrics import accuracy_score    

# 计算精确率,只考虑正样本
# 在有些场景中,我们只需要考虑正样本,负样本预测的对错没有太大的影响。
from sklearn.metrics import precision_score   

# 计算召回率
# 如果不是很在意召回,则可以不计算该指标
from sklearn.metrics import recall_score    

# 精确率和召回率的调和衡量指标
# f1score认为召回率和精确率一样重要,f0.5score认为召回率的重要程度是精确率的一半
# f2score认为召回率的重要程度是精确率的2倍。
from sklearn.metrics import f1_score          

9/二者的参数的区别

(1)重要参数

1.booster

       用于指定弱学习器的类型,默认值为 ‘gbtree’,表示使用基于树的模型进行计算。还可以选择为 ‘gblinear’ 表示使用线性模型作为弱学习器。

       推荐设置为 ‘gbtree’,本文后面的相关参数设置都以booster设置为’gbtree’为前提。

2.eta / learning_rate

       参考XGBoost算法的相关知识,不难发现XGBoost为了防止过拟合,引入了"Shrinkage"的思想,即不完全信任每个弱学习器学到的残差值。为此需要给每个弱学习器拟合的残差值都乘上取值范围在(0, 1] 的 eta,设置较小的 eta 就可以多学习几个弱学习器来弥补不足的残差。

       在XGBClassifier与XGBRegressor中,对应参数名为 learning_rate。

       推荐的候选值为:[0.01, 0.015, 0.025, 0.05, 0.1]

3.gamma

       指定叶节点进行分支所需的损失减少的最小值,默认值为0。设置的值越大,模型就越保守。

       推荐的候选值为:[0, 0.05 ~ 0.1, 0.3, 0.5, 0.7, 0.9, 1] **

4.alpha / reg_alpha

       L1正则化权重项,增加此值将使模型更加保守。

       在XGBClassifier与XGBRegressor中,对应参数名为 reg_alpha 。

       推荐的候选值为:[0, 0.01~0.1, 1]

5.lambda / reg_lambda

       L2正则化权重项,增加此值将使模型更加保守。

       在XGBClassifier与XGBRegressor中,对应参数名为 reg_lambda。

       推荐的候选值为:[0, 0.1, 0.5, 1]

6.max_depth

       指定树的最大深度,默认值为6,合理的设置可以防止过拟合。

       推荐的数值为:[3, 5, 6, 7, 9, 12, 15, 17, 25]。

7.min_child_weight

       指定孩子节点中最小的样本权重和,如果一个叶子节点的样本权重和小于min_child_weight则拆分过程结束,默认值为1。

       推荐的候选值为:[1, 3, 5, 7]

8.subsample

       默认值1,指定采样出 subsample * n_samples 个样本用于训练弱学习器。注意这里的子采样和随机森林不一样,随机森林使用的是放回抽样,而这里是不放回抽样。 取值在(0, 1)之间,设置为1表示使用所有数据训练弱学习器。如果取值小于1,则只有一部分样本会去做GBDT的决策树拟合。选择小于1的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,因此取值不能太低。

       推荐的候选值为:[0.6, 0.7, 0.8, 0.9, 1]

9.colsample_bytree

       构建弱学习器时,对特征随机采样的比例,默认值为1。

       推荐的候选值为:[0.6, 0.7, 0.8, 0.9, 1]

10.objective

       用于指定学习任务及相应的学习目标,常用的可选参数值如下:
“reg:linear”,线性回归(默认值)。
“reg:logistic”,逻辑回归。
“binary:logistic”,二分类的逻辑回归问题,输出为概率。
“multi:softmax”,采用softmax函数处理多分类问题,同时需设置参数num_class指定类别个数。

11.num_class

       用于设置多分类问题的类别个数。

12.eval_metric

       用于指定评估指标,可以传递各种评估方法组成的list。常用的评估指标如下:

       ‘rmse’,用于回归任务

       ‘mlogloss’,用于多分类任务

       ‘error’,用于二分类任务

       ‘auc’,用于二分类任务

13.silent

       数值型,表示是否输出运行过程的信息,默认值为0,表示打印信息。设置为1时,不输出任何信息。

       推荐设置为 0 。

14.seed / random_state

       指定随机数种子。

       在XGBClassifier与XGBRegressor中,对应参数名为 random_state 。

(2)训练参数

以xgboost.train为主,参数及默认值如下:
xgboost.train(params, dtrain, num_boost_round=10, evals=(),

                 obj=None, feval=None, maximize=False,                   early_stopping_rounds=None,  evals_result=None,                   verbose_eval=True, xgb_model=None, callbacks=None)

 **1.params**

       字典类型,用于指定各种参数,例如:{‘booster’:‘gbtree’,‘eta’:0.1}

2.dtrain

       用于训练的数据,通过给下面的方法传递数据和标签来构造:

       dtrain = xgb.DMatrix(data, label=label)

3.num_boost_round

       指定最大迭代次数,默认值为10

4.evals

       列表类型,用于指定训练过程中用于评估的数据及数据的名称。例如:[(dtrain,‘train’),(dval,‘val’)]

5.obj

       可以指定二阶可导的自定义目标函数。

6.feval

       自定义评估函数。

7.maximize

       是否对评估函数最大化,默认值为False。

8.early_stopping_rounds

       指定迭代多少次没有得到优化则停止训练,默认值为None,表示不提前停止训练。 如果设置了此参数,则模型会生成三个属性:

       best_score
best_iteration
best_ntree_limit

       注意:evals 必须非空才能生效,如果有多个数据集,则以最后一个数据集为准。

9.verbose_eval

       可以是bool类型,也可以是整数类型。如果设置为整数,则每间隔verbose_eval次迭代就输出一次信息。

10.xgb_model

       加载之前训练好的 xgb 模型,用于增量训练。

预测函数

       主要是下面的两个函数:

1.predict(data) :返回每个样本的预测结果

2.predict_proba(data) :返回每个样本属于每个类别的概率

       注意:data 是由 DMatrix 函数封装后的数据。

参数如何调整

xgboost 调参思路
(1)选择较高的学习率(**learning_rate**),例如0.1,这样可以减少迭代用时。
(2)然后对 max_depth , min_child_weight , gamma , subsample, colsample_bytree 这些参数进行调整。这些参数的合适候选值为:

       max_depth:[3, 5, 6, 7, 9, 12, 15, 17, 25]

       min_child_weight:[1, 3, 5, 7]

       gamma:[0, 0.05 ~ 0.1, 0.3, 0.5, 0.7, 0.9, 1]

       subsample:[0.6, 0.7, 0.8, 0.9, 1]

       colsample_bytree:[0.6, 0.7, 0.8, 0.9, 1]

3)调整正则化参数alpha,lambda , 这些参数的合适候选值为:

       alpha:[0, 0.01~0.1, 1]         lambda :[0, 0.1, 0.5, 1]

(4)降低学习率,继续调整参数:

        学习率(learning_rate)合适候选值为:[0.01, 0.015, 0.025, 0.05, 0.1]