Scala矢量标量乘法

时间:2015-12-15 20:29:09

标签: scala apache-spark apache-spark-mllib

我正在Apache Spark MLlib中实现一些机器学习算法,我想将矢量与标量相乘:

enter image description here

其中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)

如何正确地进行这种乘法?

2 个答案:

答案 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运算符的原因。