ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

XGBoost 随机森林(Random Forest)训练完全指南:从原生 API 到 Scikit-Learn 接口

XGBoost 随机森林(Random Forest)训练完全指南:从原生 API 到 Scikit-Learn 接口 XGBoost 随机森林Random Forest训练完全指南从原生 API 到 Scikit-Learn 接口【免费下载链接】xgboostScalable, Portable and Distributed Gradient Boosting (GBDT, GBRT or GBM) Library, for Python, R, Java, Scala, C and more. Runs on single machine, Hadoop, Spark, Dask, Flink and DataFlow项目地址: https://gitcode.com/gh_mirrors/xg/xgboostXGBoost 不仅是最流行的梯度提升Gradient Boosting库其底层模型表示同样可以直接用于训练独立的随机森林Random Forest。本文基于 doc/tutorials/rf.rst 展开系统讲解如何用 XGBoost 原生 API 与 Scikit-Learn 风格 API 训练随机森林、如何设置num_parallel_tree与num_boost_round等关键参数、随机森林与梯度提升的混合训练策略以及此类实现相对传统随机森林的两大差异。读完本文你将掌握一套可直接落地运行的随机森林训练配置并理解其底层实现原理。随机森林与梯度提升同一模型表示不同训练算法XGBoost 通常被用于训练梯度提升决策树GBDT及其他梯度提升模型但随机森林与梯度提升决策树共享相同的模型表示与推理路径都是若干棵回归树/分类树构成的加法模型两者的区别仅在于训练算法本身梯度提升逐轮串行地训练新树每棵树都去拟合前面所有树的残差更准确地说是损失函数的负梯度与 Hessian 信息通过eta学习率控制每棵树的贡献逐步逼近目标。随机森林一次性并行地训练num_parallel_tree棵树每棵树在行、列两个维度上做随机采样树与树之间相互独立最终结果取平均回归或投票/概率平均分类。XGBoost 从早期版本开始就提供训练随机森林的原生 APIScikit-Learn 风格的估计器同样可以通过设置合适参数来训练随机森林。需要特别注意的是专门封装的XGBRFClassifier与XGBRFRegressor包装类自 3.4.0 起已被标记为弃用详见下文。原生 API 训练独立随机森林必须设置的参数清单使用xgb.train()训练独立随机森林时以下参数必须正确设置摘自 doc/tutorials/rf.rst参数要求说明booster设置为gbtree我们训练的是树模型森林由于gbtree本身是默认值此参数通常无需显式写出subsample必须小于 1开启训练样本行的随机选择colsample_by*其一必须小于 1开启列特征的随机选择。通常设置colsample_bynode即在每个树节点分裂时随机采样特征num_parallel_tree设置为森林规模每轮 boosting 中并行训练的树的数量即随机森林的大小num_boost_round设置为 1阻止 XGBoost 对多个随机森林进行提升注意它是train()的关键字参数不属于参数字典eta别名learning_rate训练随机森林回归时设为 1学习率别名learning_raterandom_state按需设置用于为随机数生成器播种保证结果可复现其余参数按梯度提升的常规方式来设置例如回归任务objective通常为reg:squarederror分类任务为binary:logisticlambda即reg_lambdaL2 正则按期望的正则化强度设置等。参数底层语义源码佐证这些采样参数在底层树参数结构中均有明确定义见 src/tree/param.hsubsample取值范围[0.0, 1.0]默认1.0语义为训练实例的行采样比例src/tree/param.h第 133–136 行colsample_bynode取值范围[0.0, 1.0]默认1.0语义为在每个节点分裂处重新采样的列比例第 145–148 行colsample_bylevel默认1.0在每一层重新采样的列比例第 149–152 行colsample_bytree默认1.0在每棵树构建时采样的列比例第 153–156 行learning_rate与别名eta的绑定关系定义于第 82 行与第 182 行DMLC_DECLARE_ALIAS(learning_rate, eta)。在训练执行路径上src/gbm/gbtree.cc 的InitNewTrees会按model_.param.num_parallel_tree循环创建这一轮的所有树第 283 行而BoostNewTrees中有一处对随机森林至关重要的逻辑第 336–343 行学习率会按本轮并行树的数量缩放即learning_rate / new_trees.size()树训练完成后再恢复原值。这意味着当num_parallel_tree 100时即使eta保持默认的 0.3每一层的有效学习率也会被除以 100因此文档强调训练随机森林回归时要把eta设为 1否则每棵树的贡献会被过度稀释。可复制的完整示例GPU下面是原文档给出的、在 GPU 上训练二分类随机森林的参数字典与训练调用import xgboost as xgb params { colsample_bynode: 0.8, learning_rate: 1, max_depth: 5, num_parallel_tree: 100, objective: binary:logistic, subsample: 0.8, tree_method: hist, device: cuda, } dmatrix xgb.DMatrix(X_train, labely_train) bst xgb.train(params, dmatrix, num_boost_round1)要点回顾colsample_bynode0.8与subsample0.8分别开启列、行随机采样num_parallel_tree100指定森林规模为 100 棵树num_boost_round1保证只训练一个随机森林不做提升tree_methodhist使用直方图近似算法CPU 上也可配合devicecpu或省略device训练完成后bst即为常规的 Booster 对象预测接口与梯度提升模型完全一致。随机森林与梯度提升的混合训练如果同时满足num_parallel_tree 1且num_boost_round 1XGBoost 将采用随机森林 梯度提升的组合策略共执行num_boost_round轮提升每一轮都训练一个由num_parallel_tree棵树组成的随机森林。若未启用早停最终模型将包含num_parallel_tree * num_boost_round棵树。这种模式有时被用于以随机森林为基学习器的梯度提升如用 RF 作为 GBDT 的单层基模型以增强多样性也是理解XGBRF*包装类内部行为的关键文档指出那些包装类本质上是套在 boosting 接口之上的薄封装并非传统的随机森林实现因此不支持早停等功能。Scikit-Learn 风格 API 训练随机森林XGBRFClassifier/XGBRFRegressor已弃用3.4.0原文档明确标注.. deprecated:: 3.4.0XGBRFClassifier、XGBRFRegressor及其 Dask 版本DaskXGBRFClassifier、DaskXGBRFRegressor自 3.4.0 起弃用并将在未来版本中移除。原因有二它们是 boosting 接口之上的薄封装而非常规的随机森林实现它们不支持早停early stopping等特性。在源码 python-package/xgboost/sklearn.py 中可以看到_warn_rf_deprecated第 141–152 行会发出FutureWarning提示用户改用原生 API设置num_parallel_tree配合num_boost_round1或在XGBClassifier/XGBRegressor上同时传入num_parallel_tree与n_estimators1或直接使用专用实现如sklearn.ensemble.RandomForestClassifier。XGBRFClassifier.__init__还会调用_check_rf_callback来校验早停相关回调第 1995 行。Dask 侧对应类位于 python-package/xgboost/dask/init.py第 2108、2175 行同样发出弃用告警。顺带一提XGBRFClassifier的默认超参数learning_rate1.0、subsample0.8、colsample_bynode0.8、reg_lambda1e-5正是为随机森林场景调好的而它的get_xgb_params()会把num_parallel_tree设置为n_estimators的值第 1997–1999 行印证了RF 大小由n_estimators驱动的设计。推荐做法在标准估计器上配置随机森林XGBClassifier与XGBRegressor可以通过设置与原生 API 相同的参数来训练随机森林。由于对这两个估计器而言n_estimators表示提升轮数因此需要num_parallel_tree指定森林大小n_estimators设为 1阻止对多个随机森林做提升learning_rate设为 1subsample与某个colsample_by*参数设为小于 1 的值。原文档给出了一个配合交叉验证使用的随机森林回归示例import xgboost as xgb from sklearn.model_selection import KFold # 假设已有数据 X, y ... kf KFold(n_splits2) for train_index, test_index in kf.split(X, y): xgb_model xgb.XGBRegressor( n_estimators1, num_parallel_tree100, learning_rate1, subsample0.8, colsample_bynode0.8, random_state42, ).fit(X[train_index], y[train_index])每次折叠都会训练一个包含 100 棵并行树、在行/列维度各自 80% 采样的随机森林回归器n_estimators1确保只训练一层森林。分类场景只需把XGBRegressor换成XGBClassifier并相应调整objective默认即binary:logistic。Caveats与传统随机森林实现的两点关键差异原文档最后明确指出使用 XGBoost 训练随机森林时需要注意的两个技术细节二阶近似XGBoost 使用目标函数的二阶近似泰勒展开即梯度和 Hessian来指导分裂与叶子取值这可能导致训练结果与直接使用目标函数精确值的传统随机森林实现存在差异。因此不应期望 XGBoost 版的随机森林与 sklearn 等实现的随机森林输出逐位一致这是算法层面的正常差异。无放回行采样XGBoost 在对训练样本行做子采样时不进行放回替换即每个样本在子采样集中要么出现 0 次、要么出现 1 次。这与经典随机森林有放回抽样bootstrap的做法不同对样本量较小或希望保留 bootstrap 特性的场景需要特别留意。这一点与 src/tree/hist/sampler.cc 中基于均匀分布的采样逻辑第 67 行相吻合——子采样通过随机阈值筛选样本实现而非放回抽样。小结XGBoost 提供了一条与常规梯度提升共用基础设施的随机森林训练路径原生 API 下设置subsample、某个colsample_by*、num_parallel_tree为森林规模、num_boost_round1必要时learning_rate1即可Scikit-Learn 风格接口下把num_parallel_tree与n_estimators1组合使用。二者训练出的模型与 GBDT 模型拥有相同的 Booster 表示与推理接口可直接用于预测、模型序列化save_model/load_model与后续增量更新。自 3.4.0 起请勿再使用XGBRFClassifier/XGBRFRegressor等专用包装类推荐按本文给出的两种标准方式配置。【免费下载链接】xgboostScalable, Portable and Distributed Gradient Boosting (GBDT, GBRT or GBM) Library, for Python, R, Java, Scala, C and more. Runs on single machine, Hadoop, Spark, Dask, Flink and DataFlow项目地址: https://gitcode.com/gh_mirrors/xg/xgboost创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表