From 65db8d0626c0324535f09b0502f2e2a49103dae9 Mon Sep 17 00:00:00 2001 From: Nan Zhu Date: Wed, 17 Apr 2019 11:33:13 -0700 Subject: [PATCH] [jvm-packages] support spark 2.4 and compatibility test with previous xgboost version (#4377) * bump spark version * keep float.nan * handle brokenly changed name/value * add test * add model files * add model files * update doc --- doc/jvm/xgboost4j_spark_tutorial.rst | 4 ++-- jvm-packages/pom.xml | 2 +- .../params/DefaultXGBoostParamsReader.scala | 19 +++++++++++++++--- .../model/data/XGBoostClassificationModel | Bin 0 -> 94113 bytes .../model/0.82/model/metadata/_SUCCESS | 0 .../model/0.82/model/metadata/part-00000 | 1 + .../scala/spark/PersistenceSuite.scala | 16 ++++++++++++++- .../scala/spark/XGBoostGeneralSuite.scala | 1 + 8 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 jvm-packages/xgboost4j-spark/src/test/resources/model/0.82/model/data/XGBoostClassificationModel create mode 100644 jvm-packages/xgboost4j-spark/src/test/resources/model/0.82/model/metadata/_SUCCESS create mode 100644 jvm-packages/xgboost4j-spark/src/test/resources/model/0.82/model/metadata/part-00000 diff --git a/doc/jvm/xgboost4j_spark_tutorial.rst b/doc/jvm/xgboost4j_spark_tutorial.rst index a7332f253..fd106be7c 100644 --- a/doc/jvm/xgboost4j_spark_tutorial.rst +++ b/doc/jvm/xgboost4j_spark_tutorial.rst @@ -61,9 +61,9 @@ and then refer to the snapshot dependency by adding: next_version_num-SNAPSHOT -.. note:: XGBoost4J-Spark requires Apache Spark 2.3+ +.. note:: XGBoost4J-Spark requires Apache Spark 2.4+ - XGBoost4J-Spark now requires **Apache Spark 2.3+**. Latest versions of XGBoost4J-Spark uses facilities of `org.apache.spark.ml.param.shared` extensively to provide for a tight integration with Spark MLLIB framework, and these facilities are not fully available on earlier versions of Spark. + XGBoost4J-Spark now requires **Apache Spark 2.4+**. Latest versions of XGBoost4J-Spark uses facilities of `org.apache.spark.ml.param.shared` extensively to provide for a tight integration with Spark MLLIB framework, and these facilities are not fully available on earlier versions of Spark. Also, make sure to install Spark directly from `Apache website `_. **Upstream XGBoost is not guaranteed to work with third-party distributions of Spark, such as Cloudera Spark.** Consult appropriate third parties to obtain their distribution of XGBoost. diff --git a/jvm-packages/pom.xml b/jvm-packages/pom.xml index 1476801c6..d25cf51b1 100644 --- a/jvm-packages/pom.xml +++ b/jvm-packages/pom.xml @@ -34,7 +34,7 @@ 1.7 1.7 1.5.0 - 2.3.3 + 2.4.1 2.11.12 2.11 diff --git a/jvm-packages/xgboost4j-spark/src/main/scala/ml/dmlc/xgboost4j/scala/spark/params/DefaultXGBoostParamsReader.scala b/jvm-packages/xgboost4j-spark/src/main/scala/ml/dmlc/xgboost4j/scala/spark/params/DefaultXGBoostParamsReader.scala index b79d5b694..bb75bb342 100644 --- a/jvm-packages/xgboost4j-spark/src/main/scala/ml/dmlc/xgboost4j/scala/spark/params/DefaultXGBoostParamsReader.scala +++ b/jvm-packages/xgboost4j-spark/src/main/scala/ml/dmlc/xgboost4j/scala/spark/params/DefaultXGBoostParamsReader.scala @@ -22,12 +22,17 @@ import org.json4s.JsonAST.JObject import org.json4s.jackson.JsonMethods.{compact, parse, render} import org.apache.spark.SparkContext -import org.apache.spark.ml.param.Params +import org.apache.spark.ml.param.{Param, Params} import org.apache.spark.ml.util.MLReader // This originates from apache-spark DefaultPramsReader copy paste private[spark] object DefaultXGBoostParamsReader { + private val paramNameCompatibilityMap: Map[String, String] = Map("silent" -> "verbosity") + + private val paramValueCompatibilityMap: Map[String, Map[Any, Any]] = + Map("objective" -> Map("reg:linear" -> "reg:squarederror")) + /** * All info from metadata file. * @@ -103,6 +108,14 @@ private[spark] object DefaultXGBoostParamsReader { Metadata(className, uid, timestamp, sparkVersion, params, metadata, metadataStr) } + private def handleBrokenlyChangedValue[T](paramName: String, value: T): T = { + paramValueCompatibilityMap.getOrElse(paramName, Map()).getOrElse(value, value).asInstanceOf[T] + } + + private def handleBrokenlyChangedName(paramName: String): String = { + paramNameCompatibilityMap.getOrElse(paramName, paramName) + } + /** * Extract Params from metadata, and set them in the instance. * This works if all Params implement [[org.apache.spark.ml.param.Param.jsonDecode()]]. @@ -113,9 +126,9 @@ private[spark] object DefaultXGBoostParamsReader { metadata.params match { case JObject(pairs) => pairs.foreach { case (paramName, jsonValue) => - val param = instance.getParam(paramName) + val param = instance.getParam(handleBrokenlyChangedName(paramName)) val value = param.jsonDecode(compact(render(jsonValue))) - instance.set(param, value) + instance.set(param, handleBrokenlyChangedValue(paramName, value)) } case _ => throw new IllegalArgumentException( diff --git a/jvm-packages/xgboost4j-spark/src/test/resources/model/0.82/model/data/XGBoostClassificationModel b/jvm-packages/xgboost4j-spark/src/test/resources/model/0.82/model/data/XGBoostClassificationModel new file mode 100644 index 0000000000000000000000000000000000000000..5d915d02f5f854759837b85eca75ebb5377e2eef GIT binary patch literal 94113 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

NyN!=R~{-*Y$rlzF~}= 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 W!~g#Y{0_vcvH63VHg8_!y#E7Q-T;pP literal 0 HcmV?d00001 diff --git a/jvm-packages/xgboost4j-spark/src/test/resources/model/0.82/model/metadata/_SUCCESS b/jvm-packages/xgboost4j-spark/src/test/resources/model/0.82/model/metadata/_SUCCESS new file mode 100644 index 000000000..e69de29bb diff --git a/jvm-packages/xgboost4j-spark/src/test/resources/model/0.82/model/metadata/part-00000 b/jvm-packages/xgboost4j-spark/src/test/resources/model/0.82/model/metadata/part-00000 new file mode 100644 index 000000000..7e1a7221a --- /dev/null +++ b/jvm-packages/xgboost4j-spark/src/test/resources/model/0.82/model/metadata/part-00000 @@ -0,0 +1 @@ +{"class":"ml.dmlc.xgboost4j.scala.spark.XGBoostClassificationModel","timestamp":1555350539033,"sparkVersion":"2.3.2-uber-109","uid":"xgbc_5e7bec215a4c","paramMap":{"useExternalMemory":false,"trainTestRatio":1.0,"alpha":0.0,"seed":0,"numWorkers":100,"skipDrop":0.0,"treeLimit":0,"silent":0,"trackerConf":{"workerConnectionTimeout":0,"trackerImpl":"python"},"missing":"NaN","colsampleBylevel":1.0,"probabilityCol":"probability","checkpointPath":"","lambda":1.0,"rawPredictionCol":"rawPrediction","eta":0.3,"numEarlyStoppingRounds":0,"growPolicy":"depthwise","gamma":0.0,"sampleType":"uniform","maxDepth":6,"rateDrop":0.0,"objective":"reg:linear","customObj":null,"lambdaBias":0.0,"baseScore":0.5,"labelCol":"label","minChildWeight":1.0,"customEval":null,"normalizeType":"tree","maxBin":16,"nthread":4,"numRound":20,"colsampleBytree":1.0,"predictionCol":"prediction","subsample":1.0,"timeoutRequestWorkers":1800000,"featuresCol":"features","evalMetric":"error","sketchEps":0.03,"scalePosWeight":1.0,"checkpointInterval":-1,"maxDeltaStep":0.0,"treeMethod":"approx"}} diff --git a/jvm-packages/xgboost4j-spark/src/test/scala/ml/dmlc/xgboost4j/scala/spark/PersistenceSuite.scala b/jvm-packages/xgboost4j-spark/src/test/scala/ml/dmlc/xgboost4j/scala/spark/PersistenceSuite.scala index 4c0b21073..220cea307 100644 --- a/jvm-packages/xgboost4j-spark/src/test/scala/ml/dmlc/xgboost4j/scala/spark/PersistenceSuite.scala +++ b/jvm-packages/xgboost4j-spark/src/test/scala/ml/dmlc/xgboost4j/scala/spark/PersistenceSuite.scala @@ -19,9 +19,11 @@ package ml.dmlc.xgboost4j.scala.spark import java.io.{File, FileNotFoundException} import java.util.Arrays -import ml.dmlc.xgboost4j.scala.DMatrix +import scala.io.Source +import ml.dmlc.xgboost4j.scala.DMatrix import scala.util.Random + import org.apache.spark.ml.feature._ import org.apache.spark.ml.{Pipeline, PipelineModel} import org.apache.spark.network.util.JavaUtils @@ -162,5 +164,17 @@ class PersistenceSuite extends FunSuite with PerTest with BeforeAndAfterAll { assert(xgbModel.getNumRound === xgbModel2.getNumRound) assert(xgbModel.getRawPredictionCol === xgbModel2.getRawPredictionCol) } + + test("cross-version model loading (0.82)") { + val modelPath = getClass.getResource("/model/0.82/model").getPath + val model = XGBoostClassificationModel.read.load(modelPath) + val r = new Random(0) + val df = ss.createDataFrame(Seq.fill(100)(r.nextInt(2)).map(i => (i, i))). + toDF("feature", "label") + val assembler = new VectorAssembler() + .setInputCols(df.columns.filter(!_.contains("label"))) + .setOutputCol("features") + model.transform(assembler.transform(df)).show() + } } diff --git a/jvm-packages/xgboost4j-spark/src/test/scala/ml/dmlc/xgboost4j/scala/spark/XGBoostGeneralSuite.scala b/jvm-packages/xgboost4j-spark/src/test/scala/ml/dmlc/xgboost4j/scala/spark/XGBoostGeneralSuite.scala index 50f827c34..1affe1474 100644 --- a/jvm-packages/xgboost4j-spark/src/test/scala/ml/dmlc/xgboost4j/scala/spark/XGBoostGeneralSuite.scala +++ b/jvm-packages/xgboost4j-spark/src/test/scala/ml/dmlc/xgboost4j/scala/spark/XGBoostGeneralSuite.scala @@ -261,6 +261,7 @@ class XGBoostGeneralSuite extends FunSuite with PerTest { val vectorAssembler = new VectorAssembler() .setInputCols(Array("col1", "col2", "col3")) .setOutputCol("features") + .setHandleInvalid("keep") val inputDF = vectorAssembler.transform(testDF).select("features", "label") val paramMap = List("eta" -> "1", "max_depth" -> "2", "objective" -> "binary:logistic", "num_workers" -> 1).toMap