目录
一、初识XGBoost
1. 介绍
2. 使用 XGBoost 的方法
(1)直接使用xgboost库自己的建模流程
(2)使用xgboost库中的sklearn的API
3. XGBoost的三大板块
4. 提升集成算法
5. 建模流程
二、模型常用参数
1. n_estimators
2. subsample(有放回抽样问题)
3. eta(步长)
4. booster(选择弱评估器)
5. objective(XGB的目标函数)
补充:方差与泛化误差学习曲线
6. gamma(让树停止生长)
7. scale_pos_weight
三、XGB的目标函数(求解)
1. 目标函数求解
2. 参数化决策树
3. 求解 w 与 T(寻找最佳树结构)
3. 最佳分枝(结构分数之差)
四、模型调参
五、xgboost模型评估
六、XGBoost模型的保存和调用
1. Pickle保存和调用模型
2. Joblib保存和调用模型
七、其他参数
1. n_jobs(更多计算资源)
2. base.score(降低学习难度)
3. random_state(生成树的随机模式)
4. missing(自动处理缺失值)
一、初识XGBoost
1. 介绍
XGBoost 全称 是 eXtreme Gradient Boosting,可译为 极限梯度提升算法。它由 陈天奇所设计,致力于 让提升树突破自身的 计算极限,以实现 运算快速,性能优秀的 工程目标。与决策树、SVM 等不同,它是一个 集大成的机器学习算法。
2. 使用 XGBoost 的方法
(1)直接使用xgboost库自己的建模流程
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)
(2)使用xgboost库中的sklearn的API
class xgboost.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 中设定的 建模流程来 建模,和使用 sklearnAPI中的类来建模,模理效果是 比较 相似的,但是 xgboost 库 本身的 运算速度(尤其是交叉验证)以 及调参手段比 sklearn要 简单。
3. XGBoost的三大板块
XGBoost 本身的 核心是 基于 梯度提升树实现的 集成算法,整体来说 可以有 三个核心部分:集成算法本身,用于集成的弱评估器,以及应用中的其他过程。三个部分中,前 两个部分 包含了 XGBoost 的核心原理 以及 数学过程,最后的部分 主要是在 XGBoost 应用中 占有一席之地。
4. 提升集成算法
XGBoost 的基础是 梯度提升算法。梯度提升(Gradient boosting)是 构建预测模型的 最强大技术 之一,它是 集成算法中 提升法(Boosting) 的 代表算法。集成算法 通过在 数据上 构建多个 弱评估器,汇总 所有弱评估器的 建模结果,以 获取比 单个模型 更好的 回归或分类 表现。弱评估器 被定义为 是表现至少 比随机猜测 更好的模型,即 预测准确率 不低于 50% 的任意 模型。
梯度提升树中 可以 有回归树 也可以 有分类树,两者 都以 CART 树 算法 作为主流,XGBoost 背后也是 CART 树,这意味着 XGBoost 中所有的树都是 二叉的。
5. 建模流程
梯度提升回归树是 专注于回归的 树模型的 提升集成模型,其建模 过程大致如下:最 开始先建立一棵树,然后 逐次迭代,每次 迭代过程中 都增加一棵树,逐渐 形成众多树模型集成的 强评估器。
对于决策树而言,每个 被放入模型的 任意样本 最终一个 都会落到 一个叶子 节点上。而 对于 回归树,每个 叶子节点上的 值是 这个叶子节点上 所有样本的 均值。
对于 梯度提升回归树 来说,每个样本 的预测结果 可以表示为 所有树上的结 果的 加权求和:
其中,K 是树的 总数量,k 代表第 k 棵树, 是这棵树的 权重, 表示这棵树上的 预测 结果。
XGB 和 GBDT 核心区别是 求解预测值的方式 不同,GBDT 中预测值是 由 所有弱分类器上 的预测结果的 加权求和,其中 每个样本上的 预测结果 就是样本 所在的叶子节点的 均值。对于 XGB 来说,每个叶子节点上 会有一个 预测分数(prediction score),也 被称为 叶子权重。这个叶子权重 就是 所有在这个 叶子节点上的样本 在这一棵树上的 回归取值,用 或者 来表示,其中 表示 第 k 棵 决策树, 表示 样本 i 对应的 特征向量。当 只有一棵树的 时候, 就是 提升集成算法 返回的结果。当 有多棵树的时候,集成模型的 回归结 果就是 所有树的预测分数 之和,假设 这个集成模型 中 总共 有 K 棵 决策树,则 整个模型 在这个 样本 i 上 给出的预测 结果为:
二、模型常用参数
1. n_estimators
补充:
① XGB中的 树的 数量决定了 模型的 学习能力,树的数量越多,模型的学习能力越强。只要 XGB 中 树的 数量足够了,即便 只有 很少的数据,模型 也能够 学到 训练数据 100% 的信息,所以 XGB 也是 天生过拟合的 模型。但 在这种情况下,模型 会变得 非常不稳定。
② XGB 中 树的 数量很少的 时候,对 模型的 影响较大,当 树的数量 已经很多的时候,对模型的 影响 比较小。
③ 树的数量 提升 对模型的 影响 有极限,最开始,模型的表现 会随着 XGB 的树的数量一起提升,但到 达某个点 之后,树的 数量越多,模型的效果 会逐步下降,这也 说明了 暴力增加 n_estimators 不一定有效果。
2. subsample(有放回抽样问题)
训练模型 之前,必然 会有一个 巨大的 数据集。树模型 是 天生过拟合的 模型,并且 如果数据量 太过巨大,树模型的 计算 会非常 缓慢,因此,要 对原始数据集 进行 有放回抽样 (bootstrap)。无论是 装袋 还是 提升的 集成算法中,有放回抽样 都是防止 过拟合,让 单一弱分类器 变得 更轻量的 必要操作。实际应用中,每次 抽取 50% 左右的 数据就 能够有不错的 效果了。
在 梯度提升树中,每一次送代 都要 建立一棵 新的树,因此 每次迭代中,都要 有放回 抽取一个 新的 训练样本。但是 这并不能 保证每次 建新树后,集成的效果 都比 之前要好。因此 在梯度提升树中,每 构建一个 评估器,都 让模型 更加集中于 数据集中 容易被判错的 那些样本。
首先 有一个 巨大的 数据集,在 建第一棵树时,对 数据进行 初次 有放回 抽样,然后建模。建模完毕后,对 模型进行 评估,然后 将模型预测 错误的 样本反馈 给 数据集,一次迭代 就算完成。紧接着 要建立 第二棵决策树,于是 开始进行 第二次 有放回抽样。但这次 有放回抽样时,加大了 被 第一棵树判断错误的 样本的 权重。也就是说,被 第一棵树 判断错误的 样本,更 有可能被抽中。基于 这个有权重的 训练集来 建模,新 建的 决策树就会 更加倾向于 这些权重更大的,很容易 被判错的 样本。建模 完毕 之后,又将 判错的 样本 反馈给 原始数据集。下一次 送代的时候,被 判错的 样本的 权重会 更大,新的 模型 会更加 倾向于 很难被判断的 这些样本。如此 反复迭代,越后 面建的树,越是 之前的树 们判错样本 上的 专家,越专 注于攻克 那些之前的 树们 不擅长的 数据。
对于一个样本 而言,它被 预测错误的 次数越多,被 加大权重的 次数也 就越多。只要 弱分类器 足够强大,随着 模型整体 不断在 被判错的样本上 发力,这些样本 会 渐渐被 判断正确。如此 就一定程度上 实现了 我们 每新建一棵树模型的 效果都会 提升的目标。
subsample 参数 通常是 在样本量 本身很大的 时候 调整和 使用。参数 对模型的 影响 应该会非常 不稳定,大概率 应该是 无法提升 模型的泛化能力的,但 也不乏提升模型的 可能性。
3. eta(步长)
除了 保证模型逐渐 倾向于 困难样本的 方向,还 必须控制 新弱分类器的 生成,我们 必须保证,每次 新添加的树 一定得是 对这个新数据集 预测 效果最优的 那一棵树。
可以 首先找到 一个 损失函数 ,这个 损失函数 应该可以 通过 带入 预测结果 ,来衡量 梯度提升树 在样本的 预测效果。然后 利用 梯度下降来 迭代集成算法:
在 k次 迭代 后,集成算法 中 总共 有 k 棵树,k 棵树 的集成结果 是前面 所有树上的 叶子权重的 累加 。所以 让 k 棵树 的集成结果 加上 新建的 树上的 叶子权重 ,就可以 得到 第 k+1 次迭代后,总共 k+1 棵树的 预测结果 了。让 这个 过程持续下去,直到 找到 能够让 损失函数 最小化的 ,这个 就是模型的 预测结果。
上式 𝞰 读作 “eta”,是 迭代 决策树时的 步长(shrinkage),又叫 做学习率 (learning rate)。和 逻辑回归中的 a 类似,𝞰 越大,迭代的 速度越快,算法的 极限 很快被达到,有 可能无法收敛 到真正的 最佳。𝞰 越小,越有可能 找到 更精确的 最佳值,更多的 空间被留 给了 后面建立的树,但 迭代速度会 比较缓慢。
4. booster(选择弱评估器)
5. objective(XGB的目标函数)
不同于 逻辑回归 和 SVM 等算法 中固定的 损失函数写法,集成算法中 的损失函数是 可选的,要 选用什么 损失函数 取决于 我们 希望 解决什么问题,以及 希望使用 怎样的模型。比如说,如果 目标是 进行回归预测,那 可以 选择调节后的 均方误差 RMSE 作为 损失函数。如果是 进行 分类预测,那 可以选择 错误率 error 或者 对数损失 log_loss。只要 选出的 函数 是一个 可微的,能够 代表 某种损失的 函数,它就 可以是 XGB 中的 损失函数。
XGB 的是 实现了 模型表现 和 运算速度 的平衡的 算法。普通的 损失函数,比如 错误率,均方误差等,都 只能够 衡量模型的 表现,无法衡量 模型的 运算速度。XGB 因此 引入了 模型复杂度来 衡量算法的 运算效率。它的 目标函数 被写作:传统损失函数+模型复杂度。
其中 i 代表 数据集 中的 第 i 个样本,m 表示导入 第 k 棵树 的 数据总量,K 代表 建立的 所有树(n_estimators),当只建立了 t 棵树 的时候,式子 应当 为 。
第一项 代表 传统的 损失函数,衡量 真实标签 与预测值 之间的差异,通常是 RMSE(调节后的均方误差)。第二项 代表 模型的 复杂度,使用 树模型的 某种变换 𝛀 表示,这个变化代表了 一个 从树的结构 来衡量 树模型的 复杂度的式子,可以 有多种 定义。在 迭代 每一棵树的过程中,都最小化 来力求 获取最优的分,这 同时 最小化了 模型的 错误率 和 模型的 复杂度。
公式 第一项 传统损失函数 与 已经建好的 所有树 相关:
中己经 包含了 所有树的 迭代结果,因此 整个 目标函数都 与 K 棵树 相关。
补充:方差与泛化误差学习曲线
在机器学习中,用来 衡量模型 在未知数据上的 准确率的 指标,叫做 泛化误差(Genelization error)。一个 集成模型(f)在 未知数据集(D)上的 泛化误差 ,由方差(var),偏差(bais)和 噪声(𝛜)共同决定。其中 偏差 就是 训练集上的 拟合程度决定,方差 是模型的 稳定性决定,噪音 是不可控的。而 泛化误差越小,模型 就越理想。
方差 可以 被简单地 解释为 模型在 不同数据集上 表现出来地 稳定性,而偏 差是 模型预测 的准确度。
所以,式子的 第一项是 衡量偏差,模型 越不准确,第一项 就会越大。第二项 是 衡量方差,模型 越复杂,模型的学习 就会 越具体,到 不同数据集上 的表现 就会差异 巨大,方差 就会越大。所以求解 的 最小值,其实 是 在求解方差 与 偏差的 平衡点,以 求模型的 泛化误差 最小,运行 速度最快。
xgb.train() | xgb.XGBRegressor() | xgb.XGBClassifier() |
---|---|---|
obj
:默认
binary:logistic
| objective:默认reg:linear | objective:默认binary:logistic |
还可以选择自定义损失函数。
# 默认 reg:linear
reg = XGBR(n_estimators=180, random_state=420).fit(Xtrain, Ytrain)
reg.score(Xtest, Ytest)
MSE(Ytest, reg.predict(Xtest))
# 使用类Dmatrix读取数据
dtrain = xgb.DMatrix(Xtrain, Ytrain)
dtest = xgb.DMatrix(Xtest, Ytest)
# 写明参数
param = {'objective':'reg:linear', "eta":0.1}
bst = xgb.train(param, dtrain)
# 接口predict
r2_score(Ytest, bst.predict(dtest))
MSE(Ytest, bst.predict(dtest))
6. gamma(让树停止生长)
从 目标函数 和 结构分数之差 Gain 的式子中 来看,𝛄 是 每增 加一片叶子 就会 被剪去的 惩罚项。增加的 叶子越多,结构 分数之差 Gain 会被惩罚 越重,所以,𝛄 又被称之 为是 “ 复杂性控制 ”(complexity control),所以 𝛄 是 用来防止过拟合的 重要参数。实践证明,𝛄 是 对 梯度提升树 影响 最大的 参数之一,其 效果丝毫不逊色于 n_estimators 和 max_depth。同时,𝛄 还是 让树停止生长的 重要参数。
在 XGB 中规定,只要 结构分数 之差 Gain 是 大于 0 的,即 只要目标函数计 就 允许树 继续进行 分枝。对于 目标函数 减小量的 要求为:
𝛄 设定越大,算法 就越 保守,树的叶子 数量就 越少,模型的 复杂度就 越低。
7. scale_pos_weight
对于 XGB 中的 样本不均衡 问题,通常 在参数中 输入的是 负样本量 与 正样本量 之比:
scale_pos_weight 参数是 通过 调节 预测的概率值来 调节。当 我们 只 关心 预测出的 结果 是否准确,AUC 面积 或者 召回率 是否足够好,就可以 使用 scale_pos_weight 参数。当 我们 希望 能够 保持概率 原有的 模样,而 提升模型的 效果。这种时候,就不应使用scale_pos_weight。
三、XGB的目标函数(求解)
1. 目标函数求解
求解 目标函数的 目的:为了求得在 第 t 次 迭代 中最优的树 。
在 XGB 中迭代的 是 树,树 不是 数字 组成的 向量,并且 其结构 不受到 特征 矩阵 x 取值大小的 直接影响,所以在 XGB 中无法 使用 梯度下降。
在求解 XGB 的 目标函数的 过程中,考虑的是 如何 能够将 目标函数 转化成 更简单的,与树的结构 直接相关的 写法,以此来 建立 树的结构 与 模型的效 果(包括泛化能力与运行速度)之间的 直接联系。也因为 这种联系的 存在,XGB 的目标函数 又被 称为 “结构分数”。
其中 和 分别 是在 损失函数 上对 所求的 一阶导数 和 二阶导数,他们 被统称为 每个样本的 梯度统计量(gradient statisticts)。这里 求解 导数 只是 为了 配合泰勒展开中的 形式,以简化公式为 目的。所以 GBDT 和 XGB 的区别之中,GBDT 求 一阶导数,XGB 求 二阶导数,这 两个过程 根本是 不可类比的。
泰勒展开变换:
其中 表示 上对 x 求导 后,令 x 的值 等于 c 所取得的值。其中 有假设:c 与 x 非常接近, 非常接近 0,于是 可以将式子改写成:
其中, 需要 很小,与 x 相比起来 越小越好,在式子中,需要 很小的 这部分就是 。对于一个 集成算法来说,每次增加的 一棵树 对模型的 影响其实 非常小,尤其 是 当有许多树的 时候。比如 n_estimators=500, 与 x 相比总是 非常小的,因此 这个条件 可以 被满足,泰勒展开 可以被使用。
如此,目标函数 可以被 转化成:
式子中, 和 只与 传统损失函数 相关,核心的部分 是 需要 决定的树 。
2. 参数化决策树
对于 决策树 而言,每个 被放入 模型的 任意 样本 i 最终 都会落到 一个叶子节点上。对于 回归树,通常来说 每个叶子节点上的 预测值 是这个 叶子节点上 所有样本的 标签的 均值。
对于 XGB 来说,每个叶子节点上 会有一个 预测分数 (prediction score),也被称为 叶子权重。这个 叶子权重 就是所有 在这个叶子节点上的 样本在 这一棵树上的 回归取值,用 或者 来表示。
当有 多棵树的 时候,集成模型的 回归结果 就是所有树的 预测 分数 之和。假设 这个 集成模型中总共有 K 棵决策树,则 整个模型 在这个 样本 i 上给出的 预测结果为:
对于 每一棵树,都 有 自己独特的 结构,这个结构 即是 指叶子节点的 数量,树的 深度,叶子的 位置 等所形成的 一个可以 定义 唯一模型的 树结构。在这 个结构中使 用 表示样本 所在的叶子节点,并且使用 来表示 这个样本 落到 第 t 棵树 上的 第 个叶子节 点 中所获得 的分数,于是有:
这是 对于 每一个样本 而言的 叶子权重,然而 在一个叶子节点上 的 所有样本 所对应的 叶子权重 是 相同的。设一棵树 上总共 包含了 T 个叶子节点,其中 每个叶子节点的 索引为 j,则这个叶子节点上 的样本权重是 。依据 这个可以 定义模型的 复杂度 为:
注:这 不是 唯一可能的 定义,还可以 使用其他的 定义,只要 满足 叶子越多 / 深度越大,复杂度 越大的 理论,可以自己决定 要是一个 怎样的式子。
这个结构 中有 两部分内容,一部分是 控制 树结构的 ,另一部分 则是 正则项。叶子数量 T 可以 代表 整个树结构,这是因为 在 XGBoost 中所有的 树都是 CART树(二叉树),所以 可以根据 叶子的 数量 T 判断出 树的深度,而 𝛄 是自定的 控制叶子 数量的 参数。第二部分 正则项,a 和 𝛌 的作用 都是 控制正则化 强度的 参数,可以 二选一使用,也可以 一起使用 加大正则化的 力度。当 𝛌 和 a 都为 0 的时候,目标函数 就是 普通的 梯度提升树的 目标函数。
在 XGB 中,当 𝛌 和 a 越大,惩罚 越重,正则项 所占的 比例就 越大,在尽全力 最小化 目标函数的 最 优化方向下,叶子节点 数量就会 被压制,模型的 复杂度 就 越来越低,所以 对于 天生过拟合的 XGB 来说,正则化 可以 一定程度上 提升 模型效果。从 XGB 的默认 参数来看,优先选择的是 L2 正则化。但如果 真的 希望控制 模型 复杂度,往往 会调整 𝛄 而不是 调整这 两个 正则化参数。
3. 求解 w 与 T(寻找最佳树结构)
树使用 叶子节 点上的 预测分数来 表达,而树的 复杂度 则是 叶子数目 加上正则项:
假设现在 第 t 棵树的 结构已经 被 确定为 q,可以 将树的 结构 带入 损失函数,来 继续 转化目标函数。转化目标 函数的 目的是:建立树的结构(叶子节点的数量)与 目标函数的 大小 之间的 直接联系,以求出在 第 t 次迭代 中 需要求解的 最优的树 。
注:假设使用的是 L2正则化(这也是参数 lambda 和 alpha的 默认设置,lambda 为 1,alpha 为 0)。
于是有:
定义:
于是有:
其中 每个 j 取值下 都是一个 以 为自变量的 二次函数 ,目标是追求让 最小,只要 单独的 每一个 叶子 j 取值下的 二次函数 都最小,那他们的 加和 必然也会 最小。于是,在 上对 求导,让 一阶导数 等于 0 以求 极值,可得:
带入 目标函数 则有:
到了这里,比起最初的 损失函数+复杂度 的样子,现在 目标函数 已经 发生了 巨大变化。样本量 i 已经被 归结到了 每个叶子当中去,目标函数 是 基于 每个叶子节点,也就是 树的结构 来计算。所以,目标函数又叫做 “结构分数”(structure score),分数越低,树整体的 结构越好。如此就 建立了 树的结构(叶子)和 模型效果的 直接联系。
举个 例子:
在 XGB 的运行过程 中,会根据 的表达式 直接探索 最好的 树结构,也就是 说 找寻 最佳的树。从式子 中 可以看出,𝛌 和 𝛄 是设定好的 超参数, 和 是由 损失函数 和 这个 特定结构下树的 预测结果 共同决定,而 T 只由 树结构 决定。则通过最小化 所求 解出的 其实是 T(叶子的数量),本质也 就是 求解树的 结构了。
补:
① 求解 和 中带有 w 和 求解叶子权重 的问题?
一阶 和 二阶 导数的本质:
预测值的 求解公式:
与现 在要求解的 不是在 同一棵树上 的。我们是 在一直 迭代的,现在求解的 是 第 t 棵树 上的 结果,而 是前面的 棵树的 累积 w,是 在前面 所有的 迭代 中 已经 求解出来的 己知的 部分。
② 没有 “前面 己经迭代完毕 的部分”,怎么办?
假设 来 解决问题 。
3. 最佳分枝(结构分数之差)
在 XGB 中,我们 首先 使用目标函数 来衡量 树的结构的 优劣,然后 让 树从 深度 0 开始生长,每 进行一次 分枝,我们 就计算 目标函数 减少了 多少,当 目标函数的 降低 低于 设定的 某个阈值 时,就让树 停止生长。
对于 中间节点 这一个叶子 节点而言,T=1,则这个 节点上的 结构分数为:
对于 弟弟 和 妹妹节点 而言,则有:
分枝后 的结构 分数 之差为:
最后 可知,分枝后的 结构分数 之差为:
其中 和 从 左节点(弟弟节点)上 计算得出, 和 从 右节点(妹妹节点)上计算得出,而 和 从 中间节点上 计算得出。对于 任意 分枝,都可以 这样来进 行计算。
四、模型调参
参数含义 | xgb.train() | xgb.XGBRegressor() |
---|---|---|
树的最大深度
| max_depth,默认6 | max_depth,默认6 |
每次生成树时随机抽样特征的比例
| colsample_bytree,默认1 | colsample_bytree,默认1 |
每次生成树的一层时
随机抽样特征的 比例
| colsample_bylevel,默认1 | colsample_bylevel,默认1 |
每次生成一个叶子节点时
随机抽样特征的比例
| colsample_bynode,默认1 | N.A. |
一个叶子节点上所需要的最小
即叶子节点上的 二阶导数之和
类似于样本权重
| min_child_weight,默认1 | min_child_weight,默认1 |
这些 参数中,树的 最大深度是 决策树中 最常用的 剪枝参数,不过在 XGBoost 中,最大深度的 功能与 𝛄 参数 相似,因此 如果 先调节了 𝛄,则 最大深度 可能 无法 展示出 巨大的效果。当然,如果 先调整了 最大深度,则 𝛄 也有 可能无法 显示明显的 效果。通常来说,这 两个参数 中我们 只使用一个。也可以 都试试。
三个 随机抽样特征的 参数中,前 两个比较 常用。Boosting 算法一直以 抽取样本(横向 抽样)来 调整模型 过拟合的 程度,而 实践证明其实 纵向抽样(抽取特征)更 能够 防止过拟合。
参数 min_child_weight 不太常用,它 是 一篇叶子上的 二阶导数 之和,当 样本所 对应 的二阶导数 很小 时,比如说为 0.01,min_child_weight 若设定 为 1,则 说明 一片叶子 上 至少 需要 100个 样本。本质上 来说,这个 参数其实 是在 控制叶子上 所需的 最小样本量,因此 对于样本量很大的 数据会 比较有效。就 剪枝的效果 来说,这个 参数的 功能也 被 𝛄 替代了一部分,通常来说 可以试试看 这个参数。
剪枝上的调参顺序是: n_estimators 与 eta 共同调节,gamma 或者 max_depth,采样 和 抽样参数(纵向抽样影响更大),最后 才是 正则化的 两个参数。
五、xgboost模型评估
在 sklearn 下 XGBoost太不稳定,如果这样来调整参数的话,效果 就 很难保证。因此 引入新的工具,xgboost 库中的 类 xgboost.cv。
xgboost.cv (params, dtrain, num_boost_round=10, nfold=3, stratified=False, folds=None, metrics=(), obj=None, feval=None, maximize=False, early_stopping_rounds=None, fpreproc=None, as_pandas=True, verbose_eval=None, show_stdv=True, seed=0, callbacks=None, shuffle=True)
import xgboost as xgb
dfull = xgb.DMatrix(X,y)
#设定参数
param1 = {'obj':'reg:linear', "gamma":0}
num_round = 180
n_fold=5
cvresult1 = xgb.cv(param1, dfull, num_round, n_fold)
六、XGBoost模型的保存和调用
1. Pickle保存和调用模型
import pickle
dtrain = xgb.DMatrix(Xtrain, Ytrain)
#设定参数,对模型进行训练
param = {'obj':'reg:linear'
,"eta":0.05
,"gamma":20}
num_round = 180
bst = xgb.train(param, dtrain, num_round)
#保存模型
pickle.dump(bst, open("xgboost_01.dat", "wb"))
# wb 表示以 二进制写入,rb 表示以 二进制读入
#导入模型
loaded_model = pickle.load(open("xgboost_01.dat", "rb"))
2. Joblib保存和调用模型
import joblib
bst = xgb.train(param, dtrain, num_round)
# 保存模型
joblib.dump(bst, "xgboost_02.dat")
# 导入模型
loaded_model = joblib.load("xgboost_02.dat")
七、其他参数
1. n_jobs(更多计算资源)
nthread 和 n_jobs 都是 算法运行所 使用的 线程,与 sklearn 中规则一样,输入 整数 表示使用的 线程,输入 -1表 示 使用 计算机全部的 计算资源。如果 数据量很大,则 可能 需要这个 参数来 为调用 更多线程。
2. base.score(降低学习难度)
它被叫做 全局偏差,在 分类问题中,它是 我们 希望关注的 分类的 先验概率。比如说,如果 我们有 1000 个样本,其中 300个 正样本,700 个 负样本,则 base_score 就是0.3。对于 回归来说,这个分数 默认 0.5,但其 实这个分数 在这种情况下 并不有效。许多 使用 XGBoost 的人已经提出,当 使用回归 的时候 base_score 的默认 应该是 标签的 均值,不过现在 xgboost 库 尚未 对此做出 改进。使用 这个参数,便是 在告诉 模型 —些 我们了解但模型 不一定 能够 从数据中学习 到的信息。通常 我们不会 使用这个 参数,但 对于严重的 样本不均衡 问题,设置一个 正确的 base_score 取值是很有必要的。
3. random_state(生成树的随机模式)
在 xgb 库 和 sklearn 中,都 存在 空值 生成树的 随机模式的 参数 random_state。在 剪枝中,可以 通过 随机抽样特征 来 减轻过拟合的 影响,我们 可以 通过其他 参数来 影响 随机抽样的 比例,却无 法对 随机抽样 干涉 更多,因此,真正 的随机性 还是由 模型 自己 生成的。如果 希望控制 这种 随机性,可以 在 random_state 参数中 输入 固定整数。需要 注意的是,xgb 库 和 sklearn 库 中,在 random_state 参数中 输入同 一个整数 未必 表示 同一个随机 模式,不一定 会得到 相同的结果,因此 导致模 型的 feature_importances 也会不一致。
4. missing(自动处理缺失值)
XGBoost 被设计成 是 能够 自动处理 缺失值的 模型,这个 设计的初衷 其实是 为了让XGBoost 能够处理 稀疏矩阵。可以在 参数 missing 中输入一个 对象,比如 np.nan,或 数据的 任意取值,表示 将所有 含有 这个对象的 数据作为 空值处理。XGBoost 会将 所有的 空值当作 稀疏矩阵中的 0 来进行处理,因此 在使用 XGBoost 的时候,也可以 不处理缺失值。