【问题标题】:XGBoost failing after using windowing functions on label column在标签列上使用窗口函数后 XGBoost 失败
【发布时间】:2018-07-11 20:47:07
【问题描述】:

我已经成功训练了一个 XGBoost 模型,其中 trainDF 是一个包含两列的数据框:features 和 label,其中我们有 11k 1 和 57M 0(不平衡数据集)。一切正常。

val udnersample = 0.1
// Undersampling of 0's -- choosing 10%
val training1 = output1.filter($"datestr" < end_period1 && 
    $"label" === 1)
val training0 = output1.filter($"datestr" < end_period1 && 
    $"label" === 0).sample(
    false, undersample)
val training = training0.unionAll(training1)
val traindDF = training.select("label", 
    "features").toDF("label", "features")}
val paramMap = List("eta" -> 0.05,
                    "max_depth" -> 6,
                    "objective" -> "binary:logistic").toMap
val num_trees = 400
val num_cores = 200
val XGBModel = XGBoost.trainWithDataFrame(trainDF, 
                                          paramMap, 
                                          num_trees, 
                                          num_cores, 
                                          useExternalMemory = true)

然后,我想通过一些窗口来更改 y 标签,以便在每个组中,我可以更早地预测 y 标签。

val sum_label = "sum_label"
val label_window_length = 19
val sliding_window_label =  Window.partitionBy("id").orderBy(
    asc("timestamp")).rowsBetween(0, label_window_length)

val training_source = output1.filter($"datestr" < 
    end_period1).withColumn(
    sum_label, sum($"label").over(sliding_window_label)).drop(
    "label").withColumnRenamed(sum_label, "label")
val training1 = training_source.filter(col("label") === 1)
val training0 = training_source.filter(col("label") === 0).sample(false, 0.099685)
val training = training0.unionAll(training1)
val traindDF = training.select("label", 
    "features").toDF("label", "features")}

结果有 57M 的 0 和 214k 的 1(尽管行数大致相同)。在trainDF 的"label" 列中没有NAs,类型仍然是double (nullable=true)。然后 xgboost 失败:

Name: ml.dmlc.xgboost4j.java.XGBoostError
Message: XGBoostModel training failed
StackTrace:   at ml.dmlc.xgboost4j.scala.spark.XGBoost$.postTrackerReturnProcessing(XGBoost.scala:316)
at ml.dmlc.xgboost4j.scala.spark.XGBoost$.trainWithRDD(XGBoost.scala:293)
at ml.dmlc.xgboost4j.scala.spark.XGBoostEstimator.train(XGBoostEstimator.scala:138)
at ml.dmlc.xgboost4j.scala.spark.XGBoostEstimator.train(XGBoostEstimator.scala:35)
at org.apache.spark.ml.Predictor.fit(Predictor.scala:118)
at ml.dmlc.xgboost4j.scala.spark.XGBoost$.trainWithDataFrame(XGBoost.scala:169)

我可以根据需要包含日志。我的困惑是,使用窗口功能并且实际上不更改任何其他设置会导致 XGB 失败。我将不胜感激。

【问题讨论】:

    标签: scala apache-spark xgboost windowing


    【解决方案1】:

    事实证明,将表 traindDF 保存在 hive 中并将其重新加载到 Spark 中可以解决问题:

    traindDF.write.mode("overwrite").saveAsTable("database.tablename")
    

    然后,您可以轻松加载表格:

    val traindDF = spark.sql("""select * from database.tablename""")
    

    这个技巧解决了这个问题。似乎火花窗口功能有点不稳定,将结果保存到配置单元表中使其工作。

    更好的方法是在 hive 中使用窗口函数而不是 Spark。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-18
      • 1970-01-01
      • 1970-01-01
      • 2012-10-23
      • 2015-11-29
      • 1970-01-01
      • 2013-11-16
      相关资源
      最近更新 更多