我已经读过MLlib局部向量/矩阵当前正在包装Breeze实现的地方,但是将MLlib转换为Breeze向量/矩阵的方法对于org.apache.spark.mllib范围是私有的。解决这个问题的建议是在org.apache.spark.mllib.something包中编写代码。
有更好的方法吗?你能举出一些相关的例子吗?
谢谢和问候,
答案 0 :(得分:4)
我做了与@dlwh建议相同的解决方案。以下是执行此操作的代码:
package org.apache.spark.mllib.linalg
object VectorPub {
implicit class VectorPublications(val vector : Vector) extends AnyVal {
def toBreeze : breeze.linalg.Vector[scala.Double] = vector.toBreeze
}
implicit class BreezeVectorPublications(val breezeVector : breeze.linalg.Vector[Double]) extends AnyVal {
def fromBreeze : Vector = Vectors.fromBreeze(breezeVector)
}
}
注意隐式类扩展AnyVal以防止在调用这些方法时分配新对象
答案 1 :(得分:2)
据我了解,Spark人员不希望公开第三方API(包括Breeze),以便在他们决定离开时更容易改变。
您总是可以在该包中放置一个简单的隐式转换类,并将其余代码写入您自己的包中。只是把所有东西都放在那里要好得多,但是为什么你这样做会更明显。
答案 2 :(得分:2)
我的解决方案是上面@barclar和@lev的混合。如果您不使用spark-ml隐式转换,则不需要 将代码放在org.apache.spark.mllib.linalg
中。您可以在自己的程序包中定义自己的隐式转换,例如:
package your.package
import org.apache.spark.ml.linalg.DenseVector
import org.apache.spark.ml.linalg.SparseVector
import org.apache.spark.ml.linalg.Vector
import breeze.linalg.{DenseVector => BDV, SparseVector => BSV, Vector => BV}
object BreezeConverters
{
implicit def toBreeze( dv: DenseVector ): BDV[Double] =
new BDV[Double](dv.values)
implicit def toBreeze( sv: SparseVector ): BSV[Double] =
new BSV[Double](sv.indices, sv.values, sv.size)
implicit def toBreeze( v: Vector ): BV[Double] =
v match {
case dv: DenseVector => toBreeze(dv)
case sv: SparseVector => toBreeze(sv)
}
implicit def fromBreeze( dv: BDV[Double] ): DenseVector =
new DenseVector(dv.toArray)
implicit def fromBreeze( sv: BSV[Double] ): SparseVector =
new SparseVector(sv.length, sv.index, sv.data)
implicit def fromBreeze( bv: BV[Double] ): Vector =
bv match {
case dv: BDV[Double] => fromBreeze(dv)
case sv: BSV[Double] => fromBreeze(sv)
}
}
然后,您可以使用以下命令将这些隐式导入到您的代码中:
import your.package.BreezeConverters._
答案 3 :(得分:1)
这是我迄今为止最好的。请注意@dlwh:请提供您可能对此进行的任何改进。
我可以提出的解决方案 - 没有将代码放在mllib .linalg包中 - 是将每个Vector转换为新的Breeze DenseVector。
val v1 = Vectors.dense(1.0, 2.0, 3.0)
val v2 = Vectors.dense(4.0, 5.0, 6.0)
val bv1 = new DenseVector(v1.toArray)
val bv2 = new DenseVector(v2.toArray)
val vectout = Vectors.dense((bv1 + bv2).toArray)
vectout: org.apache.spark.mllib.linalg.Vector = [5.0,7.0,9.0]
答案 4 :(得分:0)
此解决方案避免将代码放入Spark的包中,并避免将稀疏转换为密集向量:
def toBreeze(vector: Vector) : breeze.linalg.Vector[scala.Double] = vector match {
case sv: SparseVector => new breeze.linalg.SparseVector[Double](sv.indices, sv.values, sv.size)
case dv: DenseVector => new breeze.linalg.DenseVector[Double](dv.values)
}
答案 5 :(得分:0)
这是一种将Mlib DenceMatrix转换为微风矩阵的方法,也许有帮助!!
import breeze.linalg._
import org.apache.spark.mllib.linalg.Matrix
def toBreez(X:org.apache.spark.mllib.linalg.Matrix):breeze.linalg.DenseMatrix[Double] = {
var i=0;
var j=0;
val m = breeze.linalg.DenseMatrix.zeros[Double](X.numRows,X.numCols)
for(i <- 0 to X.numRows-1){
for(j <- 0 to X.numCols-1){
m(i,j)=X.apply(i, j)
}
}
m
}