Scala 如何在没有StringIndexer的情况下在Spark ML中进行二进制分类

Scala 如何在没有StringIndexer的情况下在Spark ML中进行二进制分类,scala,apache-spark,classification,apache-spark-sql,apache-spark-ml,Scala,Apache Spark,Classification,Apache Spark Sql,Apache Spark Ml,我尝试在没有StringIndexer的管道中使用Spark ML DecisionTreeClassier,因为我的特性已经被索引为(0.0;1.0)。DecisionTreeClassifier as label需要双值,因此此代码应该可以工作: def trainDecisionTreeModel(training: RDD[LabeledPoint], sqlc: SQLContext): Unit = { import sqlc.implicits._ val training

我尝试在没有StringIndexer的管道中使用Spark ML DecisionTreeClassier,因为我的特性已经被索引为(0.0;1.0)。DecisionTreeClassifier as label需要双值,因此此代码应该可以工作:

def trainDecisionTreeModel(training: RDD[LabeledPoint], sqlc: SQLContext): Unit = {
  import sqlc.implicits._
  val trainingDF = training.toDF()
  //format of this dataframe: [label: double, features: vector]

  val featureIndexer = new VectorIndexer()
    .setInputCol("features")
    .setOutputCol("indexedFeatures")
    .setMaxCategories(4)
    .fit(trainingDF)

  val dt = new DecisionTreeClassifier()
    .setLabelCol("label")
    .setFeaturesCol("indexedFeatures")


  val pipeline = new Pipeline()
    .setStages(Array(featureIndexer, dt))
  pipeline.fit(trainingDF)
}
但事实上我明白了

java.lang.IllegalArgumentException:
DecisionTreeClassifier was given input with invalid label column label,
without the number of classes specified. See StringIndexer.
当然,我可以只放置StringIndexer,让他为我的双“标签”字段工作,但我想使用DecisionTreeClassifier的output rawPrediction列,以获得每行0.0和1.0的概率,如

val predictions = model.transform(singletonDF) 
val zeroProbability = predictions.select("rawPrediction").asInstanceOf[Vector](0)
val oneProbability = predictions.select("rawPrediction").asInstanceOf[Vector](1)
若我将StringIndexer放入管道中,我将不知道rawPrediction向量中输入标签“0.0”和“1.0”的索引,因为字符串索引器将按值的频率进行索引,频率可能会有所不同


请在不使用StringIndexer的情况下帮助准备DecisionTreeClassifier的数据,或建议其他方法获取每行原始标签的概率(0.0;1.0)。

您始终可以手动设置所需的元数据:

import sqlContext.implicits._
import org.apache.spark.ml.attribute.NominalAttribute

val meta = NominalAttribute
  .defaultAttr
  .withName("label")
  .withValues("0.0", "1.0")
  .toMetadata

val dfWithMeta = df.withColumn("label", $"label".as("label", meta))
pipeline.fit(dfWithMeta)

您始终可以手动设置所需的元数据:

import sqlContext.implicits._
import org.apache.spark.ml.attribute.NominalAttribute

val meta = NominalAttribute
  .defaultAttr
  .withName("label")
  .withValues("0.0", "1.0")
  .toMetadata

val dfWithMeta = df.withColumn("label", $"label".as("label", meta))
pipeline.fit(dfWithMeta)