可索引元素的处理
XGBoost 中有许多功能涉及可数集中的可索引元素,例如模型中的提升轮次/迭代/树(可以通过数字引用)、类别、分类特征中的类别/级别等。
XGBoost 用 C++ 编写,使用基于 0 的索引,并认为范围/序列包含左端但不包含右端——例如,范围 (0, 3) 将包括前三个元素,编号为 0、1 和 2。
Python 接口使用相同的逻辑,因为这也是 Python 中索引的工作方式,但其他语言(如 R)具有不同的逻辑。在 R 中,索引是基于 1 的,并且范围/序列包含两端——例如,要引用序列中的前三个元素,间隔将写为 (1, 3),元素编号为 1、2 和 3。
为了提供更符合 R 习惯的接口,XGBoost 调整其面向用户的 R 接口以遵循此约定和类似的 R 约定,但内部需要将所有这些数字转换为 C 接口使用的格式。模型旨在在其他具有不同索引逻辑的接口中序列化和加载,这使得问题更加复杂。
R 接口中进行了以下调整
DMatrix 的切片方法,它接受一个整数数组,通过从每个元素中减去 1 转换为基于 0 的索引。请注意,这是在 R 的 C 级包装函数中完成的,与所有其他在传递给 C 之前在 R 中完成的转换不同。
Booster 的切片方法接受由起始、结束和步长定义的序列。R 接口旨在与 R 的
seq
从用户的角度来看以相同的方式工作,因此它总是通过减去一来调整左端,并且根据步长是否精确地结束或不结束在右端,它还会调整右端以在 C 索引中不包含。predict
中的参数iterationrange
也被设置为与 R 的seq
以相同的方式行为。由于它没有步长,因此只需减去 1 即可调整左端。best_iteration
,根据上下文,可以存储为 C 级助推器属性和 R 属性。由于 C 级属性在接口之间共享并用于预测方法,为了提高兼容性,它将此 C 级属性保留为基于 0 的索引,但 R 属性(如果存在)将调整为基于 1 的索引。请注意,R 和其他接口中的predict
方法将仅查看 C 级属性。对迭代次数或提升轮次的其他引用,例如在打印指标或保存模型快照时,也遵循基于 1 的索引。这些其他引用完全用 R 编码,因为 C 级函数不处理此类功能。
终端叶/节点编号以基于 0 的索引返回,就像它们来自 C 接口一样。
绘图中的树编号遵循基于 1 的索引。请注意,这些仅在通过 R 接口自身处理 DiagrammeR 对象生成这些绘图时显示,但在使用 C 级 GraphViz“dot”格式生成器进行绘图时则不显示。
生成特征重要性、JSON、树到表和 SHAP 时的特征编号均遵循基于 0 的索引。
分类特征在 R 中定义为
factor
类型,它使用基于 1 的索引进行编码。当分类特征作为 Rfactor
类型传递时,会自动转换为基于 0 的索引,但如果用户希望手动提供已编码的整数作为分类特征,则这些整数需要已经是基于 0 的编码。输出(例如绘图、JSON 和树到表)中的分类级别(类别)也使用基于 0 的索引引用,无论它们是以整数形式还是以
factor
类型列的形式进入模型。DMatrices 的分类标签不进行任何额外处理——用户必须提供基于 0 编码的标签。
当使用线性系数历史回调时,检索特定于类别的系数的函数接受一个类索引参数,该参数也不进行任何转换(即用户必须传递一个基于 0 的索引),以与标签逻辑匹配——也就是说,相同的类索引将引用在 DMatrix
label
字段中用该数字编码的类。
R 接口中包含可索引元素的新增功能应注意这些约定,并尽量模仿 R 的行为。