在进行Spark ALS算法进行试验的时候发现模型对所有用户其推荐结果是一样的,即针对所有用户建模得到的模型对其推荐的项目是一样的,只是评分有比较小的差异。下面就分3个部分来进行分析,分别是实验过程及结果描述,ALS算法原理,问题分析及解决。
实验过程及结果
此部分参考:https://databricks-training.s3.amazonaws.com/movie-recommendation-with-mllib.html(里面有两个部分有点问题,下面会有描述,不过也可能是我理解错误了)。1.
上传数据到HDFS,需要上传ratings。dat 文件以及movies.dat文件,上传后到数据如下图所示:
2. 打开Spark shell 进行Spark ALS算法调用;
3. 加载电影信息数据以及评分数据,其代码如下所示:
// 设置日志级别
sc.setLogLevel(“WARN”)
// 导入必要的包
import org.apache.spark.mllib.recommendation._
// 加载movies 数据到map
val movies = sc.textFile("/user/root/als/movies.dat").map{line => val fields = line.split("::") ; (fields(0).toInt,fields(1))}.collect.toMap
// 加载评分数据
val ratings = sc.textFile("/user/root/als/ratings.dat").map{line => val fields = line.split("::");val rating = Rating(fields(0).toInt,fields(1).toInt,fields(2).toDouble);val timestamp = fields(3).toLong %10; (timestamp,rating)}
// 输出统计信息
println(ratings.count)
println(ratings.map(_._2.user).distinct.count)
println(ratings.map(_._2.product).distinct.count)
4. 分割数据到训练集和测试集,其代码如下所示:
// 分训练集
val training = ratings.filter(x=>x._1<6).values.cache()
// 分测试集
val test = ratings.filter(x=>x._1>=6).values.cache()
training.count
test.count
5. 设置参数,进行建模,其代码如下所示:
val rank = 10
val lambda = 10.0
val iter = 20
val model = ALS.train(training,rank,iter,lambda)
6. 编写均方根误差函数,并对测试数据集求其均方误差根,其代码如下所示:
// 建立均方根误差函数
import org.apache.spark.rdd.RDD
def computeRMSE(model:MatrixFactorizationModel, data:RDD[Rating]): Double = {
val usersProducts = data.map(x=>(x.user,x.product))
val ratingsAndPredictions = data.map{case Rating(user,product,rating)=>((user,product),rating)}.join(model.predict(usersProducts).map{case Rating(user,product,rating)=>((