XGBoost-4j от DMLC на Spark-1.6.1

Я пытаюсь использовать реализацию XGBoost от DMLC на Spark-1.6.1. Я могу обучать свои данные с помощью XGBoost, но испытываю трудности с предсказанием. На самом деле я хочу делать прогнозы так, как это можно сделать в mllib-библиотеках Apache Spark, которые помогают в вычислении ошибки обучения, точности, отзыва, специфичности и т. Д.

Я отправляю коды ниже, а также получаю сообщение об ошибке. Я использовал этот xgboost4j-spark-0.5-jar-with-dependencies.jar в spark-shell для запуска.

import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.util.MLUtils
import org.apache.spark.SparkContext._
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.regression.LabeledPoint
import ml.dmlc.xgboost4j.scala.Booster
import ml.dmlc.xgboost4j.scala.spark.XGBoost
import ml.dmlc.xgboost4j.scala.DMatrix
import ml.dmlc.xgboost4j.scala.{Booster, DMatrix}
import ml.dmlc.xgboost4j.scala.spark.{DataUtils, XGBoost}
import org.apache.spark.{SparkConf, SparkContext}




//Load and parse the data file.
val data = sc.textFile("file:///home/partha/credit_approval
res0: Array[Array[Array[Float]]] = Array(Array(Array(0.0), Array(1.0), Array(1.0), Array(1.0), Array(0.0), Array(0.0), Array(1.0), Array(1.0), Array(0.0), Array(1.0), Array(0.0), Array(0.0), Array(0.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(0.0), Array(1.0), Array(1.0), Array(0.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(0.0), Array(1.0), Array(1.0), Array(1.0), Array(0.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(0.0), Array(0.0), Array(0.0), Array(0.0), Array(1.0), Array(0.0), Array(0.0), Array(0.0), Array(0.0), Array(0.0), Array(0.0), Array(1.0), Array(1.0), Array(1.0), Array(...
attr.csv") val data1 = sc.textFile("file:///home/partha/credit_app_fea.csv") val parsedData = data.map { line => val parts = line.split(',').map(_.toDouble) LabeledPoint(parts(0), Vectors.dense(parts.tail)) }.cache() val parsedData1 = data1.map { line => val parts = line.split(',').map(_.toDouble) Vectors.dense(parts) } //Tuning Parameters val paramMap = List( "eta" -> 0.1f, "max_depth" -> 5, "num_class" -> 2, "objective" -> "multi:softmax" , "colsample_bytree" -> 0.8, "alpha" -> 1, "subsample" -> 0.5).toMap //Training the model val numRound = 20 val model = XGBoost.train(parsedData, paramMap, numRound, nWorkers = 1) val pred = model.predict(parsedData1) pred.collect()

Вывод из пред:

res0: Array[Array[Array[Float]]] = Array(Array(Array(0.0), Array(1.0), Array(1.0), Array(1.0), Array(0.0), Array(0.0), Array(1.0), Array(1.0), Array(0.0), Array(1.0), Array(0.0), Array(0.0), Array(0.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(0.0), Array(1.0), Array(1.0), Array(0.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(0.0), Array(1.0), Array(1.0), Array(1.0), Array(0.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(1.0), Array(0.0), Array(0.0), Array(0.0), Array(0.0), Array(1.0), Array(0.0), Array(0.0), Array(0.0), Array(0.0), Array(0.0), Array(0.0), Array(1.0), Array(1.0), Array(1.0), Array(...

Теперь, когда я использую:

val labelAndPreds = parsedData.map { point =>
          val prediction = model.predict(point.features)
          (point.label, prediction)
        }

Выход:

<console>:66: error: overloaded method value predict with alternatives:
  (testSet: ml.dmlc.xgboost4j.scala.DMatrix)Array[Array[Float]] <and>
  (testSet: org.apache.spark.rdd.RDD[org.apache.spark.mllib.linalg.Vector])org.apache.spark.rdd.RDD[Array[Array[Float]]]
 cannot be applied to (org.apache.spark.mllib.linalg.Vector)
                  val prediction = model.predict(point.features)
                                     ^

А затем попробовал это, поскольку для предсказания требуется RDD [Vector].

val labelAndPreds1 = parsedData.map { point =>
          val prediction = model.predict(Vectors.dense(point.features))
          (point.label, prediction)
        }

Результат был:

<console>:66: error: overloaded method value dense with alternatives:
  (values: Array[Double])org.apache.spark.mllib.linalg.Vector <and>
  (firstValue: Double,otherValues: Double*)org.apache.spark.mllib.linalg.Vector
 cannot be applied to (org.apache.spark.mllib.linalg.Vector)
                  val prediction = model.predict(Vectors.dense(point.features))
                                                         ^

Ясно, что это проблема типа RDD, с которой я пытаюсь разобраться, это легко с GBT на искре (http://spark.apache.org/docs/latest/mllib-ensembles.html#gradient-boosted-tree-gbts).

Я пытаюсь сделать это правильно?

Любая помощь или предложение были бы потрясающими.


person PARTHA TALUKDER    schedule 21.04.2016    source источник


Ответы (2)


На самом деле это недоступно в алгоритмах XGboost. У меня здесь та же проблема, и я реализовал следующий метод:

import ml.dmlc.xgboost4j.scala.spark.DataUtils // thanks to @Z Simon

def labelPredict(testSet: RDD[XGBLabeledPoint],
               useExternalCache: Boolean = false,
               booster: XGBoostModel): RDD[(Float, Float)] = {
val broadcastBooster = testSet.sparkContext.broadcast(booster)
testSet.mapPartitions { testData =>
  val (auxiliaryIterator, testDataIterator) = testData.duplicate
  val testDataArray = auxiliaryIterator.toArray
  val prediction = broadcastBooster.value.predict(new DMatrix(testDataIterator)).flatten
  testDataArray
    .zip(prediction)
    .map {
      case (labeledPoint, predictionValue) =>
        (labeledPoint.label, predictionValue)
    }.toIterator
}

}

Это почти тот же код, что и у XGBoost, но он использует метку labeleledpoint в возвращаемых прогнозах. Когда вы передаете Labeledpoint этому методу, он вернет RDD Tuple с (меткой, предсказанием) для каждого значения.

person dirceusemighini    schedule 30.08.2016

если вы читаете исходный код predicter ()

#
def predict(testSet: RDD[Vector]): RDD[Array[Array[Float]]] = {
    import DataUtils._
    val broadcastBooster = testSet.sparkContext.broadcast(_booster)
    testSet.mapPartitions { testSamples =>
      if (testSamples.hasNext) {
        val dMatrix = new DMatrix(new JDMatrix(testSamples, null))
        Iterator(broadcastBooster.value.predict(dMatrix))
      } else {
        Iterator()
      }
    }
  }
#

вы найдете testSet.mapPartitions () в своем testData, результатом будет массив массивов, внутренний массив - это прогнозируемое значение для тестовых данных. вы должны сделать flatMap по результату.

person Jing    schedule 27.04.2016