Scala 将[(Int,Seq[Double])]RDD转换为标签点

Scala 将[(Int,Seq[Double])]RDD转换为标签点,scala,apache-spark,apache-spark-mllib,Scala,Apache Spark,Apache Spark Mllib,我有一个以下格式的RDD,希望将其转换为LabeledPoint RDD,以便在mllib中处理它: Test: RDD[(Int, Seq[Double])] = Array((1,List(1.0,3.0,8.0),(2,List(3.0, 3.0,8.0),(1,List(2.0,3.0,7.0),(1,List(5.0,5.0,9.0)) 我试着用地图 import org.apache.spark.mllib.linalg.{Vector, Vectors} import org.a

我有一个以下格式的RDD,希望将其转换为LabeledPoint RDD,以便在mllib中处理它:

Test: RDD[(Int, Seq[Double])] = Array((1,List(1.0,3.0,8.0),(2,List(3.0, 3.0,8.0),(1,List(2.0,3.0,7.0),(1,List(5.0,5.0,9.0))
我试着用地图

import org.apache.spark.mllib.linalg.{Vector, Vectors}
import org.apache.spark.mllib.regression.LabeledPoint
Test.map(x=> LabeledPoint(x._1, Vectors.sparse(x._2)))
但是我得到了这个错误

mllib.linalg.Vector cannot be applied to (Seq[scala.Double])

因此,可能需要首先转换Seq元素,但我不知道转换成什么。

这里有一些问题:

  • 标签应为
    Double
    not
    Int
  • SparseVector
    需要大量的元素、索引和值
  • 没有一个向量构造函数接受
    Double
  • 您的数据看起来密集而不是稀疏
一种可能的解决办法:

val rdd = sc.parallelize(Array(
    (1, List(1.0,3.0,8.0)),
    (2, List(3.0, 3.0,8.0)),
    (1, List(2.0,3.0,7.0)),
    (1, List(5.0,5.0,9.0))))

rdd.map { case (k, vs) => 
  LabeledPoint(k.toDouble, Vectors.dense(vs.toArray))
}
还有一个:

rdd.collect { case (k, v::vs) =>
  LabeledPoint(k.toDouble, Vectors.dense(v, vs: _*)) }
正如您在其构造函数中所注意到的,它接收一个
双精度
作为标签和一个As特性(或)。但是,如果查看两个继承类的构造函数,它们都会收到一个
数组
,因此需要将
Seq
转换为
数组

import org.apache.spark.mllib.linalg.{Vector,Vectors,DenseVector}
导入org.apache.spark.mllib.regression.LabeledPoint
val rdd=sc.parallelize(数组((1,Seq(1.0,3.0,8.0)),
(2,Seq(3.0,3.0,8.0)),
(1,Seq(2.0,3.0,7.0)),
(1,Seq(5.0,5.0,9.0)))
valx=rdd.map{
案例(a:Int,b:Seq[Double])=>LabeledPoint(a,新DenseVector(b.toArray))
}
x、 以(2)为例。foreach(println)
//(1.0,[1.0,3.0,8.0])
//(2.0,[3.0,3.0,8.0])