Apache Spark MLlib LabeledPoint null label issue



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

此算法将训练集作为标记点。由于 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 是否可以运行此算法,或者如何克服此"空值"问题?

此代码无法工作的一些原因:

  • Row.toSeq属于() => Seq[Any]类型,s
  • 由于您只涵盖非空情况el => if (el != null) el.toString.toDouble因此属于T => AnyVal类型(其中T是任何)。如果el null则返回Unit
  • 即使不是你把它分配给Seq[Any]类型的var,这正是你得到的。无论如何,它不是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)
    }
    

相关内容

  • 没有找到相关文章

最新更新