从以前的 XGBoost 版本迁移代码

XGBoost 的 R 语言绑定在 1.x 和 2.x 版本之间发生了重大破坏性变更。以前使用旧版 XGBoost 的 R 代码可能需要修改才能在新版本中使用。本指南概述了主要区别

  • 函数 xgboost()
    • 以前,此函数接受参数 ‘data’ 和 ‘label’,现在已参照其他流行的 R 包重命名为 ‘x’ 和 ‘y’。

    • 以前,参数 ‘data’(现在是 ‘x’)必须作为 XGBoost ‘DMatrix’ 或 R 矩阵传递。现在此参数允许 R 的 data.frames、矩阵以及 ‘Matrix’ 包中的稀疏矩阵,但不允许 XGBoost 自己的 DMatrices。当传递 data.frame 时,分类列将根据列的类型自动推断。

    • 以前,‘label’ 数据(现在是 ‘y’)必须以 XGBoost 核心库使用的格式传递给 xgboost(),这意味着:二元变量必须编码为 0/1,生存目标的边界必须作为不同的参数传递等等。在最新版本中,现在 ‘y’ 不再需要手动预先编码:它应该作为对应类别的 R 对象传递,就像 base R 和核心 R 包中用于相应 XGBoost 目标的回归函数一样——例如,分类问题应该传递一个 factor,生存问题传递一个 Surv,回归问题传递一个数值向量,等等。xgboost() 尚不支持排序学习,但 xgb.train 支持。

    • 以前,xgboost() 接受 params 参数和 ... 下的命名参数。现在所有训练参数都应作为命名参数传递,并且所有接受的参数都是带有包内文档的显式函数参数。一些参数不允许使用,因为它们是从其余数据自动确定的,例如多分类问题中的类别数量是从 ‘y’ 自动确定的。此外,具有同义词或接受不同可能参数(例如 “eta” 和 “learning_rate”)的参数现在只接受其更具描述性的形式(因此不接受 “eta”,但接受 “learning_rate”)。

    • 此函数 xgboost() 生成的模型现在返回时具有不同的类 “xgboost”,它是 “xgb.Booster” 的子类,但包含更多元数据和一个具有不同默认值的 predict 方法。

    • 此函数 xgboost() 现在仅用于交互式使用。对于希望集成 XGBoost 包的包开发者,强烈建议改用 xgb.train,这是一个更低级别的函数,它密切模仿 Python 包中的同名函数,并且旨在更少受到破坏性变更的影响。

  • 函数 xgb.train()
    • 以前,xgb.train() 允许在 “params” 列表下和 ... 下的命名参数中指定参数。现在,所有训练参数都应在 params 下传递。

    • 为了更容易发现和传递参数,现在有一个 xgb.params 函数,它可以生成一个列表传递给 params 参数。xgb.params 只是一个带有命名参数的函数,它列出了 xgb.train 接受的所有内容,并提供所有参数的包内文档,返回一个简单的命名列表。

    • 应由 DMatrix 构造函数使用的参数必须直接传递给 xgb.DMatrix (例如,用于分类特征或特征名称的参数)。

    • 一些参数已被重命名(例如,以前的 ‘watchlist’ 现在是 ‘evals’,与 Python 包一致)。

    • 传递给 xgb.train 的回调函数的格式已基本重写。有关详细信息,请参阅 xgb.Callback 的文档。

  • 函数 xgb.DMatrix()
    • 此函数现在接受 ‘data.frame’ 输入,并根据其类型确定哪些特征是分类的——任何类型为 ‘factor’ 或 ‘character’ 的都将被视为分类。请注意,当向 ‘predict’ 方法传递数据时,‘factor’ 变量必须具有相同的编码(即相同的 levels),因为 XGBoost 不会为您重新编码它们。

    • 以前,一些参数(例如特征类型)必须作为列表在参数 ‘info’ 下传递,而现在它们都直接作为 ‘xgb.DMatrix’ 的函数参数传递。

    • 现在有其他类型的 DMatrix 构造函数,可能更适合某些使用场景——例如,有 ‘xgb.QuantileDMatrix’,它会直接对特征进行量化(从而避免冗余拷贝并减少内存消耗),用于 XGBoost 中的直方图方法(但请注意,量化后的 DMatrices 不能与 ‘exact’ 排序索引方法一起使用)。

    • 请注意,‘label’ 的数据仍然需要以 XGBoost 核心库接受的格式进行编码——例如,分类目标应该接收编码为零和一的 ‘label’ 数据。

    • 已弃用从文本文件创建 DMatrices 的方法。

  • 函数 xgb.cv()
    • 以前,此函数像旧版本 xgboost() 一样接受 ‘data’ 和 ‘label’,现在它只接受 xgb.DMatrix 对象。

    • 此函数的范围已扩展,支持 XGBoost 提供的更多功能,例如生存分析和排序学习目标。

  • 方法 predict
    • 现在有两种预测方法,根据模型是通过 xgboost() 还是 通过 xgb.train() 生成的,它们具有不同的默认参数。函数 xgboost() 更倾向于交互式使用,因此对此类对象(类为 “xgboost”)的 ‘predict’ 方法的默认设置将执行更多数据验证,例如检查列名是否匹配并在不匹配时重新排序。通过 xgb.train() 创建的模型(类为 “xgb.Booster”)的 ‘predict’ 方法具有与之前相同的默认设置,因此例如,在默认行为下它不会重新排序列以匹配名称。

    • 类为 “xgboost” 的对象(由 xgboost() 生成,而非由 xgb.train() 生成)的 ‘predict’ 方法现在可以通过参数 type 控制预测的类型,类似于 base R 的 ‘stats’ 模块中的 ‘predict’ 方法——例如,现在可以执行 predict(model, type="class");而对于 “xgb.Booster” 对象(由 xgb.train() 生成)的 ‘predict’ 方法,就像以前一样,通过诸如 outputmargin 之类的独立参数来控制这些。

    • 以前,使用树的子集进行预测时使用基于 0 的索引和模仿 Python 范围的范围语法,而现在它们使用 R 中常见的基于 1 的索引,并且其范围行为与 R 的 seq 函数匹配。请注意,“使用所有树” 和 “使用直到早停标准的树” 的语法已更改(详情请参阅文档)。

  • Booster 对象
    • 这些对象的结构已修改——现在它们表示为一个简单的 R “ALTLIST”(一种特殊的 ‘list’ 对象),带有附加属性。

    • 现在这些对象不能通过向其添加更多字段来修改,但可以作为属性添加其元数据。

    • 这些对象区分两种类型的属性

      • R 端属性(可以通过 R 函数 attributes(model)attributes(model)$field <- val 访问和修改),允许任意对象。许多属性由模型构建函数自动添加,例如评估日志(一个 data.table 包含每次迭代计算的指标),以前这些是模型字段。

      • C 级属性,只允许符合 JSON 的数据,并且可以通过 函数 xgb.attributes(model) 访问和设置。这些 C 级属性可以在不同的 XGBoost 接口中通过序列化模型共享,而 R 级属性是 R 接口特有的。XGBoost 语言绑定中一些标准属性,例如最佳迭代次数,保留为 C 属性。

    • 以前,刚从磁盘格式反序列化的模型需要在其上调用方法 ‘xgb.Booster.complete’ 来完成完整的反序列化过程才能使用,否则会在第一次调用 ‘predict’ 时自动调用此方法。现在序列化处理得更优雅,并且不涉及额外的函数/方法——也就是说,如果使用 saveRDS() 将模型保存到磁盘,然后使用 readRDS() 读回,模型将立即完全加载,无需对其调用额外的额外方法。

其他建议

默认情况下,XGBoost 可能会识别出某些参数已从以前的版本中移除或重命名,并且仍然接受与以前相同的函数调用(使用已重命名或移除的参数),但会在此过程中发出弃用警告,以突出显示这些更改。

这些行为将在未来版本中移除,目前返回弃用警告的函数调用将来将不再工作,因此为了确保调用 XGBoost 的代码能够继续工作,应确保它不发出弃用警告。

可选地,可以通过选项 “xgboost.strict_mode” 将这些弃用警告转换为错误(同时保留其他类型的警告仍为警告)——示例:.. code-block:: r

options("xgboost.strict_mode" = TRUE)

它也可以通过环境变量 XGB_STRICT_MODE=1 控制,该变量优先于 R 选项——例如:.. code-block:: r

Sys.setenv("XGB_STRICT_MODE" = "1")

强烈建议包开发者在其包检查期间启用此选项,以确保与 XGBoost 更好的兼容性。