web-dev-qa-db-ja.com

2つのRDD [mllib.linalg.Vector]の追加

2つのファイルに保存されている2つの行列を追加する必要があります。

latest1.txtおよびlatest2.txtのコンテンツには、次のstrがあります。

 1 2 3 
 4 5 6 
 7 8 9 

私はそれらのファイルを次のように読んでいます:

scala> val rows = sc.textFile(“latest1.txt”).map { line => val values = line.split(‘ ‘).map(_.toDouble)
    Vectors.sparse(values.length,values.zipWithIndex.map(e => (e._2, e._1)).filter(_._2 != 0.0))
}

scala> val r1 = rows
r1: org.Apache.spark.rdd.RDD[org.Apache.spark.mllib.linalg.Vector] = MappedRDD[2] at map at :14

scala> val rows = sc.textFile(“latest2.txt”).map { line => val values = line.split(‘ ‘).map(_.toDouble)
    Vectors.sparse(values.length,values.zipWithIndex.map(e => (e._2, e._1)).filter(_._2 != 0.0))
}

scala> val r2 = rows
r2: org.Apache.spark.rdd.RDD[org.Apache.spark.mllib.linalg.Vector] = MappedRDD[2] at map at :14

R1、r2を追加したい。それで、Apache-Sparkにこの2つのRDD[mllib.linalg.Vector]を追加する方法はありますか?.

13
krishna

これは実際には良い質問です。私は定期的にmllibを使用していますが、これらの基本的な線形代数演算に簡単にアクセスできないことに気づいていませんでした。

重要なのは、基礎となるbreezeベクトルには、期待するすべての線形代数操作が含まれているということです。もちろん、具体的に述べた基本的な要素ごとの加算も含まれます。

ただし、そよ風の実装は、次の方法で外界から隠されています。

[private mllib]

では、外界/パブリックAPIの観点から、これらのプリミティブにどのようにアクセスするのでしょうか。

それらのいくつかはすでに公開されています:例:平方和:

/**
 * Returns the squared distance between two Vectors.
 * @param v1 first Vector.
 * @param v2 second Vector.
 * @return squared distance between two Vectors.
 */
def sqdist(v1: Vector, v2: Vector): Double = { 
  ...
}

ただし、このような使用可能なメソッドの選択は制限されています。実際、要素ごとの加算、減算、乗算などの基本的な操作はnot含まれていません。

だからここに私が見ることができる最高のものがあります:

  • ベクトルをそよ風に変換します。
  • 簡単にベクトル演算を実行します
  • そよ風からmllibベクトルに変換し直します

サンプルコードは次のとおりです。

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]
19
javadba

次のコードは、SparkのasBreezeメソッドとfromBreezeメソッドを公開しています。このソリューションは、_vector.toArray_を使用するのとは対照的に、SparseVectorをサポートします。 Sparkは将来APIを変更する可能性があり、すでにtoBreezeの名前をasBreezeに変更していることに注意してください。

_package org.Apache.spark.mllib.linalg
import breeze.linalg.{Vector => BV}
import org.Apache.spark.sql.functions.udf

/** expose vector.toBreeze and Vectors.fromBreeze
  */
object VectorUtils {

  def fromBreeze(breezeVector: BV[Double]): Vector = {
    Vectors.fromBreeze( breezeVector )
  }

  def asBreeze(vector: Vector): BV[Double] = {
    // this is vector.asBreeze in Spark 2.0
    vector.toBreeze
  }

  val addVectors = udf {
    (v1: Vector, v2: Vector) => fromBreeze( asBreeze(v1) + asBreeze(v2) )
  }

}
_

これにより、df.withColumn("xy", addVectors($"x", $"y"))を実行できます。

2
Jussi Kujala