Apache Spark MLlib LabeledPoint空标签问题

时间:2016-02-26 12:42:00

标签: scala apache-spark apache-spark-sql logistic-regression apache-spark-mllib

我正在尝试在我的数据库上运行MLlib算法之一,即LogisticRegressionWithLBFGS。

此算法将训练集作为LabeledPoint。由于LabeledPoint需要双标签(LabeledPoint(双标签,矢量要素))并且我的数据库包含一些空值,我该如何解决这个问题?

在这里,您可以看到与此问题相关的代码:

val labeled = table.map{ row => 
    var s = row.toSeq.toArray           
    s = s.map(el => if (el != null) el.toString.toDouble)
    LabeledPoint(row(0), Vectors.dense((s.take(0) ++ s.drop(1))))
    }

我得到的错误:

error   : type mismatch;
found   : Any
required: Double

如果不使用LabeledPoint,我可以运行此算法,或者如何克服这个“空值”问题?

1 个答案:

答案 0 :(得分:2)

此代码无法使用的一些原因:

  • Row.toSeq的类型为() => Seq[Any],因此s
  • 由于您仅涵盖非空案例el => if (el != null) el.toString.toDouble属于T => AnyVal类型(其中T为任意)。如果elnull,则会返回Unit
  • 即使您没有将其分配到var类型的Seq[Any],这正是您所获得的。不管怎样,它都不是Vectors.dense
  • 的有效输入
  • Row.apply的类型为Int => Any,因此输出不能用作标签

应该有效但不起作用:

  • s.take(0)

可能会停止在Spark 2.0中工作

  • map超过DataFrame - 由于Vector类没有可用的编码器,我们现在无能为力。

如何处理此问题:

  • 过滤完整行或填充缺失值,例如使用DataFrameNaFunctions

      // You definitely want something smarter than that
      val fixed = df.na.fill(0.0)
      // or
      val filtered = df.na.drop
    
  • 使用VectorAssembler构建向量:

    import org.apache.spark.ml.feature.VectorAssembler
    
    val assembler = new VectorAssembler()
      .setInputCols(df.columns.tail)
      .setOutputCol("features")
    
    val assembled = assembler.transform(fixed)
    
  • 转换为LabledPoint

    import org.apache.spark.mllib.regression.LabeledPoint  
    
    
    // Assuming lable column is called label
    
    assembled.select($"label", $"features").rdd.map {
      case Row(label: Double, features: Vector) => 
        LabeledPoint(label, features)
    }