【大数据 Spark】利用电影观看记录数据,进行电影推荐
利用电影观看记录数据,进行电影推荐。

准备
1、任务描述:
在推荐领域有一个著名的开放测试集,下载链接是:http://grouplens.org/datasets/movielens/,该测试集包含三个文件,分别是ratings.dat、sers.dat、movies.dat,具体介绍可阅读:README.txt。
请编程实现:通过连接ratings.dat和movies.dat两个文件得到平均得分超过4.0的电影列表,采用的数据集是:ml-1m

2、数据下载
下载(大小约为5.64M)后解压,会有movies.dat、ratings.dat、ReadMe、users.dat四个文件。
3、部分数据展示
movies.dat 部分数据:
MovieID::Title::Genres
1::Toy Story (1995)::Animation|Children's|Comedy
2::Jumanji (1995)::Adventure|Children's|Fantasy
3::Grumpier Old Men (1995)::Comedy|Romance
4::Waiting to Exhale (1995)::Comedy|Drama
5::Father of the Bride Part II (1995)::Comedy
6::Heat (1995)::Action|Crime|Thriller
7::Sabrina (1995)::Comedy|Romance
8::Tom and Huck (1995)::Adventure|Children's
9::Sudden Death (1995)::Action
10::GoldenEye (1995)::Action|Adventure|Thriller
11::American President, The (1995)::Comedy|Drama|Romance
12::Dracula: Dead and Loving It (1995)::Comedy|Horror
13::Balto (1995)::Animation|Children's
14::Nixon (1995)::Drama
15::Cutthroat Island (1995)::Action|Adventure|Romance
16::Casino (1995)::Drama|Thriller
17::Sense and Sensibility (1995)::Drama|Romance
18::Four Rooms (1995)::Thriller
19::Ace Ventura: When Nature Calls (1995)::Comedy
20::Money Train (1995)::Action
ratings.dat 部分数据:
UserID::MovieID::Rating::Timestamp
1::1193::5::978300760
1::661::3::978302109
1::914::3::978301968
1::3408::4::978300275
1::2355::5::978824291
1::1197::3::978302268
1::1287::5::978302039
1::2804::5::978300719
1::594::4::978302268
1::919::4::978301368
1::595::5::978824268
1::938::4::978301752
1::2398::4::978302281
1::2918::4::978302124
1::1035::5::978301753
1::2791::4::978302188
1::2687::3::978824268
1::2018::4::978301777
1::3105::5::978301713
1::2797::4::978302039
实操
将我们刚刚下载的数据存放到我们的项目中,项目目录结构如下,创建我们的主程序movie.scala

1、设置输入输出路径
这里使用数组保存我们的输入输出文件,方便后面的修改以及使用
val files = Array("src/main/java/day_20200425/data/movies.dat",
"src/main/java/day_20200425/data/ratings.dat",
"src/main/java/day_20200425/output")
2、配置spark
val conf = new SparkConf().setAppName("SparkJoin").setMaster("local")
val sc = new SparkContext(conf)
3、读取Rating文件
读取Ratings.dat文件,根据其内容格式我们将其用::分隔开两个部分,最后计算出电影评分。
// Read rating file
val textFile = sc.textFile(files(1))
//提取(movieid, rating)
val rating = textFile.map(line => {
val fileds = line.split("::")
(fileds(1).toInt, fileds(2).toDouble)
})
//get (movieid,ave_rating)
val movieScores = rating
.groupByKey()
.map(data => {
val avg = data._2.sum / data._2.size
(data._1, avg)
})
4、读取movie文件
Join操作的结果(ID,((ID,Rating),(ID,MovieName)))
RDD的keyBy(func)实际上是为每个RDD元素生成一个增加了key的<key,value>
由于有时候数据的列数很多,不只是按一项作为key来排序,有时候需要对其中两项进行排序,Spark的RDD提供了keyBy的方法。
val movies = sc.textFile(files(0))
val movieskey = movies.map(line => {
val fileds = line.split("::")
(fileds(0).toInt, fileds(1)) //(MovieID,MovieName)
}).keyBy(tup => tup._1)
5、保存结果
保存评分大于4的电影
val result = movieScores
.keyBy(tup => tup._1)
.join(movieskey)
.filter(f => f._2._1._2 > 4.0)
.map(f => (f._1, f._2._1._2, f._2._2._2))
// .foreach(s =>println(s))
val file = new File(files(2))
if(file.exists()){
deleteDir(file)
}
result.saveAsTextFile(files(2))
6、结果
他会自动生成output文件夹,里面有四个文件,_SUCECCESS代表成功的意思,里面没有任何内容,part-00000就是我们的需要的数据。

