ARTICLE DETAIL

资讯详情

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

XGBoost 多分类实战指南:基于 UCI Dermatology 数据集的 multi:softmax 与 multi:softprob 详解

XGBoost 多分类实战指南:基于 UCI Dermatology 数据集的 multi:softmax 与 multi:softprob 详解 XGBoost 多分类实战指南基于 UCI Dermatology 数据集的 multi:softmax 与 multi:softprob 详解【免费下载链接】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 提供了multi:softmax与multi:softprob两种多分类目标函数用于处理类别数大于 2 的分类任务。本文以仓库内 demo/multiclass_classification 目录下的官方演示为核心骨架结合 UCI Dermatology皮肤病理学数据集完整讲解数据预处理、参数配置、训练与预测的 Python 与 R 双语言实现并从 multiclass_obj.cc 源码层面剖析 softmax 梯度的计算与预测输出变换的底层原理帮助读者掌握 XGBoost 多分类的标准工作流与踩坑点。一、Demo 概览一份可直接运行的官方多分类样例在 XGBoost 仓库中多分类演示位于 demo/multiclass_classification其官方说明见 README.md。该目录包含四个文件文件作用README.md演示说明基于 UCI Dermatology 数据集完成多分类任务runexp.sh一键脚本自动下载数据并调用 Python 训练脚本train.pyPython 版训练与评估脚本train.RR 版等价实现使用 data.table xgboost运行前提需要先将 XGBoost Python 模块安装好或在 python-package 目录下完成本地构建并加入PYTHONPATHREADME 中的 Make sure you make xgboost python module in ../../python 即指此意。当前版本的官方安装方式更推荐通过pip install xgboost安装发布版或参考 doc/install.rst 从源码构建。执行整个演示只需一条命令cd demo/multiclass_classification ./runexp.sh脚本 runexp.sh 的逻辑非常直白若本地不存在dermatology.data则用wget从 UCI 下载该数据集随后调用python train.py完成训练与评估。如果下载失败可手动下载数据集放到当前目录后重跑脚本。二、数据集与预处理理解 Dermatology 数据的特殊之处UCI Dermatology 数据集包含 366 条样本、34 个特征33 个数值特征 1 个年龄特征其中部分特征含缺失值目标变量是 6 种皮肤病的类别标签。该数据集有两个经典坑正是 train.py 预处理部分要解决的缺失值编码为?字符串数据中?表示缺失Python 端通过np.loadtxt的converters参数在读取时将其转换为数值data np.loadtxt(./dermatology.data, delimiter,, converters{33: lambda x:int(x ?), 34: lambda x:int(x) - 1})这里converters{33: ...}处理第 34 列索引 33的年龄缺失值{34: ...}将第 35 列索引 34即标签列的类别编号从 1~6 转换为 0~5。标签必须从 0 开始连续编号XGBoost 多分类要求标签为0到num_class - 1的离散整数。源码 multiclass_obj.cc 在训练首轮会调用MulticlassValidationKernel校验标签不满足会抛出SoftmaxMultiClassObj: label must be discrete values in the range of [0, num_class).R 版在 train.R 中做了等价处理用fread读取 CSV将第 34 列的?转为 0将第 35 列标签整体减 1df[, :(V34 as.integer(ifelse(V34 ?, 0L, V34)), V35 V35 - 1L)]数据切分Python 端按 7:3 顺序切分前 70% 训练、后 30% 测试标签列取第 35 列索引 34sz data.shape train data[:int(sz[0] * 0.7), :] test data[int(sz[0] * 0.7):, :] train_X train[:, :33] train_Y train[:, 34] test_X test[:, :33] test_Y test[:, 34]R 端则使用随机采样sample无放回抽取 70% 作为训练集。注意随机切分每次结果不同误差率会有小幅波动属正常现象。三、核心参数配置多分类目标函数与超参数3.1 两种多分类目标multi:softmax与multi:softprob官方参数文档 doc/parameter.rst 对两者的定义multi:softmax使用 softmax 目标做多分类直接输出类别索引即每个样本的预测类别编号。使用它必须同时设置num_class。multi:softprob与 softmax 相同但输出ndata * nclass长度的向量预测概率可 reshape 成ndata * nclass矩阵其中每个元素是该样本属于各类别的概率。从源码看两者本质上是同一个目标函数的两个注册实例。multiclass_obj.cc 中XGBOOST_REGISTER_OBJECTIVE(SoftmaxMultiClass, multi:softmax) .describe(Softmax for multi-class classification, output class index.) .set_body([]() { return new SoftmaxMultiClassObj(false); }); XGBOOST_REGISTER_OBJECTIVE(SoftprobMultiClass, multi:softprob) .describe(Softmax for multi-class classification, output probability distribution.) .set_body([]() { return new SoftmaxMultiClassObj(true); });二者的唯一区别是构造参数output_prob_multi:softmax为false输出类别索引multi:softprob为true输出概率分布。SaveConfig中也据此写回目标名见 multiclass_obj.cc。3.2 Demo 中的参数清单train.py 的配置如下param {} param[objective] multi:softmax # 使用 softmax 多分类 param[eta] 0.1 # 学习率/步长收缩 param[max_depth] 6 # 树最大深度 param[nthread] 4 # 并行线程数 param[num_class] 6 # 类别总数必须与标签范围一致R 版 train.R 的等价配置params - list( objective multi:softmax, num_class 6, max_depth 6, nthread 4, eta 0.1 )各参数要点num_class必填。定义输出类别数对应源码SoftmaxMultiClassParam中声明见 multiclass_param.h其下界为 1DMLC_DECLARE_FIELD(num_class).set_lower_bound(1).describe( Number of output class in the multi-class classification.);训练时GetGradient会校验preds.Size() n_classes * info.labels.Size()即预测向量长度必须等于样本数 × 类别数multiclass_obj.cc。etalearning_rate学习率默认 0.3demo 取 0.1 以获得更稳的收敛。max_depth单棵树最大深度默认 6。nthread线程数默认取系统核数。此外自 XGBoost 2.0 起新增multi_strategy参数见 doc/parameter.rst可选one_output_per_tree默认每个类别一棵树或multi_output_tree多目标树后者可加速训练详见 doc/tutorials/multioutput.rst。3.3 默认评估指标SoftmaxMultiClassObj的默认评估指标为mlogloss多分类对数损失见 multiclass_obj.cc。训练时的watchlist会同时打印训练集与测试集上的该指标便于观察过拟合趋势。四、训练与 watchlist 观测两种目标共用同一套训练流程watchlist [(xg_train, train), (xg_test, test)] num_round 5 bst xgb.train(param, xg_train, num_round, watchlist)DMatrix是 XGBoost 的核心数据接口xgb.DMatrix(train_X, labeltrain_Y)封装特征矩阵与标签对应 Python 包 python-package/xgboost/data.py 中的DMatrix类。watchlist用于在每轮迭代后同时评估训练集与验证集训练日志会输出类似[0] train-mlogloss:... test-mlogloss:...的信息用于监控收敛与过拟合。num_round 5仅为演示而设的较小轮数实际应用中建议增大迭代轮数并配合早停early_stopping_rounds见 python-package/xgboost/callback.py 与 R 包 R-package/R/callbacks.R。R 端训练等价写法bst - xgb.train( params params, data xg_train, watchlist watchlist, nrounds 5 )五、预测与评估软标签与硬标签两种范式5.1multi:softmax直接输出类别索引pred bst.predict(xg_test) error_rate np.sum(pred ! test_Y) / test_Y.shape[0] print(Test error using softmax {}.format(error_rate))预测结果是一维数组每个元素为预测的类别编号0~5直接与test_Y比较即可计算误分类率。5.2multi:softprob输出概率并取 argmaxparam[objective] multi:softprob bst xgb.train(param, xg_train, num_round, watchlist) # 输出是 1D 数组需 reshape 为 (ndata, nclass) pred_prob bst.predict(xg_test).reshape(test_Y.shape[0], 6) pred_label np.argmax(pred_prob, axis1) error_rate np.sum(pred_label ! test_Y) / test_Y.shape[0] print(Test error using softprob {}.format(error_rate))multi:softprob的原始输出是一维向量ndata * nclass必须 reshape 成(样本数, 类别数)后再按行取argmax得到预测类别。源码中的变换逻辑见 multiclass_obj.cc 的MulticlassTransformCpuprobability true时对每个样本的 nclass 维预测向量做softmaxcommon::Softmax得到概率分布probability false时用common::FindMaxIndex找到每行最大值的索引输出类别编号。5.3 底层梯度原理softmax 交叉熵的解析解两种目标的训练过程完全相同因为它们使用同一个MulticlassGradientCpu计算一阶、二阶梯度multiclass_obj.cc。对每个样本、每个类别 k先计算数值稳定的 softmax 概率wmax max_k(point(k)); // 数值稳定性减去最大值防溢出 wsum sum_k exp(point(k) - wmax); probability exp(point(k) - wmax) / wsum;随后得到梯度与 softmax 交叉熵损失的一阶/二阶导数完全对应grad (label k) ? probability - 1.0f : probability; // 一阶梯度 hess max(2.0f * probability * (1.0f - probability) * weight, 1e-16f); // 二阶梯度其中hess下限被钳制在1e-16以防数值除零。正是这套梯度使得每个类别对应一棵独立的回归树每轮迭代生成num_class棵树pred_leaf输出维度也与之对应见 doc/prediction.rst。R 端 softprob 预测与评估的等价写法注意 R 中矩阵按列填充需byrow TRUEpred_prob - predict(bst, xg_test) pred_mat - matrix(pred_prob, ncol 6, byrow TRUE) pred_label - apply(pred_mat, 1, which.max) - 1L error_rate - sum(pred_label ! test_y) / length(test_y) print(paste(Test error using softprob , error_rate))5.4 输出形状速查目标函数predict 原始输出含义取类别方式multi:softmax一维(ndata,)每样本的类别索引直接用multi:softprob一维(ndata*nclass,)展平的类别概率reshape 后argmax需注意 Python 中若设置strict_shapeTruemulti:softprob会输出二维数组(ndata, nclass)R 包在strict_shape下返回 column-major 的 array维度顺序与 numpy 相反详见 doc/prediction.rst 与 doc/prediction.rst。六、扩展讨论从 Demo 到生产实战6.1 其他接口中的多分类用法multi:softprob是更推荐的目标它保留概率信息可用于 ROC/AUC 评估、阈值调整与不确定性分析。官方 Spark 教程 doc/jvm/xgboost4j_spark_tutorial.rst 中同样使用objective - multi:softprob, num_class - 3的组合sklearn 接口的XGBClassifier也默认使用该目标并自动推断num_class见 python-package/xgboost/sklearn.py。需注意多分类场景下 AUC 指标要求使用multi:softprob因为multi:softmax不输出概率doc/parameter.rst。6.2 测试佐证仓库测试 tests/python/test_basic.py 中亦有{max_depth: 2, eta: 1, num_class: 2}这类多分类参数组合的回归验证模型导出/切片测试 tests/python/test_basic_models.py 则印证了每轮生成num_parallel_tree * num_classes棵树的树数量规律——理解这一点有助于掌握pred_leaf输出维度与模型切片的正确性。6.3 常见踩坑清单标签未归零标签必须为0 ~ num_class-1否则训练直接报错multiclass_obj.cc。忘记设置num_class缺省值为 1会导致预测维度不匹配。multi:softprob输出形状误解默认一维展平必须 reshape 为(样本数, 类别数)。多标签multi-label不支持源码明确CHECK_LE(info.labels.Shape(1), 1)多标签分类暂不支持multiclass_obj.cc。七、小结通过 demo/multiclass_classification 这份官方演示读者可以完整走通 XGBoost 多分类的五个环节数据清洗与标签归零 →DMatrix封装 →multi:softmax/multi:softprob目标与num_class配置 →xgb.trainwatchlist训练监控 → 预测与误分类率评估。结合 multiclass_obj.cc 的源码可以看到两种目标共享同一套 softmax 交叉熵梯度实现仅在预测输出变换上分叉为类别索引与概率分布两种形式。将这套流程迁移到真实业务时建议使用multi:softprob保留概率、增大迭代轮数并配合早停再结合 doc/parameter.rst 与 doc/prediction.rst 深入调参。【免费下载链接】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),仅供参考
返回列表