Spark课程设计——电影推荐系统

题目所需数据集及相应信息描述:
数据集:
1、用户评分数据集ratings.dat:包含了大量用户的历史评分数据。
2、样本评分数据集personalRatings.dat:包含了少数几个用户的个性化评分数据,这些数据反映了某个用户的个性化观影喜好。
3、电影数据集movies.dat:包含了每部电影的相关信息。
注意:
之后依次使用数据集1~3表示上述数据集
数据集结构如下:
1、用户ID::电影ID::评分::时间戳
2、用户ID::电影ID::评分::时间戳
3、电影ID::电影名称::电影类型

(1)movies.dat数据集部分展示:
在这里插入图片描述
(2)ratings.dat数据集部分展示:
在这里插入图片描述
题目要求:
1、根据数据集3,计算每年发行电影的数量,并进行可视化(柱状图)。
2、根据数据集1,计算每部电影的平均分,并进行可视化(柱状图)。
3、根据数据集1,将电影评分离散化,[0,2)为差,[2-4)为良好,[4-5)为优秀,并进行可视化(饼图)。
4、根据数据集3,统计每种类型电影的数量(若一个电影有多个分类,选择第一个),并进行可视化(饼图)。
5、根据数据集1、2,自行挑选用户(用户id),使用协同过滤算法为其推荐十部电影,无需可视化,只需运行结果。

实验思路及代码:

(1)第一小题思路(流程图)
在这里插入图片描述
代码:

//计算每年发行电影的数量
 val rdd1 = sc.textFile("C:/Users/ch/Desktop/大学/大三阶段/spark/spark实验/课程设计/题目/实验数据集/movies.txt")
//先将每行元素按照::进行分割,然后取出包含年份的那个字段
 val rdd2 = rdd1.map(line=>line.split("::")(1))
//获取年份(使用两次反转)
 val rdd3 = rdd2.map(line=>line.reverse.take(5))
 val rdd4 = rdd3.map(line=>line.reverse.take(4))
//计算每年发行电影的数量
val rdd_result = rdd4.map(word=>(word,1)).reduceByKey(_+_)
//进行格式化
val rdd_show = rdd_result.map(line=>line._1+"年,有"+line._2+"份电影")
//将结果输出到文件夹当中
rdd_show.saveAsTextFile("C:/Users/ch/Desktop/大学/大三阶段/spark/spark实验/课程设计/题目/实验数据集/Test1")

结果展示:
在这里插入图片描述

(2)第二小题思路
在这里插入图片描述
代码:

//提取每个电影以及对应的评分,形成一个元组
val rdd3_2 = rdd3_1.map(line=>(line.split("::")(1),line.split("::")(2).toInt))
//对应rdd3_2的value进行操作,key不动
val rdd3_3 = rdd3_2.mapValues(x=>(x,1))
//将相同的电影的评分进行求平均
val rdd3_4 = rdd3_3.reduceByKey((x,y)=>(x._1+y._1,x._2+y._2)).mapValues(x=>x._1/x._2)
//将结果进行保存
rdd3_4.saveAsTextFile("C:/Users/ch/Desktop/大学/大三阶段/spark/spark实验/课程设计/题目/实验数据集/Test3")

结果展示:
在这里插入图片描述

(3)第三小题思路
在这里插入图片描述
代码:

//读取数据
val rdd2_1 = sc.textFile("C:/Users/ch/Desktop/大学/大三阶段/spark/spark实验/课程设计/题目/实验数据集/ratings.txt")
//获取评分 
val rdd2_2 = rdd2_1.map(line=>line.split("::")(2))
//将评分转化为整数
val rdd2_3 = rdd2_2.map(line=>line.toInt)
//对评分进行离散化
val rdd2_4 = rdd2_3.map(line=>if (line>=0&&line<2) "差" else if(line>=2&&line<4) "良好" else if(line>=4&&line<=5) "优秀")
//将结果进行统计
 val rdd2_5 = rdd2_4.map(line=>(line,1)).reduceByKey(_+_)
//将结果进行展示
rdd2_5.foreach(println)

结果展示:
在这里插入图片描述

(4)第四小题思路:
在这里插入图片描述
代码:

//对movies数据集进行读取
val rdd4_1 = sc.textFile("C:/Users/ch/Desktop/大学/大三阶段/spark/spark实验/课程设计/题目/实验数据集/movies.txt")
//转换成只包含类型数据的RDD
 val rdd4_2 = rdd4_1.map(line=>line.split("::")(2))
//当遇到一个电影有多个类型的时候只选取其中第一个类型
val rdd4_3 = rdd4_2.map(line=>line.split(",")(0))
//统计每种类型电影的数量
 val rdd4_4 = rdd4_3.map(line=>(line,1)).reduceByKey(_+_)
//将数据保存
 rdd4_4.saveAsTextFile("C:/Users/ch/Desktop/大学/大三阶段/spark/spark实验/课程设计/题目/实验数据集/Test4")

结果展示:
在这里插入图片描述

(5)第五小题思路:
在这里插入图片描述
代码:

//导入文件生成RDD
val rdd5_1 = sc.textFile("C:/Users/ch/Desktop/大学/大三阶段/spark/spark实验/课程设计/题目/实验数据集/ratings.txt"
)
//定义样例类,用来隐式转换
case class Rating(userId:Int,movieId:Int,rating:Float,timestamp:Long)
//反射机制推断RDD来生成DataFrame
val rdd5_2 = rdd5_1.map(line=>Rating(line.split("::")(0).toInt,line.split("::")(1).toInt,line.split("::")(2).toFloat,line.split("::")(3).toLong)).toDF()
//将数据集按4:1划分成训练集和测试集
val Array(train,test) = rdd5_2.randomSplit(Array(0.8,0.2))
//创建model
val model = new ALS().setMaxIter(10).setRegParam(0.03).setUserCol("userId").setItemCol("movieId").setRatingCol("rating")
//训练生成模型
val train_model = model.fit(train)
//模型进行测试
val test_rdd = train_model.transform(test)
//注册为临时表
test_rdd.createOrReplaceTempView("result")
//查找用户id为1的
val result_rdd = spark.sql("select userId,movieId,prediction as rating from result where userId=1")
//按照rating进行降序排列
result_rdd.sort(result_rdd("rating").desc).show()
//读取movies文件
 val movie_rdd = sc.textFile("C:/Users/ch/Desktop/大学/大三阶段/spark/spark实验/课程设计/题目/实验数据集/movies.tx
t")
//创建样例类进行隐式转换
 case class Movie(movieId:Int,name:String,movieType:String)
val movie_DF = movie_rdd.map(line=>Movie(line.split("::")(0).toInt,line.split("::")(1),line.split("::")(2))).toDF()
//将用户表进行注册
val user_movie = result_rdd.sort(result_rdd("rating").desc)
//注册为临时表
movie_DF.createOrReplaceTempView("movie")
user_movie.createOrReplaceTempView("user")
//两张表进行关联
scala> val result = spark.sql("select movieId,name from movie where movieId = 1287 or movieId=1035 or movieId=3105 or movieId=2355 or movieId=150 or movieId=1 or movieId=1961 or movieId=1028 or movieId=1029 or movieId=1270")
//结果展示(为用户1推荐的电影)
result.map(line=>"MovieId:"+line(0)+","+"MovieName:"+line(1)).show()
result.map(line=>"MovieName:"+line(1)).show()
result.show()

结果展示:
在这里插入图片描述

  • 14
    点赞
  • 150
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值