我正在尝试在Spark上实现ALS。我使用 ml 类而不是 mllib ,因为CSV文件在一列中包含String。 mllib 中的评级类不接受String作为参数。
我想使用来自 org.apache.spark.mllib.recommendation.MatrixFactorizationModel 类的预测函数,但在运行它时正在 org.apache.spark.rdd.RDD中搜索。
这是我正在使用的代码。
import org.apache.spark.{SparkContext, SparkConf}
import org.apache.spark.ml.recommendation.ALS
import org.apache.spark.ml.recommendation.ALS.Rating
import org.apache.spark.mllib.recommendation.MatrixFactorizationModel
object LoadCsv{
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("Load CSV")
val sc = new SparkContext(conf)
println("READING FILE...............................");
val data = sc.textFile("file.csv")
val ratings = data.map(_.split(',') match { case Array(user, item, rate) =>
Rating[String](user, item, rate.toFloat)
})
//val (userFactors, itemFactors) = ALS.train(ratings)
//Build the recommendation model using ALS
val rank = 10
val numIterations = 10
val model = ALS.train(ratings, rank, numIterations)
// Evaluate the model on rating data
val usersProducts = ratings.map { case Rating(user, product, rate) =>
(user, product)
}
// GETTING ERROR OVER HERE.
val predictions =
model.predict(usersProducts).map { case Rating(user, product, rate) =>
((user, product), rate)
}
val ratesAndPreds = ratings.map { case Rating(user, product, rate) =>
((user, product), rate)
}.join(predictions)
val MSE = ratesAndPreds.map { case ((user, product), (r1, r2)) =>
val err = (r1 - r2)
err * err
}.mean()
println("Mean Squared Error = " + MSE)
// Save and load model
//model.save(sc, "/home/shishir/spark-Projects/op")
//val sameModel = MatrixFactorizationModel.load(sc, "target/tmp/myCollaborativeFilter")
// $example off$
}
}
在运行代码时,我收到此错误:
LoadCsv.scala:34: value predict is not a member of (org.apache.spark.rdd.RDD[(String, Array[Float])], org.apache.spark.rdd.RDD[(String, Array[Float])])
[error] model.predict(usersProducts).map { case Rating(user, product, rate) =>
答案 0 :(得分:1)
您的导入是"不正确",您使用的是:
import org.apache.spark.ml.recommendation.ALS
import org.apache.spark.ml.recommendation.ALS.Rating
当你应该使用它时:
import org.apache.spark.mllib.recommendation.ALS
import org.apache.spark.mllib.recommendation.Rating
您可以使用其他套餐,只是结果不会成为模型,但(如错误所示)和RDD。
你可以在线阅读为什么有两个ML包(我记得mllib
包是旧的包并且包含一些设计缺陷,所以它们在ml
重新实现,所以他们可以使用管道)
答案 1 :(得分:1)
看起来你正在混合MLLib和ML风格的方法。如果您的数据使用支持的ID类型(在这里看起来不是这样),您可以使用MLLib实现:
import org.apache.spark.mllib.recommendation.{ALS => OldALS}
import org.apache.spark.mllib.recommendation.{
MatrixFactorizationModel => OldModel}
import org.apache.spark.mllib.recommendation.{Rating => OldRating}
val ratings: RDD[OldRating] = ???
val model: OldModel = OldALS()
.setAlpha(0.01)
.setIterations(numIterations)
.setRank(rank)
.run(ratings)
如果您的数据使用非标准ID并且您希望访问用户友好的API,最好使用DataFrames
:
val ratings: RDD[org.apache.spark.ml.recommendation.ALS.Rating[String]] = ???
val df = ratings.toDF
val als: org.apache.spark.ml.recommendation.ALS = new ALS()
.setAlpha(0.01)
.setMaxIter(numIterations)
.setRank(rank)
val model: org.apache.spark.ml.recommendation.ALSModel = als.fit(df)
最后,您可以使用当前的方法,但是您必须直接操作用户因素和项目因素而不需要predict
等帮助程序。