部分结果:
(1084,4.096209912536443,Bonnie and Clyde (1967))
(3007,4.013559322033898,American Movie (1999))
(2493,4.142857142857143,Harmonists, The (1997))
(3517,4.5,Bells, The (1926))
(1,4.146846413095811,Toy Story (1995))
(1780,4.125,Ayn Rand: A Sense of Life (1997))
(2351,4.207207207207207,Nights of Cabiria (Le Notti di Cabiria) (1957))
(759,4.101694915254237,Maya Lin: A Strong Clear Vision (1994))
(1300,4.1454545454545455,My Life as a Dog (Mitt liv som hund) (1985))
(1947,4.057818659658344,West Side Story (1961))
(2819,4.040752351097178,Three Days of the Condor (1975))
(162,4.063136456211812,Crumb (1994))
(1228,4.1875923190546525,Raging Bull (1980))
(1132,4.259090909090909,Manon of the Spring (Manon des sources) (1986))
(306,4.227544910179641,Three Colors: Red (1994))
(2132,4.074074074074074,Who's Afraid of Virginia Woolf? (1966))
(720,4.426940639269406,Wallace & Gromit: The Best of Aardman Animation (1996))
(2917,4.031746031746032,Body Heat (1981))
(1066,4.1657142857142855,Shall We Dance? (1937))
(2972,4.015384615384615,Red Sorghum (Hong Gao Liang) (1987))
你可能会遇到的问题
问题一:结果输出目录已存在
描述:
Exception in thread "main" org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory file:/D:/Projects/JAVA/Scala/src/main/java/day_20200425/data/output already exist
分析:由于运行,然后输出文件夹已存在,则需要删除该目录
解决:方法一:手动删除、方法二:加入以下代码
1、主程序中
val file = new File(files(2))
if(file.exists()){
deleteDir(file)
}
2、删除函数
/**
* https://www.cnblogs.com/honeybee/p/6831346.html
* 删除一个文件夹,及其子目录
*
* @param dir 目录
*/
def deleteDir(dir: File): Unit = {
val files = dir.listFiles()
files.foreach(f => {
if (f.isDirectory) {
deleteDir(f)
} else {
f.delete()
println("delete file " + f.getAbsolutePath)
}
})
dir.delete()
println("delete dir " + dir.getAbsolutePath)
}
问题二:缺少hadoop环境变量
描述:
ERROR util.Shell: Failed to locate the winutils binary in the hadoop binary path java.io.IOException
分析:
在windows环境下没有配置hadoop环境的原因。
解决:
下载:https://github.com/amihalik/hadoop-common-2.6.0-bin,并且将其bin目录配置为系统的环境变量(path),然后再代码中加入以下代码,例如我的目录为E:\\Program\\hadoop\\hadoop-common-2.6.0-bin,那么则需要加入:
System.setProperty("hadoop.home.dir", "E:\\Program\\hadoop\\hadoop-common-2.6.0-bin")
【大数据 Spark】利用电影观看记录数据,进行电影推荐的更多相关文章
- 【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习
下了这本<大数据Spark企业级实战版>, 另外还有一本<Spark大数据处理:技术.应用与性能优化(全)> 先看前一篇. 根据书里的前言里面,对于阅读顺序的建议.先看最后的S ...
- 数据库学习任务四:数据读取器对象SqlDataReader、数据适配器对象SqlDataAdapter、数据集对象DataSet
数据库应用程序的开发流程一般主要分为以下几个步骤: 创建数据库 使用Connection对象连接数据库 使用Command对象对数据源执行SQL命令并返回数据 使用DataReader和DataSet ...
- 入门大数据---Spark整体复习
一. Spark简介 1.1 前言 Apache Spark是一个基于内存的计算框架,它是Scala语言开发的,而且提供了一站式解决方案,提供了包括内存计算(Spark Core),流式计算(Spar ...
- 大数据Spark超经典视频链接全集
论坛贴吧等信息发布参考模板 Scala.Spark史上最全面.最详细.最彻底的一整套视频全集(特别是机器学习.Spark Core解密.Spark性能优化.Spark面试宝典.Spark项目案例等). ...
- 《大数据Spark企业级实战 》
基本信息 作者: Spark亚太研究院 王家林 丛书名:决胜大数据时代Spark全系列书籍 出版社:电子工业出版社 ISBN:9787121247446 上架时间:2015-1-6 出版日期:20 ...
- 大数据Spark+Kafka实时数据分析案例
本案例利用Spark+Kafka实时分析男女生每秒购物人数,利用Spark Streaming实时处理用户购物日志,然后利用websocket将数据实时推送给浏览器,最后浏览器将接收到的数据实时展现, ...
- 大数据学习day33----spark13-----1.两种方式管理偏移量并将偏移量写入redis 2. MySQL事务的测试 3.利用MySQL事务实现数据统计的ExactlyOnce(sql语句中出现相同key时如何进行累加(此处时出现相同的单词))4 将数据写入kafka
1.两种方式管理偏移量并将偏移量写入redis (1)第一种:rdd的形式 一般是使用这种直连的方式,但其缺点是没法调用一些更加高级的api,如窗口操作.如果想更加精确的控制偏移量,就使用这种方式 代 ...
- 王家林 大数据Spark超经典视频链接全集[转]
压缩过的大数据Spark蘑菇云行动前置课程视频百度云分享链接 链接:http://pan.baidu.com/s/1cFqjQu SCALA专辑 Scala深入浅出经典视频 链接:http://pan ...
- 大数据 --> Spark与Hadoop对比
Spark与Hadoop对比 什么是Spark Spark是UC Berkeley AMP lab所开源的类Hadoop MapReduce的通用的并行计算框架,Spark基于map reduce算法 ...
随机推荐
- . Number throry
steve 学完了快速幂,现在会他快速的计算:(ij)%d , Alex 作为一个数学大师,给了 steve 一个问题:已知i∈[1,n],j∈[1,m] ,计算满足 (ij)%d=0 的 (i,j) ...
- linux常用命令--文件搜索
find / -name file1 从 '/' 开始进入根文件系统搜索文件和目录 find / -user user1 搜索属于用户 'user1' 的文件和目录 find /home/user1 ...
- element动态添加表头的正确姿势
1. 第一步循环 el-table-column <el-table-column v-if="item.show" v-for="(item, index) in ...
- 使用 PyHamcrest 执行健壮的单元测试
在 测试金字塔 的底部是单元测试.单元测试每次只测试一个代码单元,通常是一个函数或方法. 通常,设计单个单元测试是为了测试通过一个函数或特定分支的特定执行流程,这使得将失败的单元测试和导致失败的 bu ...
- Centos8安装docker-compose
一.首先检查是否有pip 执行命令:piv -V 二.更新pip 执行命令:pip install --upgrade pip 三.下载 setuptools 执行命令 :pip install - ...
- thinkphp5 不使用form,用input+ajax异步上传图片
不支持$this->request->file()获取图片 后台接收文件请使用$_FILE 正文开始: HTML <div class="upload"> ...
- 作业十一——LL(1)文法的判断,递归下降分析程序
作业十一——LL(1)文法的判断,递归下降分析程序 判断是否为LL(1)文法 选取有多个产生式的求select,只有一条产生式的无需求select 同一个非终结符之间求交集,全部判断为空后则为LL(1 ...
- java中wait和sleep的区别
文章目录 Wait和sleep的区别 唤醒wait和sleep java中wait和sleep的区别 在本篇文章中,我们将会讨论一下java中wait()和sleep()方法的区别.并讨论一下怎么使用 ...
- 自动获取时间html代码
<button type="button" onclick="document.getElementById('demo').innerHTML = Date()& ...
- MyBaties一级缓存
2019独角兽企业重金招聘Python工程师标准>>> 一.一级缓存简介 在系统代码的运行中,我们可能会在一个数据库会话中,执行多次查询条件完全相同的Sql,鉴于日常应用的大部分场景 ...