Spark RDD实现电影流行度分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012848709/article/details/85647697

楔子

学习《spark大数据商业实战》第12章节,统计所有电影平均得分最高的前10部电影

数据说明

数据下载 CSDN位置
或者在此处下载

详细github代码

1:用户文件users.dat---------------------------------------
UserID::Gender::Age::OccupationID::Zip-code
用户id   性别M是男性 年龄  职业     邮编

2:ratings.dat---------------------------------------------
UserID::MovieID::Rating::Timestamp
用户ID   电影id评分数据 时间戳
----------------------------------------------------------
3:movies.dat
MovieID::Title::Genres
电影ID 电影名    电影类型

4:职业Occupation.dat--------------------------------------
OccupationID::OccupationName
职业id  职业
推荐系统常用数据集
https://www.cnblogs.com/shenxiaolin/p/8337913.html

思路

分为3步骤:

  1. 把数据变为key-value ,eg (MovieID,(Rating,1))
  2. 通过reduceByKey 汇总,key是MovieID,但是values是(评分总和,点评人数合计) (此处是之前不曾遇到的思路)
  3. sortByKey(false) 倒序排列,在通过take取出前10位

demo

RDD方式

/**
 * 1:RDD实现电影流行度 (1):所有电影中平均得分最高的Top10电影
 * 
 */

private static void rddForMovieTop10(JavaRDD<String> ratRdd) {
	// step 1 把数据变为key-value ,eg (MovieID,(Rating,1))
	JavaPairRDD<String, Tuple2<Long, Long>> mapToPair = ratRdd.mapToPair(new PairFunction<String, String, Tuple2<Long, Long>>() {
		private static final long serialVersionUID = 1L;

		@Override
		public Tuple2<String, Tuple2<Long, Long>> call(String t) throws Exception {
			String[] split = t.split("::");// UserID::MovieID::Rating::Timestamp
			Tuple2<Long, Long> tuple2 = new Tuple2<Long, Long>(Long.valueOf(split[2]), 1L);
			return new Tuple2<String, Tuple2<Long, Long>>(split[1], tuple2);
		}
	});
	// step 2 通过reduceByKey 汇总,key是MovieID,但是values是(评分总和,点评人数合计)
	JavaPairRDD<String, Tuple2<Long, Long>> reduceByKey = mapToPair.reduceByKey(new Function2<Tuple2<Long, Long>, Tuple2<Long, Long>, Tuple2<Long, Long>>() {
		private static final long serialVersionUID = 1L;

		@Override
		public Tuple2<Long, Long> call(Tuple2<Long, Long> v1, Tuple2<Long, Long> v2) throws Exception {
			return new Tuple2<Long, Long>(v1._1 + v2._1, v1._2 + v2._2);
		}
	});
	// step 3 sortByKey(false) 倒序排列
	JavaPairRDD<Double, String> result = reduceByKey.mapToPair(new PairFunction<Tuple2<String, Tuple2<Long, Long>>, Double, String>() {
		@Override
		public Tuple2<Double, String> call(Tuple2<String, Tuple2<Long, Long>> v1) throws Exception {
			// TODO 都是整数 做除法还是整数
			double avg = v1._2._1 * 0.1 / v1._2._2;
			return new Tuple2<Double, String>(avg, v1._1);
		}
	});
	System.out.println("所有电影中平均得分最高的Top10电影 RDD方式");
	result.sortByKey(false).take(10).forEach(t -> System.out.println(t));
}

SparkSQL方式

/**
 * 1:RDD实现电影流行度 (1):所有电影中平均得分最高的Top10电影Bysql
 * 
 */
private static void rddForMovieTop10Bysql(Dataset<Row> ratDF) {
	ratDF.createOrReplaceTempView("t_rat");
	Dataset<Row> sql = sparkSession.sql("select * from ("//
			+ "select avg(rat) rat_avg ,MovieID  from t_rat group by MovieID order by rat_avg desc" //
			+ " ) limit 20");
	System.out.println("所有电影中平均得分最高的Top20电影 SQL方式");
	sql.show();

}

结果如下

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u012848709/article/details/85647697