Apache Spark MLlib LabeledPoint 空标签问题

Apache Spark MLlib LabeledPoint null label issue

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

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

在这里你可以看到与这个问题相关的一段代码:

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,我可以 运行 这个算法吗?或者我怎样才能克服这个 "null value" 问题?

此代码无法运行的一些原因:

  • Row.toSeq() => Seq[Any] 类型,s
  • 也是
  • 因为您仅涵盖非空情况 el => if (el != null) el.toString.toDouble 属于 T => AnyVal 类型(其中 T 是任何类型)。如果 elnull 它 returns Unit
  • 即使不是您将其分配给 Seq[Any] 类型的 var,这也正是您得到的结果。无论哪种方式,它都不是 Vectors.dense
  • 的有效输入
  • Row.apply 是类型 Int => Any 所以输出不能用作标签

应该有效但没有效果:

  • s.take(0)

可能会停止在 Spark 2.0 中工作

  • map 优于 DataFrame - 我们现在无能为力,因为 Vector class 没有可用的编码器。

如何解决这个问题:

  • 过滤完整行或填充缺失值,例如使用 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)
    }