XGBoost4J-Spark 教程

XGBoost4J-Spark 是一个旨在通过将 XGBoost 适配到 Apache Spark 的 MLLIB 框架来无缝集成 XGBoost 和 Apache Spark 的项目。通过这种集成,用户不仅可以使用 XGBoost 的高性能算法实现,还可以利用 Spark 强大的数据处理引擎进行

  • 特征工程:特征提取、转换、降维和选择等。

  • 管道:构建、评估和调优机器学习管道

  • 持久化:持久化和加载机器学习模型,甚至整个管道

本教程将介绍使用 XGBoost4J-Spark 构建机器学习管道的端到端过程。我们将讨论

  • 使用 Spark 预处理数据以适应 XGBoost4J-Spark 的数据接口

  • 使用 XGBoost4J-Spark 训练 XGBoost 模型

  • 使用 Spark 部署 XGBoost 模型(预测)

  • 使用 XGBoost4J-Spark 构建机器学习管道

  • 在生产环境中运行 XGBoost4J-Spark

使用 XGBoost4J-Spark 构建 ML 应用程序

参考 XGBoost4J-Spark 依赖

在开始了解如何使用 XGBoost4J-Spark 之前,您应该首先查阅 从 Maven 仓库安装,以便将 XGBoost4J-Spark 添加为项目的依赖项。我们提供稳定版本和快照版本。

注意

XGBoost4J-Spark 需要 Apache Spark 3.0+

XGBoost4J-Spark 现在需要 Apache Spark 3.0+。最新版本的 XGBoost4J-Spark 广泛使用 org.apache.spark.ml.param.shared 的功能,以提供与 Spark MLLIB 框架的紧密集成,而这些功能在早期版本的 Spark 中并未完全提供。

此外,请务必直接从 Apache 网站安装 Spark。上游 XGBoost 不保证与第三方 Spark 发行版(例如 Cloudera Spark)兼容。请咨询相应的第三方以获取其 XGBoost 发行版。

数据准备

如前所述,XGBoost4J-Spark 无缝集成了 Spark 和 XGBoost。这种集成使用户能够利用方便强大的数据处理框架 Spark 对训练/测试数据集应用各种类型的转换。

在本节中,我们以 Iris 数据集为例,展示如何使用 Spark 转换原始数据集并使其适应 XGBoost 的数据接口。

Iris 数据集以 CSV 格式提供。每个实例包含 4 个特征:“萼片长度”、“萼片宽度”、“花瓣长度”和“花瓣宽度”。此外,它还包含“类别”列,这实际上是具有三个可能值(“山鸢尾”、“变色鸢尾”和“弗吉尼亚鸢尾”)的标签。

使用 Spark 内置阅读器读取数据集

数据转换的第一件事是将数据集作为 Spark 的结构化数据抽象 DataFrame 加载。

import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.types.{DoubleType, StringType, StructField, StructType}

val spark = SparkSession.builder().getOrCreate()
val schema = new StructType(Array(
  StructField("sepal length", DoubleType, true),
  StructField("sepal width", DoubleType, true),
  StructField("petal length", DoubleType, true),
  StructField("petal width", DoubleType, true),
  StructField("class", StringType, true)))
val rawInput = spark.read.schema(schema).csv("input_path")

在第一行,我们创建了一个 SparkSession 实例,它是任何处理 DataFrame 的 Spark 程序的入口。 schema 变量定义了包装 Iris 数据的 DataFrame 的模式。通过这个显式设置的模式,我们可以定义列名及其类型;否则,列名将是 Spark 派生的默认名称,例如 _col0 等。最后,我们可以使用 Spark 内置的 CSV 阅读器将 Iris CSV 文件加载为名为 rawInput 的 DataFrame。

Spark 还包含许多用于其他格式的内置阅读器。最新版本的 Spark 支持 CSV、JSON、Parquet 和 LIBSVM。

转换原始 Iris 数据集

为了使 Iris 数据集可被 XGBoost 识别,我们需要

  1. 将字符串类型标签,即“class”,转换为双精度类型标签。

  2. 将特征列组合成一个向量,以适应 Spark ML 框架的数据接口。

要将字符串类型标签转换为双精度类型,我们可以使用 Spark 的内置特征转换器 StringIndexer

import org.apache.spark.ml.feature.StringIndexer
val stringIndexer = new StringIndexer().
  setInputCol("class").
  setOutputCol("classIndex").
  fit(rawInput)
