2017-03-17 67 views
1

我需要每個矩陣元素劃分(I,J)由對角元素(I,i)和換言之(j,j)的如何在火花中標準化矩陣?

所有j的乘積的平方根我需要執行:

mat(i, j) = mat(i, j)/sqrt(mat(i,i)*mat(j,j)) 

所以矩陣:

4 0 12     
0 1 1 
12 0 9 

變爲:

1 0 2     
0 1 1 
2 0 1 

到目前爲止,我所擁有的行/列索引對的列表中有一個權重,我將其轉換爲CoordinateMatrix(以及後來的RowMatrix)。我通過過濾row ==列的元素來提取對角線。

實現這種元素劃分的最佳方式是什麼?

import org.apache.spark.mllib.linalg.distributed.{CoordinateMatrix, MatrixEntry, RowMatrix} 
import scala.math.sqrt 

val pairs = Array((0,0,4.0), (0,2,12.0), (1,1,1.0), (2,0,12.0), (2,2,9.0)) 
val pairs_rdd = sc.parallelize(pairs) 

val diagonal = pairs_rdd.filter(r => r._1 == r._2).map(r => (r._2, sqrt(r._3))) 

val matrixEntries = pairs_rdd.map(r => MatrixEntry(r._1, r._2, r._3)) 

val coordinateMatrix: CoordinateMatrix = new CoordinateMatrix(matrixEntries) 
val rowMatrix: RowMatrix = coordinateMatrix.toRowMatrix() 

回答

2

似乎沒有MLLib基質輔助類的真的可以幫助在這裏,所以唯一的出路似乎是手動與您所創建的對角線(一旦被i通過j你的矩陣的加盟,一旦):

val diagonal: RDD[(Long, Double)] = pairs_rdd.filter(r => r._1 == r._2).map(r => (r._2, r._3)) 

val result = matrixEntries 
    .keyBy(_.i).join(diagonal).values  // join by i coordinate 
    .keyBy(_._1.j).join(diagonal).values // join by j coordinate 
    .map { case ((e, di), dj) => MatrixEntry(e.i, e.j, e.value/sqrt(di * dj)) }