我做的電影recommandation系統,利用現有的MovieLens數據集在這裏: http://grouplens.org/datasets/movielens/OutOfBoundsException與ALS - 弗林克MLlib
要計算該recommandation系統,我用弗林克的ML庫Scala和particulalrly ALS算法(org.apache.flink.ml.recommendation.ALS
)。
我第一次在電影的收視率映射到DataSet[(Int, Int, Double)]
,然後創建一個trainingSet
和testSet
(見下面的代碼)。
我的問題是,當我在整個數據集(所有評級)中使用ALS.fit
函數時沒有任何錯誤,但是如果我只刪除一個評級,那麼fit函數不再有效,而我不明白爲什麼。
你有什麼想法嗎? :)使用
代碼:
Rating.scala
case class Rating(userId: Int, movieId: Int, rating: Double)
PreProcessing.scala
object PreProcessing {
def getRatings(env : ExecutionEnvironment, ratingsPath : String): DataSet[Rating] = {
env.readCsvFile[(Int, Int, Double)](
ratingsPath, ignoreFirstLine = true,
includedFields = Array(0,1,2)).map{r => new Rating(r._1, r._2, r._3)}
}
Processing.scala
object Processing {
private val ratingsPath: String = "Path_to_ratings.csv"
def main(args: Array[String]) {
val env = ExecutionEnvironment.getExecutionEnvironment
val ratings: DataSet[Rating] = PreProcessing.getRatings(env, ratingsPath)
val trainingSet : DataSet[(Int, Int, Double)] =
ratings
.map(r => (r.userId, r.movieId, r.rating))
.sortPartition(0, Order.ASCENDING)
.first(ratings.count().toInt)
val als = ALS()
.setIterations(10)
.setNumFactors(10)
.setBlocks(150)
.setTemporaryPath("/tmp/tmpALS")
val parameters = ParameterMap()
.add(ALS.Lambda, 0.01) // After some tests, this value seems to fit the problem
.add(ALS.Seed, 42L)
als.fit(trainingSet, parameters)
}
}
「但如果我只是刪除只有一個等級」
val trainingSet : DataSet[(Int, Int, Double)] =
ratings
.map(r => (r.userId, r.movieId, r.rating))
.sortPartition(0, Order.ASCENDING)
.first((ratings.count()-1).toInt)
錯誤:
2015年6月19日15時00分24秒協同組(協同組在org.apache.flink.ml.recommendation.ALS $ .updateFactors(ALS.scala:570))(4/4)切換爲FAILED
java.lang.ArrayIndexOutOfBoundsException:5
在org.apache.flink.ml.recommendation.ALS $ BlockRating.apply(ALS.scala:358)
在org.apache.flink.ml.recommendation。 ALS $$匿名$ 111.coGroup(ALS.scala:635)
在org.apache.flink.runtime.operators.CoGroupDriver.run(CoGroupDriver.java:152)
...
謝謝!完美的作品! 只是一個問題:當你使用'persist'時,你將路徑設置爲一個文件。但是'ALS'如何知道這個持久化文件是爲了它而不是爲了程序的其他部分(例如,如果我們必須爲另一個算法「堅持」)呢? – Kerial
'persist'函數調用觸發數據流的執行。因此,存儲在相同路徑下的任何文件都將被覆蓋。只有在觸發後續部分工作時纔會讀取結果。這意味着您可以在理論上刪除或覆蓋此文件。因此,您應該嘗試在算法範圍內分配唯一的文件名。或者,您也可以創建碰撞概率較低的隨機文件名。 –