val labelTransformed = stringIndexer.transform(rawInput).drop("class")

使用新创建的 StringIndexer 实例

  1. 我们设置输入列,即包含字符串类型标签的列。

  2. 我们设置输出列,即包含双精度类型标签的列。

  3. 然后我们使用输入 DataFrame rawInput 对 StringIndex 进行 fit 操作,以便 Spark 内部可以获取总不同值数量等信息。

现在我们有了一个 StringIndexer,它已准备好应用于我们的输入 DataFrame。为了执行 StringIndexer 的转换逻辑,我们对输入 DataFrame rawInput 进行 transform 操作,并且为了保持 DataFrame 简洁,我们删除了“class”列,只保留了特征列和转换后的双精度类型标签列(在上述代码片段的最后一行)。

fittransform 是 MLLIB 中的两个关键操作。基本上,fit 产生一个“转换器”,例如 StringIndexer,每个转换器都对 DataFrame 应用 transform 方法来添加包含转换后的特征/标签或预测结果等的新列。要了解有关 fittransform 的更多信息,您可以在 此处找到更多详细信息。

类似地,我们可以使用另一个转换器 VectorAssembler 将特征列“sepal length”、“sepal width”、“petal length”和“petal width”组合成一个向量。

import org.apache.spark.ml.feature.VectorAssembler
val vectorAssembler = new VectorAssembler().
  setInputCols(Array("sepal length", "sepal width", "petal length", "petal width")).
  setOutputCol("features")
val xgbInput = vectorAssembler.transform(labelTransformed).select("features", "classIndex")

现在,我们有一个 DataFrame,它只包含两列:“features”列,其中包含向量表示的“萼片长度”、“萼片宽度”、“花瓣长度”和“花瓣宽度”,以及“classIndex”列,其中包含双精度类型标签。像这样的 DataFrame(包含向量表示的特征和数字标签)可以直接馈送给 XGBoost4J-Spark 的训练引擎。

处理缺失值

XGBoost 默认支持缺失值(此处描述)。如果给定一个稀疏向量,XGBoost 将把稀疏向量中不存在的任何值视为缺失值。您还可以指定 XGBoost 将数据集中某个特定值视为缺失值。默认情况下,XGBoost 将 NaN 视为表示缺失值的值。

在 XGBoostClassifier 中设置缺失值(例如 -999)到“missing”参数的示例

import ml.dmlc.xgboost4j.scala.spark.XGBoostClassifier
val xgbParam = Map("eta" -> 0.1f,
      "missing" -> -999,
      "objective" -> "multi:softprob",
      "num_class" -> 3,
      "num_round" -> 100,
      "num_workers" -> 2)
val xgbClassifier = new XGBoostClassifier(xgbParam).
      setFeaturesCol("features").
      setLabelCol("classIndex")

注意

缺失值

如果特征是向量类型,则单个特征实例可能是稀疏向量,其中“0”将被视为缺失值。为了获得正确的模型,XGBoost4j-Spark 将通过恢复“0”将稀疏向量转换为数组。但是,我们不能假设 0 表示缺失值,因为它可能是有意义的。因此,在这种情况下,即使 XGBoost4j-Spark 中默认将缺失值设置为 Float.NaN,用户也需要显式指定缺失值。

训练

XGBoost 支持回归、分类和排名。虽然本教程中使用 Iris 数据集来展示如何使用 XGBoost4J-Spark 解决多类分类问题,但回归和排名中的用法与分类非常相似。

为了训练分类的 XGBoost 模型,我们首先需要创建一个 XGBoostClassifier

import ml.dmlc.xgboost4j.scala.spark.XGBoostClassifier
val xgbParam = Map("eta" -> 0.1f,
      "max_depth" -> 2,
      "objective" -> "multi:softprob",
      "num_class" -> 3)
val xgbClassifier = new XGBoostClassifier(xgbParam).
      setNumRound(100).
      setNumWorkers(2).
      setFeaturesCol("features").
      setLabelCol("classIndex")

训练 XGBoost 模型可用的参数可在 此处 找到。在 XGBoost4J-Spark 中,我们不仅支持默认参数集,还支持这些参数的驼峰命名变体,以与 Spark 的 MLLIB 参数保持一致。

具体来说,此页面 中的每个参数在 XGBoost4J-Spark 中都有其对应的驼峰命名形式。例如,要为每棵树设置 max_depth,您可以像我们在上面的代码片段中所做的那样传递参数(作为 Map 中包装的 max_depth),或者您可以通过 XGBoostClassifer 中的 setter 来实现

