XGBoost库的使用

XGBoost库实际上就是对GBDT 算法的一种优化的实现,XGBoost是机器学习中准确率最高的算法了,下面我将详细介绍XGBoost库的使用。

XGBoost有两种类型的Python API,一种是原生的,一种是为了方便 sklearn 库的开发人员设计的 sklearn 风格的API,在这里我会简单介绍下原生API的流程和参数,更加推荐大家使用sklearn风格的API。

1. 原生API

1.1 读取数据

import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import numpy as np

# 使用sklearn的数据集生成函数
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)

1.2 设置参数

XGBoost 的参数设置采用的是键值对,即 key : value 的形式,设置如下:

params = {
    'booster': 'gbtree',
    'objective': 'binary:logistic',# 二分类的问题
    'gamma': 0.1,                  # 用于控制是否后剪枝的参数,越大越保守,一般0.1、0.2这样子。
    'max_depth': 12,               # 构建树的深度,越大越容易过拟合
    'lambda': 2,                   # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。
    'subsample': 0.7,              # 随机采样训练样本
    'colsample_bytree': 0.7,       # 生成树时进行的列采样
    'min_child_weight': 3,         # 最小子节点的权重
    'verbosity': 2,                # 设置成2则输出详细信息
    'eta': 0.001,                  # 如同学习率
    'seed': 1000,                  
    'nthread': 4,                  # cpu 线程数
}

注意, objective 中写了二分类问题后,就不能再写问题的分类数量 num_class=2 了,否则会报错。

1.3 训练模型

# 迭代的次数
num_rounds = 100
model = xgb.train(params, dtrain, num_rounds)

1.4 模型预测

# 对测试集进行预测
y_pred = model.predict(dtest)
y_pred = (y_pred > 0.5).astype(np.int32)
accuracy = accuracy_score(y_test,y_pred)
print("accuarcy: %.2f%%" % (accuracy*100.0))

1.5 保存、读取模型

# 保存模型
model.save_model('0001.model')

# 加载保存的模型:
bst = xgb.Booster({'nthread': 4})  # init model
bst.load_model('0001.model')  # load data

2. sklearn风格API

对sklearn不清楚的朋友可以看我的上一篇博文对sklearn了解一下。

XGBoost在sklearn风格中的参数可以直接在初始化类时就写进去,如sklearn的逻辑回归参数形式 LogisticRegression(solver='saga', multi_class='auto', random_state=42, max_iter=10000) 一样。

2.1 sklearn风格分类

我们这里对sklearn中的鸢尾花数据集进行分类,代码如下:

from sklearn.datasets import load_iris
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 加载样本数据集
iris = load_iris()
X,y = iris.data,iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1234565) # 数据集分割

# 训练模型
model = xgb.XGBClassifier(max_depth=5, learning_rate=0.1, n_estimators=160, silent=True, objective='multi:softmax')
model.fit(X_train, y_train)

# 对测试集进行预测
y_pred = model.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test,y_pred)
print("accuarcy: %.2f%%" % (accuracy*100.0))

可以看到,XGBoost 完美的融入到了 sklearn 的流程当中,sklearn使用不同的算法只需要将初始化的估计器改个名字就行,这对XGBoost也是一样的。

2.2 sklearn风格回归

这里我们使用sklearn数据集中的波士顿房价来当做示例。

import xgboost as xgb
from xgboost import plot_importance
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_boston

boston = load_boston()
X,y = boston.data,boston.target

# XGBoost训练过程
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

model = xgb.XGBRegressor(max_depth=5, learning_rate=0.1, n_estimators=160, silent=True, objective='reg:gamma')
model.fit(X_train, y_train)

# 对测试集进行预测
ans = model.predict(X_test)

2.3 XGBoost 参数说明

XGBoost在原生API以及sklearn风格中的参数如下所示。

sklearn API参数原生API参数默认值含义说明
n_estimatorsnum_round子学习器个数boosting框架下的子学习器数量。在原生API中,该参数在train方法中定义,也即最大迭代次数
learning_rateeta0.3学习率用于限制子学习器的过拟合,提高模型的泛化能力,与n_estimators配合使用
verbosityverbosity1是否输出详细信息,2是输出详细信息,1是偶尔输出,0是不输出
subsampleeta0.3样本子采样数用于限制子学习器的过拟合,提高模型的泛化能力,与n_estimators配合使用
max_depthmax_depth6树的最大深度对基学习器函数空间的正则化,一种预修剪手段
objectiveobjective损失函数自定义的损失函数,通过申明合适的损失函数来处理分类、回归和排序问题。常见的方法包括线性回归‘reg:linear’、逻辑回归’reg:logistic’、二分类逻辑回归’binary:logistic’,多分类’multi:softmax’,平方误差reg:squarederror
boosterboostergbtree基学习器类型xgboost中采用的基学习器,如梯度提升树’gbtree’,梯度提升线性模型’gblinear’等
gammagamma0分裂阈值即最小损失分裂,用来控制分裂遵循的结构分数提升下限阈值。
min_child_weightgamin_child_weightma叶子节点最小权重叶子节点允许的最小权重值(即节点中所有样本的二阶导数值之和),可视为是对叶子节点的正则化,是一种后剪枝的手段。
reg_alphaalpha0L1正则化系数对集成模型进行L1正则化(以子节点的个数为约束)的系数
reg_lambdalambda0L2正则化系数对集成模型进行L2正则化(以子节点权重w的平方和为约束)的系数
nthreadn_jobs最大并发线程数最大并发线程数
random_stateseed随机种子控制模型的随机性。
missingmissingNone为缺失值进行标注。默认为None,即标注为np.nan。

