要求1:根据用户以往的电影评价数据,构建推荐模型,进而对编号为i的用户推荐不少于3部电影,推荐列表中给出电影的编号和预测打分,要求采用HDFS存储输入文件,即给出用户的id列表;输出文件位置也为HDFS 文件系统下的目录,输出文件中每行记录分别包括用户id、推荐列表,如下所示
userId recommendations
[[9,4.471581], [。。。。。。。。。。。。。2,3.9190567], [92,3.5106018]]
[[20,4.571581], [23,3.8190567], [97,3.7106018]]
。。。。。。
要求2:利用sbt,或者maven,或者集成开发环境开发后,能够打包成jar包。要求上传数据集文件到HDFS上存储;要求能够撰写shell脚本执行spark程序。过程需要截图。
要求3:程序要支持分布式集群运行。如果仅仅支持单机运行,只能获得60分。程序代码需要以文本方式粘贴到报告中。运行结果需要截图。
代码:
package top.yanzx
import org.apache.spark._
import org.apache.spark.mllib.recommendation.Rating
import org.apache.spark.mllib.recommendation.ALS
import org.apache.spark.sql.{DataFrame, SparkSession}
import scala.collection.mutable
object MovieRec {
def main(args: Array[String]): Unit = {
// 获取sc
val spark = SparkSession.builder()
.appName("MovieRec")
.getOrCreate()
val sc = spark.sparkContext
// 输入
println("请输入要推荐的用户id列表(以空格分割):")
val userIdStr = Console.readLine()
val userIds = userIdStr.split(" ").toList.map(_.toInt)
println("请输入结果输出路径:")
val outputPath = Console.readLine()
// 文件路径
// val rawData = sc.textFile("C:\\Users\\20924\\Desktop\\ml-100k\\u.data") // 本次测试
val rawData = sc.textFile("./u.data") // hdfs下的 /root/u.data
println(rawData.first())
// 取前三列
val rawRatings = rawData.map(_.split("\t").take(3))
// uid, movie_id, rating
val ratings = rawRatings.map { case Array(user, movie, rating) => Rating(user.toInt, movie.toInt, rating.toDouble) }
// ALS协同过滤训练
val model = ALS.train(ratings, 50, 10, 0.01)
// 取10个
val K1 = 10
val map = mutable.Map[String, String]()
for (userId <- userIds) {
// 推荐电影
val topKRecs = model.recommendProducts(userId, K1)
// 小列表
val li = mutable.ListBuffer[String]()
for (elem <- topKRecs) {
val tempList = List(elem.product.toString, elem.rating.toString)
li.append(tempList.mkString("[", ", ", "]"))
}
println("=======================================================")
println(li)
println("=======================================================")
// 格式化
map(userId.toString) = li.mkString("[", ", ", "]")
}
println(map.toString())
// 存储文件
sc.makeRDD(map.toList).saveAsTextFile(outputPath)
println("==已保存==")
}
}