我正在Apache Spark MLlib中实现一些机器学习算法,我想将矢量与标量相乘:
其中u_i_j_m是Double,x_i是向量
我尝试了以下内容:
import breeze.linalg.{ DenseVector => BDV, Vector => BV}
import org.apache.spark.mllib.linalg.{DenseVector, Vectors, Vector}
...
private def runAlgorithm(data: RDD[VectorWithNorm]): = {
...
data.mapPartitions { data_ponts =>
c = Array.fill(clustersNum)(BDV.zeros[Double](dim).asInstanceOf[BV[Double]])
...
data_ponts.foreach { data_point =>
...
u_i_j_m : Double = ....
val temp= data_point.vector * u_i_j_m)
// c(j) = temp
}
}
}
其中VectorWithNorm的定义如下:
class VectorWithNorm(val vector: Vector, val norm: Double) extends Serializable {
def this(vector: Vector) = this(vector, Vectors.norm(vector, 2.0))
def this(array: Array[Double]) = this(Vectors.dense(array))
def toDense: VectorWithNorm = new VectorWithNorm(Vectors.dense(vector.toArray), norm)
}
但是当我构建项目时,我收到以下错误:
错误:value *不是org.apache.spark.mllib.linalg.Vector的成员 val temp =(data_point.vector * u_i_j_m)
如何正确地进行这种乘法?
答案 0 :(得分:4)
不幸的是,Spark-Scala贡献者决定他们不会在Scala中选择基础计算库,即线性代数。在引擎盖下他们使用微风,但Spark Vector上的标量*和+是私有的,以及其他有用的方法。这与python完全不同,你可以使用优秀的numpy线性代数库。争论的焦点是,开发人员已经捉襟见肘了,因为开发停滞不前(如果我没记错的话)微风是可疑的,还有一个替代方案(apache.commons.math),所以他们决定让用户选择你想要使用哪个linalg库在斯卡拉。但是,在社区的一些成员的推动下,现在有一个spark包,它在org.apache.spark.mllib.linalg.Vector
- see here上提供线性代数。
答案 1 :(得分:2)
在您的代码中,您使用的是sparks的Vector特征,而不是breeze的DenseVector,这就是为什么*
成员没有定义data_point.vector
运算符的原因。