7

我在某处读到 MLlib 本地向量/矩阵当前正在包装 Breeze 实现,但是将 MLlib 转换为 Breeze 向量/矩阵的方法对于 org.apache.spark.mllib 范围是私有的。解决此问题的建议是在 org.apache.spark.mllib.something 包中编写代码。

有一个更好的方法吗?你能举一些相关的例子吗?

谢谢并恭祝安康,

4

6 回答 6

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 以防止在调用这些方法时分配新对象

于 2014-11-15T16:42:42.577 回答
3

我的解决方案是上面@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._
于 2019-01-20T22:32:52.503 回答
2

据我了解,Spark 人不想公开第三方 API(包括 Breeze),以便在他们决定远离它们时更容易更改。

您总是可以在该包中放置一个简单的隐式转换类,然后将其余代码编写在您自己的包中。没有比把所有东西都放在那里好多少,但它让你为什么要这样做更明显。

于 2014-10-31T17:06:06.640 回答
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]
于 2015-02-01T01:25:09.647 回答
1

该解决方案避免将代码放入 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)
    }
于 2017-02-04T21:03:58.937 回答
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
}
于 2018-05-12T21:34:13.167 回答