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 构建机器学习应用

参考 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 个特征:“sepal length”(萼片长度)、“sepal width”(萼片宽度)、“petal length”(花瓣长度)和“petal width”(花瓣宽度)。此外,它还包含“class”列,这本质上是标签,有三个可能的值:“Iris Setosa”、“Iris Versicolour”和“Iris Virginica”。

使用 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”(包含向量表示的“sepal length”、“sepal width”、“petal length”和“petal width”)和“classIndex”(包含双精度浮点数类型的标签)。这样的 DataFrame(包含向量表示的特征和数值标签)可以直接馈送给 XGBoost4J-Spark 的训练引擎。

处理缺失值

XGBoost 默认支持缺失值(此处描述)。如果给定 SparseVector,XGBoost 会将 SparseVector 中不存在的任何值视为缺失值。您还可以指定 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")

注意

缺失值

如果特征是向量类型,单个特征实例可以是 SparseVector,其中“0”将被视为缺失值。为了获得正确的模型,XGBoost4j-Spark 会通过恢复“0”将 SparseVector 转换为数组。然而,我们不能将 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),或者您可以通过 XGBoostClassifier 中的 setter 来完成

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

在设置好 XGBoostClassifier 参数和特征/标签列后,我们可以通过使用输入 DataFrame 对 XGBoostClassifier 进行拟合,从而构建一个转换器 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 保存到文件系统以及从文件系统加载。它还支持保存和加载包含这些评估器和模型的机器学习流水线。

我们可以将 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)

关于机器学习流水线的保存和加载,请参考下一节。

与 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 与其他绑定之间的一致性问题

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 构建机器学习流水线

基本机器学习流水线

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

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

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

然后我们构建包含 4 个阶段的机器学习流水线

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

  • 将字符串标签转换为索引双精度浮点数标签。

  • 使用 XGBoostClassifier 训练分类模型。

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

我们在前面的章节中展示了前三个步骤,最后一步通过一个新的转换器 IndexToString 完成

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

我们需要将这些步骤组织成 Spark ML 框架中的一个 Pipeline,并评估整个 Pipeline 以获得 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 相同的值

Gang 调度

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