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
是任何类型)。如果 el
是 null
它 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)
}
我正在尝试 运行 我的数据库中的一种 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
是任何类型)。如果el
是null
它 returnsUnit
- 即使不是您将其分配给
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) }