这是我在这里的第一篇文章,我希望我能正确遵循这些指导原则。
我目前正在使用spark.mllib.recommendation.Rating
的RDD(key1,key2,value),我想将Spark的MLLib SVD应用于in this example。为此,我需要创建一个(稀疏的)RowMatrix
。我可以通过应用
val inputData = data.map{ case Rating(key1, key2, ecpm) => (key1, key2, ecpm)}
// Number of columns
val nCol = inputData.map(_._2).distinct().count().toInt
// Construct rows of the RowMatrix
val dataRows = inputData.groupBy(_._1).map[(Long, Vector)]{ row =>
val (indices, values) = row._2.map(e => (e._2, e._3)).unzip
(row._1, new SparseVector(nCol, indices.toArray, values.toArray))
}
// Compute 20 largest singular values and corresponding singular vectors
val svd = new RowMatrix(dataRows.map(_._2).persist()).computeSVD(20, computeU = true)
我的问题是,当我尝试运行此代码时,出现以下错误:
org.apache.spark.SparkException: Job aborted due to stage failure: Task 72 in stage 12.0 failed 4 times, most recent failure: Lost task 72.3 in stage 12.0 (TID 2329, spark7): Java.lang.ArrayIndexOutOfBoundsException: 1085194
我想这个ArrayIndexOutOfBoundsException
错误来自于我的key1
和key2
键是可能很大的整数(对于RowMatrix
来说太大了对象索引)。所以我试图做的是将新索引分配给key1
和key2
,它们分别位于[1,n_key1]和[1,n_key2]中。我使用zipWithIndex
或zipWithUniqueId
等方法看过一些相关主题(例如this one或this one),但我不认为这对我的情况有帮助。我正在考虑应用像
inputData.map{(key1, key2, value) => key1}.distinct().zipWithIndex()
和key2
相同。这会给我两个键的索引,但后来我不知道如何恢复与inputData
形状相同的RDD。我是Scala / Spark的新手,我想不出办法。但是,如何解决我的问题,即如何用我的RDD中的某些索引替换key1
和key2
键?请注意,key1
和key2
并非所有样本都是唯一的,可能会重复。
编辑:我的数据如下:
scala> data.take(5)
res3: Array[org.apache.spark.mllib.recommendation.Rating] = Array(Rating(39150941,1020026,0.0), Rating(33640847,1029671,0.0), Rating(7447392,988161,0.0), Rating(41696301,1130435,0.0), Rating(42941712,461150,0.0))