我正在尝试使用scala实现k-means方法。 我创建了类似的RDD
val df = sc.parallelize(data).groupByKey().collect().map((chunk)=> {
sc.parallelize(chunk._2.toSeq).toDF()
})
val examples = df.map(dataframe =>{
dataframe.selectExpr(
"avg(time) as avg_time",
"variance(size) as var_size",
"variance(time) as var_time",
"count(size) as examples"
).rdd
})
val rdd_final=examples.reduce(_ union _)
val kmeans= new KMeans()
val model = kmeans.run(rdd_final)
使用此代码我会收到错误
type mismatch;
[error] found : org.apache.spark.rdd.RDD[org.apache.spark.sql.Row]
[error] required:org.apache.spark.rdd.RDD[org.apache.spark.mllib.linalg.Vector]
所以我试着去做:
val rdd_final_Vector = rdd_final.map{x:Row => x.getAs[org.apache.spark.mllib.linalg.Vector](0)}
val model = kmeans.run(rdd_final_Vector)
但后来我得到了一个错误:
java.lang.ClassCastException: java.lang.Double cannot be cast to org.apache.spark.mllib.linalg.Vector
所以我正在寻找一种方法来进行演员表,但我找不到任何方法。
有什么想法吗?
祝你好运
答案 0 :(得分:1)
至少有几个问题:
Spark SQL
理解的潜在不同类型的集合。 Vector
不是本机spark sql类型KMeans
尝试实现的内容之间似乎不匹配:SQL正在执行聚合。但是KMeans
期望一个单独的数据点形式为Vector(它封装了Array[Double]
)。那么 - 为什么要将sum
和average
提供给KMeans
操作?在这里解决#1问题:你需要做一些事情:
val doubVals = <rows rdd>.map{ row => row.getDouble("colname") }
val vector = Vectors.toDense{ doubVals.collect}
然后你有一个正确封装的Array[Double]
(在Vector中),可以提供给Kmeans
。