【xgboost】XGBoost

07-21 1685阅读

XGBoost

  • p.s. 参考链接(very nice)
  • 1. 原理改进及特点
    • 1.1 遵循Boosting算法的基本建模流程
    • 1.2 平衡精确性与复杂度
    • 1.3 降低模型复杂度、提升运行效率
    • 1.4 保留部份GBDT属性
    • 1.5 Boosting算法的改进历程
    • 2. sklearn接口(回归)
      • 2.1 导库 & 数据
      • 2.2 sklearn api普通训练
      • 2.3 sklearn api交叉验证
      • 2.4 查看属性接口
      • 2.5 参数意义&调参指导(chat-gpt版)
      • 3. xgboost原生代码(回归)
        • 3.1 导包
        • 3.2 DMatrix数据 xgboost.DMatrix()
        • 3.3 params参数 params={}
        • 3.4 不交叉验证 xgboost.train()
          • 3.4.1 参数 & 代码
          • 3.4.2 评估指标
          • 3.5 交叉验证 xgboost.cv()
          • 4. xgboost实现分类
            • 4.1 sklearn接口
            • 4.2 xgboost原生代码

              p.s. 参考链接(very nice)

              知乎 - xgboost的参数解释和调整

              1. 原理改进及特点

              1.1 遵循Boosting算法的基本建模流程

              依据上一个弱评估器f(x)k-1的结果,计算损失函数L;

              并使用L自适应地影响下一个弱评估器f(x)k的构建。

              集成模型输出的结果,受所有弱评估器f(x)0~f(x)K的影响.

              1.2 平衡精确性与复杂度

              树模型的学习能力和过拟合风险需要平衡,即预测精确性与模型复杂度之间的平衡,经验风险与结构风险之间的平衡。

              一般建立模型后手动剪枝调节复杂度,XGBoost在迭代过程中实现平衡。

              • XGBoost为损失函数加入结构风险项

                AdaBoost、GBDT追求损失函数L(y,y^)最小化;

                XGBoost追求目标函数O(y,y^) = L(y,y^) + 结构风险项最小化。

                XGBoost利用结构风险项控制过拟合,其他树模型依赖树结构max_depth,min_impurity_decrease等。

              • XGBoost使用新不纯度衡量指标

                一般算法建CART树,分类使用信息增益,回归使用MSE或弗里德曼MSE;

                XGBoost设定分支指标结构分数,基于结构分数的结构分数增益,向整体结构简单的方向建树。

                1.3 降低模型复杂度、提升运行效率

                决策树建树,需要对每一个特征上所有潜在的分支节点进行不纯度计算。XGBoost多种优化技巧优化提升效率:

                • 全新建树流程

                  使用估计贪婪算法、平行学习、分位数草图算法等,适用于大数据。

                • 提升硬件运算性能

                  使用感知缓存访问技术、核外计算技术。

                • 建树增加随机性

                  引入Dropout技术。

                  1.4 保留部份GBDT属性

                  • 弱评估器是回归器,借助sigmoid或softmax实现分类。
                  • 拟合负梯度

                    GBDT中每次用于建立评估器的是样本X,以及当下集成输出H(xi)与真是标签y之间的伪残差(负梯度)。

                    当损失函数是1/2 MSE时,负梯度等同于残差。

                    XGBoost同样依赖于拟合残差来影响后续弱评估器建立。

                  • 抽样思想

                    对样本和特征进行抽样增大弱评估器之间的独立性。

                    1.5 Boosting算法的改进历程

                    【xgboost】XGBoost

                    2. sklearn接口(回归)

                    2.1 导库 & 数据

                    from sklearn.model_selection import KFold, cross_validate
                    from sklearn.model_selection import train_test_split
                    from xgboost import XGBRegressor
                    '''
                    xgboost提供的sklearn api
                        XGBRegressor()    实现xgboost回归
                        XGBClassifier()   实现xgboost分类
                        XGBRanker()       实现xgboost排序
                        XGBRFClassifier() 基于xgboost库实现随机森林分类
                        XGBRFRegressor()  基于xgboost库实现随机森林回归
                    '''
                    
                    from sklearn.datasets import load_digits
                    data = load_digits()
                    X = data.data
                    y = data.target
                    Xtrain,Xtest,Ytrain,Ytest = train_test_split(X,y,test_size=0.3,random_state=1412)
                    print(Xtrain.shape, Xtest.shape)
                    '''
                        (1257, 64) (540, 64)
                    '''
                    

                    2.2 sklearn api普通训练

                    # sklearn普通训练:实例化,fit,score
                    # booster 使用弱评估器建树,可选gbtree,gbliner,dart
                    xgb_sk = XGBRegressor(random_state=1412)
                    xgb_sk.fit(Xtrain, Ytrain)
                    xgb_sk.score(Xtest, Ytest) # 默认评估指标R^2
                    '''
                        0.831818417176343
                    '''
                    

                    2.3 sklearn api交叉验证

                    # sklearn交叉验证:实例化,交叉验证,结果求平均
                    xgb_sk = XGBRegressor(random_state=1412)
                    cv = KFold(n_splits=5, shuffle=True, random_state=1412)
                    result_xgb_sk = cross_validate(xgb_sk
                                                  ,X,y
                                                  ,scoring='neg_root_mean_squared_error' #-RMSE
                                                  ,return_train_score=True
                                                  ,verbose=True
                                                  ,n_jobs=-1
                                                  )
                    result_xgb_sk
                    '''
                        {'fit_time': array([1.49709201, 1.51305127, 1.5214994 , 1.52006483, 1.49009109]),
                         'score_time': array([0.00797772, 0.0069809 , 0.02449441, 0.00797725, 0.01301908]),
                         'test_score': array([-1.3107202 , -1.3926962 , -1.34945876, -1.18663263, -1.49893354]),
                         'train_score': array([-0.0196779 , -0.02156499, -0.0167526 , -0.01670659, -0.02254371])}
                    '''
                    
                    def RMSE(result, name):
                        return abs(result[name].mean())
                    RMSE(result_xgb_sk, 'train_score')
                    '''
                        0.019449156665978885
                    '''
                    RMSE(result_xgb_sk, 'test_score')
                    '''
                        1.347688263452443
                    '''
                    

                    2.4 查看属性接口

                    # sklearn查看属性接口
                    xgb_sk = XGBRegressor(max_depth=5).fit(X,y)
                    xgb_sk.feature_importances_ # 特征重要性
                    '''
                        array([0.        , 0.00225333, 0.00230321, 0.00326973, 0.00863725,
                               0.00895859, 0.00746422, 0.00157759, 0.        , 0.00096148,
                               0.00569782, 0.00173326, 0.02128937, 0.00525403, 0.00283347,
                               0.00028462, 0.00450659, 0.00130977, 0.01772124, 0.00536137,
                               0.04007934, 0.06141694, 0.00869896, 0.00226618, 0.        ,
                               0.00413993, 0.01785861, 0.03045771, 0.0369929 , 0.03439412,
                               0.04346734, 0.00481802, 0.        , 0.04838382, 0.01810016,
                               0.03241276, 0.06217332, 0.00609181, 0.00342981, 0.        ,
                               0.        , 0.00546112, 0.04138443, 0.00643031, 0.00676051,
                               0.00443247, 0.00591809, 0.        , 0.        , 0.00230393,
                               0.00367385, 0.02346367, 0.0843313 , 0.01382598, 0.00216754,
                               0.00023067, 0.        , 0.00051113, 0.01587264, 0.00686751,
                               0.01672259, 0.01588235, 0.00281848, 0.18434276], dtype=float32)
                    '''
                    
                    # 调出单独的树
                    xgb_sk.get_booster()[1] 
                    '''
                        
                    '''
                    # 一共建立树数量,n_estimators取值
                    xgb_sk.get_num_boosting_rounds() 
                    '''
                        100
                    '''
                    
                    # 获取参数取值
                    xgb_sk.get_params()
                    '''
                        {'objective': 'reg:squarederror',
                         'base_score': 0.5,
                         'booster': 'gbtree',
                         'callbacks': None,
                         'colsample_bylevel': 1,
                         'colsample_bynode': 1,
                         'colsample_bytree': 1,
                         'early_stopping_rounds': None,
                         'enable_categorical': False,
                         'eval_metric': None,
                         'gamma': 0,
                         'gpu_id': -1,
                         'grow_policy': 'depthwise',
                         'importance_type': None,
                         'interaction_constraints': '',
                         'learning_rate': 0.300000012,
                         'max_bin': 256,
                         'max_cat_to_onehot': 4,
                         'max_delta_step': 0,
                         'max_depth': 5,
                         'max_leaves': 0,
                         'min_child_weight': 1,
                         'missing': nan,
                         'monotone_constraints': '()',
                         'n_estimators': 100,
                         'n_jobs': 0,
                         'num_parallel_tree': 1,
                         'predictor': 'auto',
                         'random_state': 0,
                         'reg_alpha': 0,
                         'reg_lambda': 1,
                         'sampling_method': 'uniform',
                         'scale_pos_weight': 1,
                         'subsample': 1,
                         'tree_method': 'exact',
                         'validate_parameters': 1,
                         'verbosity': None}
                    '''
                    

                    2.5 参数意义&调参指导(chat-gpt版)

                    1. n_estimators: 弱学习器(决策树)的数量,即梯度提升迭代的次数。增加此参数可能会导致过拟合,因为模型更多地关注训练集,而不是泛化到新数据上。
                    2. learning_rate: 每个决策树对模型的贡献系数,用于缩小每个决策树的影响。默认0.1。较小的学习率可以降低过拟合的风险,但也可能增加训练时间。
                    3. max_depth: 决策树的最大深度,用于控制决策树的复杂度。较大的值可能导致过拟合。
                    4. subsample: 每次迭代使用的样本比例,用于控制样本的随机性。较小的子样本比例可能会降低过拟合的风险,但也可能减少模型的预测能力。
                    5. colsample_bytree: 每次迭代使用的特征比例,用于控制特征的随机性。较小的特征比例可能会降低过拟合的风险,但也可能减少模型的预测能力。
                    6. gamma: 决策树节点分裂的最小损失函数下降值。在节点分裂时,只有分裂后损失函数的值下降了,才会分裂这个节点。增加此参数可能会降低过拟合的风险,设置过高会导致欠拟合。
                    7. reg_alpha和reg_lambda: L1和L2正则化的权重,用于控制模型的复杂度。较大的正则化权重可能会降低过拟合的风险,但也可能降低模型的预测能力。
                    8. min_child_weight: 决策树节点所需的最小叶子节点样本权重和,用于避免过拟合。增加此参数可以减少过拟合的风险,避免学习局部特殊样本。
                    9. scale_pos_weight: 正样本权重与负样本权重的比例,用于解决类别不平衡问题。

                    除了上述参数外,Scikit-Learn接口实现还支持许多其他参数,例如min_child_weight、scale_pos_weight等。这些参数的含义和XGBoost原生API实现中的含义基本相同,但可能存在一些差异。用户在使用时应该根据自己的需求和数据特点选择合适的参数值。

                    调参步骤&举例

                    3. xgboost原生代码(回归)

                    3.1 导包

                    from sklearn.datasets import load_digits
                    import xgboost # 原生代码只需导入xgboost
                    data = load_digits()
                    X = data.data
                    y = data.target
                    print(X.shape,y.shape)
                    '''
                        (1797, 64) (1797,)
                    '''
                    

                    3.2 DMatrix数据 xgboost.DMatrix()

                    • 必须使用xgboost自定义的数据结构DMatrix
                      '''
                      返回专用的DMatrix对象
                      不能索引和循环读取, 即不可查看和修改
                      不分X,y,特征和标签同时打包,训练时作为dtrain的输入
                      '''
                      data_xgb = xgboost.DMatrix(X,y)
                      print(data_xgb)
                      
                      '''
                      若需划分训练测试集,需提前划分再转换类型
                      '''
                      from sklearn.model_selection import train_test_split
                      Xtrain,Xtest,Ytrain,Ytest = train_test_split(X,y,test_size=0.3,random_state=1412)
                      dtrain = xgboost.DMatrix(Xtrain, Ytrain)
                      dtest = xgboost.DMatrix(Xtest, Ytest)
                      print(dtrain, dtest)
                      '''
                          
                           
                      '''
                      

                      3.3 params参数 params={}

                      '''
                      定义参数
                      参数名称会与sklearn有区别,seed随机数种子
                      这里的seed是boosting过程的随机数种子
                      '''
                      params = {'max_depth':5, 'seed':1412}
                      

                      3.4 不交叉验证 xgboost.train()

                      3.4.1 参数 & 代码

                      '''
                      xgboost.train()
                          包含了实例化和训练过程,返回实例
                          训练时没区分回归分类,默认执行回归算法
                          
                      .train()中,params外
                          num_boost_round 控制建树数量(迭代次数)
                          提前停止
                          一般来说除了上述两个参数,其余参数设置在params中
                      params中
                          xgb_model 指定弱评估器,可选gbtree,gbliner,dart评估器有不同的params列表
                          eta boosting算法中的学习率
                          objective 用于优化的损失函数,分类使用
                          base_score 初始化预测结果H0的值
                          max_delta_step 一次迭代中允许的最大迭代值
                          目标函数参数 https://www.bilibili.com/video/BV1Au411B7bC
                          gamma,lambda,alpha 放大可控制过拟合
                      '''
                      
                      reg = xgboost.train(params, data_xgb, num_boost_round=100)
                      y_pred = reg.predict(data_xgb)
                      y_pred
                      '''
                          array([-0.10801424,  0.84069467,  2.083782  , ...,  8.143546  ,
                                  8.9779825 ,  8.03064   ], dtype=float32)
                      '''
                      

                      3.4.2 评估指标

                      # 评估指标
                      # 借用sklearn.metrics
                      from sklearn.metrics import mean_squared_error as MSE
                      # squared=False 使用RMSE
                      MSE(y, y_pred, squared=False)
                      '''
                          0.10822869258896699
                      '''
                      
                      # 特征重要性
                      from xgboost import plot_importance
                      plot_importance(reg)
                      '''
                          
                      '''
                      

                      【xgboost】XGBoost

                      3.5 交叉验证 xgboost.cv()

                      '''
                      不会返回模型,train()可以返回模型
                      返回评估指标和数值
                      '''
                      result = xgboost.cv(params, data_xgb, num_boost_round=100
                                         ,nfold=5 # 5折
                                         # 交叉验证的随机数种子
                                         # params中seed是建树的随机数种子
                                         ,seed=1412
                                         )
                      
                      '''
                      返回DataFrame
                      100行代表num_boost_round定义迭代100次
                      每一次迭代都会进行5折交叉验证,显示结果为5次的平均
                      4列,训练集/测试集 上的 均值/标准差
                      很适合用来绘制图像
                      '''
                      result
                      
                      train-rmse-meantrain-rmse-stdtest-rmse-meantest-rmse-std
                      03.6381850.0396323.6777300.202608
                      12.7634500.0287392.8781120.173517
                      22.1282770.0208192.3033250.152110
                      31.6775890.0277721.9110490.117346
                      41.3735730.0346421.6579490.097172
                      ...............
                      950.0946390.0044661.0766970.055437
                      960.0925240.0041421.0764980.055798
                      970.0910610.0039361.0764790.055860
                      980.0897550.0038741.0764140.055971
                      990.0885330.0036731.0765860.056002

                      100 rows × 4 columns

                      import matplotlib.pyplot as plt
                      # dpi=300分辨率,figsize=[,]画布大小
                      plt.figure()
                      plt.plot(result['train-rmse-mean'])
                      plt.plot(result['test-rmse-mean'])
                      plt.legend(['train', 'test'])
                      plt.title('xgboost 5fold cv')
                      

                      【xgboost】XGBoost

                      4. xgboost实现分类

                      4.1 sklearn接口

                      from xgboost import XGBClassifier
                      

                      4.2 xgboost原生代码

                      '''
                      objective:
                      “reg:linear” 线性回归.
                      “reg:logistic" 逻辑回归.
                      “binary:logistic” 二分类的逻辑回归问题,输出为概率.
                      “binary:logitraw” 二分类的逻辑回归问题,输出的为wTx.
                      “count:poisson” 计数问题的poisson回归,输出结果为poisson分布.max_delta_step默认为0.7.(used to safeguard optimization)
                      “multi:softmax” softmax处理多分类问题,同时需要设置参数num_class(类别个数).
                      “multi:softprob” 输出各个分类概率,ndata*nclass向量,表示样本所属于每个类别的概率.
                      “rank:pairwise” set XGBoost to do ranking task by minimizing the pairwise loss.
                      '''
                      params = {'learning_rate':0.1
                               ,'max_depth':5
                               ,'objective':'multi:softmax'
                               # ,'objective':'multi:softprob'
                               ,'num_class':10
                               ,'random_state':1412
                               , 'eta':0.8 # boosting算法中的学学习率
                               }
                      
                      model = xgboost.train(params, data_xgb, num_boost_round=10)
                      y_pred = model.predict(data_xgb)
                      y_pred
                      '''
                          array([0., 1., 2., ..., 8., 9., 8.], dtype=float32)
                      '''
                      
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]