1

Q是一個分佈式的行矩陣中的星火,我想計算的Q跨產品與它的轉Q'如何計算Apache Spark中兩個分佈式RowMatrix的點積?

儘管行矩陣確實有一個multiply()方法,但它只能接受局部矩陣作爲參數。

碼圖(斯卡拉):

val phi = new RowMatrix(phiRDD)   // phiRDD is an instance of RDD[Vector] 
val phiTranspose = transposeRowMatrix(phi) // transposeRowMatrix() 
              // returns the transpose of a RowMatrix 
val crossMat = ?       // phi * phiTranspose 

注意,我想執行分佈式RowMatrix的 點積不是分佈式一個與當地的一個。

一種解決方案是使用一個IndexedRowMatrix如下:

val phi = new IndexedRowMatrix(phiRDD) // phiRDD is an instance of RDD[IndexedRow] 
val phiTranspose = transposeMatrix(phi) // transposeMatrix() 
             // returns the transpose of a Matrix 
val crossMat = phi.toBlockMatrix().multiply(phiTranspose.toBlockMatrix() 
              ).toIndexedRowMatrix() 

然而,我要使用的行矩陣的方法,例如tallSkinnyQR()並且這意味着我sholud變換crossMat到RowMatrix,使用.toRowMatrix()方法:

val crossRowMat = crossMat.toRowMatrix() 

終於我可以申請

crossRowMat.tallSkinnyQR() 

但這個過程包括各類分佈式矩陣,並根據我從MLlib Programming Guide明白這是昂貴之間的許多變革:

選擇合適的格式存儲大和分佈是非常重要的矩陣。將分佈式矩陣轉換爲不同的格式可能需要全局洗牌,這非常昂貴。

請問有人詳細說明。

回答

2

只支持矩陣乘矩陣的分佈矩陣是BlockMatrices。你有你的數據相應的轉換 - 人工指標是不夠好:

new IndexedRowMatrix(
    rowMatrix.rows.zipWithIndex.map(x => IndexedRow(x._2, x._1)) 
).toBlockMatrix match { case m => m.multiply(m.transpose) } 
+0

請您檢查我的更新版本。 – user8547317

1

我用這個page從積用向量外積移動乘法問題分佈式標產品的問題列出的算法:

兩個矢量之間的外積是與所述第一向量的所有元素的 第二向量的標量積,導致 矩陣

我自己爲Row Matrices創建的乘法函數(可以更優化)就這樣結束了。

def multiplyRowMatrices(m1: RowMatrix, m2: RowMatrix)(implicit ctx: SparkSession): RowMatrix = { 

// Zip m1 columns with m2 rows 
val m1Cm2R = transposeRowMatrix(m1).rows.zip(m2.rows) 

// Apply scalar product between each entry in m1 vector with m2 row 
val scalar = m1Cm2R.map{ 
case(column:DenseVector,row:DenseVector) => column.toArray.map{ 
    columnValue => row.toArray.map{ 
    rowValue => columnValue*rowValue 
    } 
} 
} 

// Add all the resulting matrices point wisely 
val sum = scalar.reduce{ 
case(matrix1,matrix2) => matrix1.zip(matrix2).map{ 
    case(array1,array2)=> array1.zip(array2).map{ 
    case(value1,value2)=> value1+value2 
    } 
} 
} 

new RowMatrix(ctx.sparkContext.parallelize(sum.map(array=> Vectors.dense(array)))) 
} 

之後,我測試了approaches-我自己的功能和使用塊矩陣 - 採用300×10矩陣一個機

上使用我自己的函數:

val PhiMat = new RowMatrix(phi) 
val TphiMat = transposeRowMatrix(PhiMat) 
val product = multiplyRowMatrices(PhiMat,TphiMat) 

使用矩陣轉型:

val MatRow = new RowMatrix(phi) 
val MatBlock = new IndexedRowMatrix(MatRow.rows.zipWithIndex.map(x => IndexedRow(x._2, x._1))).toBlockMatrix() 
val TMatBlock = MatBlock.transpose 
val productMatBlock = MatBlock.multiply(TMatBlock) 
val productMatRow = productMatBlock.toIndexedRowMatrix().toRowMatrix() 

第一種方法跨越1祚b5個階段和花費2s完成總計。而第二種方法跨越4就業三連一個階段一個兩個階段,並在總帶着0.323s。第二種方法在Shuffle Read/Write大小方面也超過第一種。

但我仍然由MLlib Programming指南聲明困惑:

選擇合適的格式存儲大和 分佈矩陣是非常重要的。將分佈式矩陣轉換爲不同的 格式可能需要全局洗牌,這非常昂貴。