val xgbClassifier = new XGBoostClassifier().
  setFeaturesCol("features").
  setLabelCol("classIndex")
xgbClassifier.setMaxDepth(2)

设置 XGBoostClassifier 参数和特征/标签列后,我们可以通过将 XGBoostClassifier 与输入 DataFrame 拟合来构建一个转换器 XGBoostClassificationModel。此 fit 操作本质上是训练过程,生成的模型可用于预测。

val xgbClassificationModel = xgbClassifier.fit(xgbInput)

提前停止

提前停止是一项防止不必要训练迭代的功能。通过指定 num_early_stopping_rounds 或直接在 XGBoostClassifier 或 XGBoostRegressor 上调用 setNumEarlyStoppingRounds,我们可以定义评估指标偏离最佳迭代的轮数,并提前停止训练迭代。

当涉及自定义评估指标时,除了 num_early_stopping_rounds 之外,您还需要定义 maximize_evaluation_metrics 或调用 setMaximizeEvaluationMetrics 来指定您是希望在训练中最大化还是最小化指标。对于内置评估指标,XGBoost4J-Spark 将自动选择方向。

例如,我们需要最大化评估指标(将 maximize_evaluation_metrics 设置为 true),并将 num_early_stopping_rounds 设置为 5。第 10 次迭代的评估指标是目前最大的。在随后的迭代中,如果没有评估指标大于第 10 次迭代(最佳)的指标,则训练将在第 15 次迭代时提前停止。

使用评估数据集进行训练

您还可以在训练期间使用评估数据集监控模型性能。通过在 XGBoostClassifier、XGBoostRegressor 或 XGBoostRanker 上调用 setEvalDataset

预测

XGBoost4j-Spark 支持两种模型服务方式:批量预测和单实例预测。

批量预测

当我们获得模型时,无论是 XGBoostClassificationModel、XGBoostRegressionModel 还是 XGBoostRankerModel,它都会接收一个 DataFrame,读取包含特征向量的列,对每个特征向量进行预测,并默认输出一个包含以下列的新 DataFrame

  • XGBoostClassificationModel 将输出每个可能标签的边距 (rawPredictionCol)、概率 (probabilityCol) 和最终预测标签 (predictionCol)。

  • XGBoostRegressionModel 将输出预测标签 (predictionCol)。

  • XGBoostRankerModel 将输出预测标签 (predictionCol)。

批量预测要求用户以 DataFrame 的形式传递测试集。XGBoost4J-Spark 为 DataFrame 的每个分区启动一个 XGBoost worker 进行并行预测,并批量生成整个 DataFrame 的预测结果。

val xgbClassificationModel = xgbClassifier.fit(xgbInput)
val results = xgbClassificationModel.transform(testSet)

通过上述代码片段,我们得到一个结果 DataFrame,其中包含每个类别的边际、概率以及每个实例的预测结果。