除了上述模型,在xgboost的 fit 方法中,还涉及到几个重要参数:
(1)sample_weight:表示样本权重
(2)eval_set:在训练的同时进行验证的数据集
(3)eval_metric:验证集的评价指标
(4)early_stopping_rounds: 根据模型在验证集表现的早停轮数阈值。具体而言,若模型在连续early_stopping_rounds次迭代过程中,其在eval_set上的eval_metric并无提升,则模型停止迭代。

3. XGBoost 调参

XGBoost 的调参主要集中在以下几个参数,未提到的参数都可以使用系统的默认值。

  • objective
    在回归问题 objective 一般使用 reg:squarederror ,即MSE均方误差。二分类问题一般使用 binary:logistic , 多分类问题一般使用 multi:softmax
  • max_depth
    控制树结构的深度,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,需要限制这个最大深度,具体的取值一般要网格搜索调参。常用 3-10 之间。
  • min_child_weight
    最小的子节点权重阈值,如果某个树节点的权重小于这个阈值,则不会再分裂子树,即这个树节点就是叶子节点。这个值需要网格搜索寻找最优值.
  • gamma
    XGBoost的决策树分裂所带来的损失减小阈值。这个值也需要网格搜索寻找最优值。
  • subsample
    选择小于1的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,因此取值不能太低。初期可以取值1,如果发现过拟合后可以网格搜索调参找一个相对小一些的值,典型的范围在 0.5-0.9 之间
  • n_estimators
    `n_estimators则是非常重要的要调的参数,它关系到我们XGBoost模型的复杂度,因为它代表了我们决策树弱学习器的个数。这个参数对应sklearn GBDT的n_estimators。n_estimators太小,容易欠拟合,n_estimators太大,模型会过于复杂,一般需要调参选择一个适中的数值。
  • learning_rate
    学习率,理想的学习率一般在0.05-0.3之间,一般情况为0.1,。
  • colsample_bytree
    用来控制每棵随机采样的列数的占比(每一列是一个特征)。 典型值:0.5-1 之间。
  • reg_lambda
    权重的L2正则化项。(和Ridge regression类似)。这个参数是用来控制XGBoost的正则化部分的。这个参数在减少过拟合上很有帮助。
  • reg_alpha
    权重的L1正则化项。(和Lasso regression类似)。 可以应用在很高维度的情况下,使得算法的速度更快。

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

以下为一个网格搜索的例子:

import xgboost as xgb
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score

train_data = pd.read_csv('train.csv')   # 读取数据
y = train_data.pop('30').values   # 用pop方式将训练数据中的标签值y取出来,作为训练目标,这里的‘30’是标签的列名
col = train_data.columns   
x = train_data[col].values  # 剩下的列作为训练数据
train_x, valid_x, train_y, valid_y = train_test_split(x, y, test_size=0.333, random_state=0)   # 分训练集和验证集
# 这里不需要Dmatrix

parameters = {
              'max_depth': [5, 10, 15, 20, 25],
              'learning_rate': [0.01, 0.02, 0.05, 0.1, 0.15],
              'n_estimators': [500, 1000, 2000, 3000, 5000],
              'min_child_weight': [0, 2, 5, 10, 20],
              'max_delta_step': [0, 0.2, 0.6, 1, 2],
              'subsample': [0.6, 0.7, 0.8, 0.85, 0.95],
              'colsample_bytree': [0.5, 0.6, 0.7, 0.8, 0.9],
              'reg_alpha': [0, 0.25, 0.5, 0.75, 1],
              'reg_lambda': [0.2, 0.4, 0.6, 0.8, 1],
              'scale_pos_weight': [0.2, 0.4, 0.6, 0.8, 1]

}

xlf = xgb.XGBClassifier(max_depth=10,
            learning_rate=0.01,
            n_estimators=2000,
            verbosity=2,
            objective='binary:logistic',
            nthread=-1,
            gamma=0,
            min_child_weight=1,
            max_delta_step=0,
            subsample=0.85,
            colsample_bytree=0.7,
            colsample_bylevel=1,
            reg_alpha=0,
            reg_lambda=1,
            scale_pos_weight=1,
            seed=1440,
            missing=None)
            
# 有了gridsearch我们便不需要fit函数
gsearch = GridSearchCV(xlf, param_grid=parameters, scoring='accuracy', cv=3)
gsearch.fit(train_x, train_y)

print("Best score: %0.3f" % gsearch.best_score_)
print("Best parameters set:")
best_parameters = gsearch.best_estimator_.get_params()
for param_name in sorted(parameters.keys()):
    print("\t%s: %r" % (param_name, best_parameters[param_name]))

Reference

[1] https://blog.youkuaiyun.com/guofei_fly/article/details/103569388
[2] https://www.cnblogs.com/pinard/p/11114748.html
[3] https://www.jianshu.com/p/1100e333fcab
[4] https://cloud.tencent.com/developer/article/2070965
[5] https://zhuanlan.zhihu.com/p/143009353?utm_source=ZHShareTargetIDMore

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值