首页 > 解决方案 > 如果存在空值,XGBoost 训练将失败(整个管道存在 setHandleInvalid “keep”)

问题描述

我正在使用 Spark (Scala) 训练 XGBoostRegressor 模型,我注意到预测值的数量少于使用 model.transform(df) 提供给模型的数量。

问题是由于存在(并且应该是,根据我的用例)NULL 值。我已经通过在我拥有的每个阶段(特别是 stringIndexer、oneHotEncoder、vectorAssembler)使用 setHandleInvalid 来处理这些问题。

但是,仍然,如果我使用“keep”,模型无法训练,但如果我使用“skip”(顺便说一句,仅在 vectorAssembler 上),那么模型设法训练,但只是“丢弃”甚至 1 个字段为空的记录。

尝试了大量的谷歌,但并没有真正看到任何解决方案。

将不胜感激任何人的意见。

提前致谢。

Spark、Scala、XGBoost Docs 看到了几个没有帮助的 PR,尝试了几种处理 Null 值的策略,但没有一个成功。

对于保持案例(火车失败)->

  .setInputCol("country_code")
  .setOutputCol("country_code_indexed")
  .setHandleInvalid("keep")

val oneHotEncoder = new OneHotEncoderEstimator()
.setInputCol("user_country_code_indexed")
.setOutputCol("user_country_oneHotEncoded")
.setHandleInvalid("keep")

val assembler =  new VectorAssembler()
  .setInputCols(trainUpdated.drop("label",
                               "someCol1",
                               "someCol2", 
                               "country_code", 
                               "country_code_indexed").columns)
  .setOutputCol("features")
  .setHandleInvalid("keep")

val xgboostRegressor = new XGBoostRegressor(Map[String, Any](
  "num_round" -> 100,
  "num_workers" -> 10,  //num of instances * num of cores is the max.
  "objective" -> "reg:linear",
  "eta" -> 0.1,
  "gamma" -> 0.5,
  "max_depth" -> 6, 
  "early_stopping_rounds" -> 9,
  "seed" -> 1234,
  "lambda" -> 0.4,
  "alpha" -> 0.3,
  "colsample_bytree" -> 0.6,
  "subsample" -> 0.3
  ))

然后我得到-> ml.dmlc.xgboost4j.java.XGBoostError: XGBoostModel training failed

预期结果 -使用空值进行模型训练(因为它是其默认行为......)并返回训练/测试期间的确切记录数(拟合/转换,两者的策略相同)。

标签: apache-sparkxgboost

解决方案


我想声明我已经与 XGBoost 的创建者讨论过这个问题,并且我通过相应地更新文档来为社区做出贡献。新文档在这里(缺失值部分) - https://xgboost.readthedocs.io/en/latest/jvm/xgboost4j_spark_tutorial.html


推荐阅读