+-----------------+----------+--------------------+--------------------+----------+
|         features|classIndex|       rawPrediction|         probability|prediction|
+-----------------+----------+--------------------+--------------------+----------+
|[5.1,3.5,1.4,0.2]|       0.0|[3.45569849014282...|[0.99579632282257...|       0.0|
|[4.9,3.0,1.4,0.2]|       0.0|[3.45569849014282...|[0.99618089199066...|       0.0|
|[4.7,3.2,1.3,0.2]|       0.0|[3.45569849014282...|[0.99643349647521...|       0.0|
|[4.6,3.1,1.5,0.2]|       0.0|[3.45569849014282...|[0.99636095762252...|       0.0|
|[5.0,3.6,1.4,0.2]|       0.0|[3.45569849014282...|[0.99579632282257...|       0.0|
|[5.4,3.9,1.7,0.4]|       0.0|[3.45569849014282...|[0.99428516626358...|       0.0|
|[4.6,3.4,1.4,0.3]|       0.0|[3.45569849014282...|[0.99643349647521...|       0.0|
|[5.0,3.4,1.5,0.2]|       0.0|[3.45569849014282...|[0.99579632282257...|       0.0|
|[4.4,2.9,1.4,0.2]|       0.0|[3.45569849014282...|[0.99618089199066...|       0.0|
|[4.9,3.1,1.5,0.1]|       0.0|[3.45569849014282...|[0.99636095762252...|       0.0|
|[5.4,3.7,1.5,0.2]|       0.0|[3.45569849014282...|[0.99428516626358...|       0.0|
|[4.8,3.4,1.6,0.2]|       0.0|[3.45569849014282...|[0.99643349647521...|       0.0|
|[4.8,3.0,1.4,0.1]|       0.0|[3.45569849014282...|[0.99618089199066...|       0.0|
|[4.3,3.0,1.1,0.1]|       0.0|[3.45569849014282...|[0.99618089199066...|       0.0|
|[5.8,4.0,1.2,0.2]|       0.0|[3.45569849014282...|[0.97809928655624...|       0.0|
|[5.7,4.4,1.5,0.4]|       0.0|[3.45569849014282...|[0.97809928655624...|       0.0|
|[5.4,3.9,1.3,0.4]|       0.0|[3.45569849014282...|[0.99428516626358...|       0.0|
|[5.1,3.5,1.4,0.3]|       0.0|[3.45569849014282...|[0.99579632282257...|       0.0|
|[5.7,3.8,1.7,0.3]|       0.0|[3.45569849014282...|[0.97809928655624...|       0.0|
|[5.1,3.8,1.5,0.3]|       0.0|[3.45569849014282...|[0.99579632282257...|       0.0|
+-----------------+----------+--------------------+--------------------+----------+

单实例预测

XGBoostClassificationModel、XGBoostRegressionModel 或 XGBoostRankerModel 也支持对单个实例进行预测。它接受单个 Vector 作为特征,并输出预测标签。

然而,由于 XGBoost 内部开销,单实例预测的开销很高,请谨慎使用!

val features = xgbInput.head().getAs[Vector]("features")
val result = xgbClassificationModel.predict(features)

模型持久化

模型和管道持久化

数据科学家生成一个机器学习模型,并将其交给工程团队部署到生产环境中。反之,训练好的模型可能被数据科学家使用,例如作为基准,贯穿数据探索过程。因此,支持模型持久化以使模型在各种使用场景和编程语言中可用非常重要。

XGBoost4j-Spark 支持将 XGBoostClassifier/XGBoostClassificationModel 和 XGBoostRegressor/XGBoostRegressionModel 以及 XGBoostRanker/XGBoostRankerModel 保存到/从文件系统。它还支持保存和加载包含这些估计器和模型的 ML 管道。

我们可以将 XGBoostClassificationModel 保存到文件系统

val xgbClassificationModelPath = "/tmp/xgbClassificationModel"
xgbClassificationModel.write.overwrite().save(xgbClassificationModelPath)

然后在另一个会话中加载模型

import ml.dmlc.xgboost4j.scala.spark.XGBoostClassificationModel

val xgbClassificationModel2 = XGBoostClassificationModel.load(xgbClassificationModelPath)
xgbClassificationModel2.transform(xgbInput)

注意

除了将模型转储为原始格式外,用户还可以将模型转储为 json 或 ubj 格式。

val xgbClassificationModelPath = "/tmp/xgbClassificationModel"
xgbClassificationModel.write.overwrite().option("format", "json").save(xgbClassificationModelPath)

关于 ML 管道的保存和加载,请参考下一节。

与 XGBoost 的其他绑定交互

在使用 XGBoost4j-Spark 在海量数据集上训练模型后,有时我们希望在单机上进行模型服务或将其与其他单节点库集成以进行进一步处理。

保存模型后,我们可以直接使用单节点 Python XGBoost 加载此模型。

val xgbClassificationModelPath = "/tmp/xgbClassificationModel"
xgbClassificationModel.write.overwrite().save(xgbClassificationModelPath)
import xgboost as xgb
bst = xgb.Booster({'nthread': 4})
bst.load_model("/tmp/xgbClassificationModel/data/model")

注意

XGBoost4J-Spark 与其他 XGBoost 绑定之间的一致性问题

XGBoost4J-Spark 与 XGBoost 的其他语言绑定之间存在一致性问题。

当用户使用 Spark 通过以下代码片段加载 LIBSVM 格式的训练/测试数据时

spark.read.format("libsvm").load("trainingset_libsvm")

Spark 假设数据集使用 1-based 索引(特征索引从 1 开始)。然而,当您使用 XGBoost 的其他绑定(例如,XGBoost 的 Python API)进行预测时,XGBoost 默认假设数据集使用 0-based 索引(特征索引从 0 开始)。这为使用 Spark 训练模型但使用相同格式的数据集在 XGBoost 的其他绑定中进行预测的用户造成了一个陷阱。解决方案是在您使用(例如)Python API 进行预测之前将数据集转换为 0-based 索引,或者在您使用 DMatrix 加载时在文件路径后附加 ?indexing_mode=1。例如在 Python 中

xgb.DMatrix('test.libsvm?indexing_mode=1')

使用 XGBoost4J-Spark 构建 ML 管道

基本 ML 管道

Spark ML 管道可以将多种算法或功能组合成一个单一的管道。它涵盖了从特征提取、转换、选择到模型训练和预测。XGBoost4j-Spark 使 XGBoost 能够无缝嵌入到这样的管道中。以下示例展示了如何构建这样一个由 Spark MLlib 特征转换器和 XGBoostClassifier 估计器组成的管道。

我们仍然使用 Iris 数据集和 rawInput DataFrame。首先我们需要将数据集分成训练集和测试集。

val Array(training, test) = rawInput.randomSplit(Array(0.8, 0.2), 123)

然后我们构建包含 4 个阶段的 ML 管道

  • 将所有特征组装成一个单独的向量列。

  • 从字符串标签到索引双精度标签。

  • 使用 XGBoostClassifier 训练分类模型。

  • 将索引双精度标签转换回原始字符串标签。

我们已经在前面的部分中展示了前三个步骤,最后一步使用新的转换器 IndexToString 完成

val labelConverter = new IndexToString()
.setInputCol("prediction")
.setOutputCol("realLabel")
.setLabels(stringIndexer.labels)

我们需要在 Spark ML 框架中将这些步骤组织成一个管道,并评估整个管道以获得 PipelineModel

import org.apache.spark.ml.feature._
import org.apache.spark.ml.Pipeline

val pipeline = new Pipeline()
    .setStages(Array(assembler, stringIndexer, booster, labelConverter))
val model = pipeline.fit(training)

获得 PipelineModel 后,我们可以在测试数据集上进行预测并评估模型准确性。

import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator

val prediction = model.transform(test)
val evaluator = new MulticlassClassificationEvaluator()
val accuracy = evaluator.evaluate(prediction)

带超参数调优的管道

最大化 XGBoost 力量最关键的操作是为模型选择最佳参数。手动调优参数是一个繁琐且耗时的过程。借助最新版本的 XGBoost4J-Spark,我们可以利用 Spark 模型选择工具来自动化此过程。

以下示例展示了利用 CrossValidation 和 MulticlassClassificationEvaluator 搜索两个 XGBoost 参数(max_deptheta)最佳组合的代码片段。(请参阅 XGBoost 参数。)选择由 MulticlassClassificationEvaluator 定义的产生最大准确率的模型,并用于生成测试集的预测。

import org.apache.spark.ml.tuning._
import org.apache.spark.ml.PipelineModel
import ml.dmlc.xgboost4j.scala.spark.XGBoostClassificationModel

val paramGrid = new ParamGridBuilder()
    .addGrid(booster.maxDepth, Array(3, 8))
    .addGrid(booster.eta, Array(0.2, 0.6))
    .build()
val cv = new CrossValidator()
    .setEstimator(pipeline)
    .setEvaluator(evaluator)
    .setEstimatorParamMaps(paramGrid)
    .setNumFolds(3)

val cvModel = cv.fit(training)

val bestModel = cvModel.bestModel.asInstanceOf[PipelineModel].stages(2)
    .asInstanceOf[XGBoostClassificationModel]
bestModel.extractParamMap()

在生产环境中运行 XGBoost4J-Spark

XGBoost4J-Spark 是将 XGBoost 更轻松地引入生产环境最重要的步骤之一。在本节中,我们将介绍在生产环境中运行 XGBoost4J-Spark 的三个关键特性。

并行/分布式训练

大规模训练数据集是生产环境中最重要的特征之一。为了确保 XGBoost 的训练随着数据规模的增长而扩展,XGBoost4J-Spark 桥接了 Spark 的分布式/并行处理框架和 XGBoost 的并行/分布式训练机制。

在 XGBoost4J-Spark 中,每个 XGBoost worker 都由一个 Spark 任务包装,Spark 内存空间中的训练数据集以对用户透明的方式馈送给 XGBoost worker。

在我们构建 XGBoostClassifier 的代码片段中,我们设置了参数 num_workers(或 numWorkers)。此参数控制在训练 XGBoostClassificationModel 时我们希望拥有多少个并行 worker。

注意

关于 OpenMP 优化

默认情况下,我们为每个 XGBoost worker 分配一个核心。因此,每个 XGBoost worker 内部的 OpenMP 优化不生效,训练的并行化是通过同时运行多个 worker(即 Spark 任务)来实现的。

如果您确实需要 OpenMP 优化,则必须

  1. 在创建 XGBoostClassifier/XGBoostRegressor 时将 nthread 设置为大于 1 的值

  2. 将 Spark 中的 spark.task.cpus 设置为与 nthread 相同的值

组调度

XGBoost 使用 AllReduce 算法在训练期间同步每个 worker 的统计信息(例如直方图值)。因此,XGBoost4J-Spark 要求在训练运行之前,所有 nthread * numWorkers 核心都可用。

在许多用户共享同一个集群的生产环境中,很难保证您的 XGBoost4J-Spark 应用程序能够为每次运行获得所有请求的资源。默认情况下,XGBoost 中的通信层在需要更多资源时会阻塞整个应用程序。这个过程通常会带来不必要的资源浪费,因为它会保留已就绪的资源并尝试申请更多资源。此外,这种情况通常悄无声息地发生,不会引起用户的注意。

XGBoost4J-Spark 允许用户设置从集群请求资源的超时阈值。如果应用程序在此时间段内无法获得足够的资源,则应用程序将失败,而不是长时间挂起而浪费资源。要启用此功能,您可以为 XGBoostClassifier/XGBoostRegressor/XGBoostRanker 进行设置

xgbClassifier.setRabitTrackerTimeout(60000L)

或在构建 XGBoostClassifier 时在 xgbParamMap 中传入 rabit_tracker_timeout

val xgbParam = Map("eta" -> 0.1f,
   "max_depth" -> 2,
   "objective" -> "multi:softprob",
   "num_class" -> 3,
   "num_round" -> 100,
   "num_workers" -> 2,
   "rabit_tracker_timeout" -> 60000L)
val xgbClassifier = new XGBoostClassifier(xgbParam).
    setFeaturesCol("features").
    setLabelCol("classIndex")

如果 XGBoost4J-Spark 无法获得足够的资源来运行两个 XGBoost worker,应用程序将失败。用户可以使用外部机制来监控应用程序状态并在发生此类情况时获得通知。

训练期间的检查点

瞬时故障在生产环境中也很常见。为了简化 XGBoost 的设计,如果任何分布式 worker 失败,我们都会停止训练。但是,如果训练在经过长时间后失败,那将是巨大的资源浪费。

我们支持在训练期间创建检查点,以方便从故障中更有效地恢复。要启用此功能,您可以使用 setCheckpointInterval 设置我们构建每个检查点的迭代次数,并使用 setCheckpointPath 设置检查点的位置

xgbClassifier.setCheckpointInterval(2)
xgbClassifier.setCheckpointPath("/checkpoint_path")

另一种等效方法是在 XGBoostClassifier 的构造函数中传入参数

val xgbParam = Map("eta" -> 0.1f,
   "max_depth" -> 2,
   "objective" -> "multi:softprob",
   "num_class" -> 3,
   "num_round" -> 100,
   "num_workers" -> 2,
   "checkpoint_path" -> "/checkpoints_path",
   "checkpoint_interval" -> 2)
val xgbClassifier = new XGBoostClassifier(xgbParam).
    setFeaturesCol("features").
    setLabelCol("classIndex")

如果在这些 100 轮中训练失败,下一次训练运行将通过读取 /checkpoints_path 中的最新检查点文件开始,并从创建检查点时的迭代开始,直到下一次失败或指定的 100 轮结束。

外部内存

3.0 版本新增。

警告

此功能处于实验阶段。

这里我们指的是基于迭代器的外部内存,而不是使用特殊 URL 参数的外部内存。自 3.0 版本以来,XGBoost-Spark 对基于 GPU 的外部内存训练提供了实验性支持(XGBoost4J-Spark-GPU 教程)。当与基于 GPU 的训练结合使用时,数据首先缓存到磁盘,然后暂存到 CPU 内存。有关外部内存训练的一般概念和最佳实践,请参阅 使用 XGBoost 外部内存版本。此外,请参阅估计器参数 useExternalMemory 的文档字符串。使用 Spark 估计器

val xgbClassifier = new XGBoostClassifier(xgbParam)
    .setFeaturesCol(featuresNames)
    .setLabelCol(labelName)
    .setUseExternalMemory(true)
    .setDevice("cuda")  // CPU is not yet supported