大数据项目2a:基于spark的电影推荐和分析系统设计与实现

  • 1、项目目的

本项目的目的是设计并实现一个基于Spark的电影推荐系统,以应对大数据环境下电影推荐服务的挑战。通过整合电影、评分和用户数据集,并利用SparkSql框架进行高效处理,系统能够为用户提供个性化的电影推荐。项目采用多种先进技术,包括Java、Maven、SparkSparkSql、MySQL、Spring Boot和MyBatis等,以确保系统的稳定性和可扩展性。

作为毕业设计项目,本项目旨在通过实现离线推荐、热门推荐和最新推荐等模块,提升系统的推荐效果和用户体验。同时,项目还将进行深入的统计分析,包括电影评分分布、电影年份分布、不同分段占比、不同评分段的类型占比、不同类型演员前5名称以及电影国家分布占比等,以提供有价值的数据洞察和业务指导。通过本项目的实施,不仅可以锻炼和提升我的专业技能和综合素质,还可以为电影推荐领域的发展做出一定的贡献。

2、项目介绍

本项目是一个基于Spark的电影推荐系统,专注于大数据环境下的推荐服务。系统通过SparkSql框架处理电影、评分和用户数据集,利用协同过滤算法为用户生成个性化的电影推荐。项目包含数据存储、大数据分析、Web后端及可视化前端,确保推荐结果的准确性与用户界面的友好性。系统易于部署和运行,同时提供完整的数据文件和SQL文件,便于数据管理和系统维护。其中推荐模块包含:离线推荐,热门推荐,最新推荐等模块!

  • 3、实现过程

    1. 数据采集

本项目旨在构建数据资产分析系统,通过从Kaggle网站下载电影评分数据集和用户数据集,对数据进行分析和处理。数据集包含电影ID、用户ID、电影海报URL、用户评分及用户名称等信息,为系统提供全面的数据支持。

      1. 数据集介绍

该数据集包含电影推荐所需的基本信息,具体包括用户ID(userid)、电影ID(movieid)、电影海报图片的URL链接(url)以及用户对电影的评分(rating,满分为10分)。该数据集可用于分析用户偏好,进而实现电影推荐功能。

      1. 数据清洗

在数据采集完成后,我们将对下载的数据使用spark技术进行清洗和预处理。这包括去除重复数据、处理缺失值、纠正错误数据等,以确保数据的质量和可靠性。同时,我们还将对数据的格式进行统一,方便后续的数据分析和处理。

    1. 大数据推荐计算

代码和业务介绍:

本段代码实现了一个基于Apache Spark的电影推荐系统。系统首先通过SparkConf配置Spark应用程序的基本信息,如应用名称、运行模式以及资源参数。接着,利用SparkSession读取存储在本地CSV文件中的电影评分数据集,该数据集包含用户ID、电影ID以及用户对电影的评分。

在数据处理阶段,代码将评分数据集转换为RDD格式,并提取出用户ID、电影ID以及评分信息。随后,对用户和电影数据集进行去重操作,以获取唯一的用户ID和电影ID列表。基于这些处理后的数据,系统构建了训练数据集,并采用交替最小二乘法(ALS)进行模型训练。ALS是一种在推荐系统中广泛应用的协同过滤算法,能够高效地处理大规模数据集。

在模型训练完成后,系统利用训练好的模型对所有的用户-电影对进行评分预测,从而构建了一个完整的用户推荐矩阵。通过过滤掉评分值较低的预测结果,并对用户推荐的电影进行排序和截取,系统最终生成了一个包含用户推荐信息的DataFrame。

此外,该代码还实现了将原始评分数据集和用户推荐结果存储到MySQL数据库中的功能,便于后续的数据分析和业务应用。通过展示用户推荐信息的DataFrame,可以直观地看到系统为每个用户推荐的电影列表及其预测评分。总之本段代码实现了一个基于Spark和ALS算法的电影推荐系统,能够高效地处理电影评分数据集,并为用户提供个性化的电影推荐服务。

//conf对象
val sparkConf = new SparkConf().setAppName("OfflineRecommender").setMaster("local")
  //在程序中设置资源参数
  .set("spark.executor.memory", "6G").set("spark.driver.memory", "3G")
val spark = SparkSession.builder().config(sparkConf).getOrCreate()
//读取mongoDb 的数据
import spark.implicits._
//从mongo的表中去读数据 [评分数据表] 数据格式 [用户id,电影id,评分]
//todo:1.ratingRDD
val ratingRDD01 = spark
  .read
  .format("csv")
  .option("header", "true")
  .load("D:\\3_ideaworkplace\\_105_movies_recommend_system\\algorithm_analysis\\src\\main\\resources\\ali_t02.csv")
val prop = new Properties()
prop.put("user", "root")
prop.put("password", "123456")
//原始的数据存入数据库
ratingRDD01.write.mode("overwrite")
  .jdbc("jdbc:mysql://localhost:3306/movie_tmp?useUnicode=true&characterEncoding=utf8", "movie_tmp.moviesurl", prop)

//[用户id,电影的id,用户对电影的评分,评分的时间]
val ratingRDD = ratingRDD01.rdd.map(line => {
  (line.get(0).toString.toInt, line.get(1).toString.toInt, line.get(3).toString.toDouble)
}).cache()

//去重操作用户的数据集 RDD[Int] [用户id]
//todo:2.userRDD
val userRDD = ratingRDD.map(_._1).distinct()
//电影数据集 RDD[Int]
val movieRDD = ratingRDD.map(_._2).distinct()


//创建训练数据集 [userid,mid,soucre]
val trainData = ratingRDD.map(x => Rating(x._1, x._2, x._3))
//特征数   迭代次数  正则参数
val (rank, iterations, lambda) = (10, 1, 0.01)


//模型训练[训练集,特征数,迭代次数,正则参数]
//todo:黑箱子
val model = ALS.train(trainData, rank, iterations, lambda)


//使用模型预测
//5.计算用户推荐矩阵(每一个用户对所有的电影)
//需要构造一个usersProducts  RDD[(Int,Int)]
//todo:大的空矩阵
val userMovies = userRDD.cartesian(movieRDD)
//模型预测[Rating是它自带的样例类][这是所有的都已经进行了评分]
//todo:通过黑箱子 补全大矩阵
val preRatings: RDD[Rating] = model.predict(userMovies)


//用户推荐矩阵
val userRecs = preRatings
  //把评分值大于零的过滤掉dm
  .filter(_.rating > 0.5)
  .map(rating => (rating.user, (rating.product, rating.rating)))
  .groupByKey()
  .map {
    case (uid, recs) =>
      UserRecs(uid, recs.toList.sortWith(_._2 > _._2).take(10).map(x => x._1).toString())
  }.toDF()


userRecs.show()
//todo:0.把原始数据存储到mysql中

userRecs.write.mode("overwrite")
  .jdbc("jdbc:mysql://localhost:3306/movie_tmp?useUnicode=true&characterEncoding=utf8", "movie_tmp.userRecs", prop)
spark.close()

    1. 大数据统计分析

      1. 电影评分分布分析

该分析通过统计不同评分值下的电影数量,直观展示电影评分的整体分布情况。X轴代表1至5的评分分值,Y轴则显示对应评分下的电影数量。通过柱状图的形式,我们可以清晰地看到哪个评分段最受欢迎,以及电影评分的大致趋势,为电影制作和营销策略提供参考。

  1. 分析结果图如下
  1. 核心代码如下:

val rate_tendency = spark.sql("select RATING rating,count(1) ct from t_rate group by RATING order by RATING ")
println("1.电影的评分分布")
rate_tendency.show()
rate_tendency.write.mode("overwrite")
  .jdbc("jdbc:mysql://localhost:3306/198_movies_recomm?useUnicode=true&characterEncoding=utf8", "198_movies_recomm.1_rate_tendency", prop)

      1. 电影年份分布分析

本分析按照电影上映年份进行分组统计,X轴表示年份,Y轴显示该年份电影的平均评分数量(注意:原文中“每个评分下的数量”可能需调整为平均评分或其他统计量,以避免歧义)。柱状图展示了电影随时间的变化趋势,帮助我们了解电影市场的历史发展和观众口味的变迁

  1. 分析结果图如下
  1. 核心代码如下:

val year_tendency = spark.sql("select YEAR year,count(1) ct from t_movies where LENGTH(year) <5  group by YEAR order by YEAR  ")
println("2.电影的年份分布")
year_tendency.show()
year_tendency.write.mode("overwrite")
  .jdbc("jdbc:mysql://localhost:3306/198_movies_recomm?useUnicode=true&characterEncoding=utf8", "198_movies_recomm.2_year_tendency", prop)

      1. 不同分段演员参演数量的前8名

此分析利用开窗函数,在每个评分段内统计参演电影数量最多的前8名演员。旭日图以层次结构展示这些演员,直观呈现不同评分段内演员的影响力分布,为演员选拔和角色分配提供数据支持。

  1. 分析结果图如下
  1. 核心代码如下:

val avgRateDF = spark.sql("select MOVIE_ID ,round(avg(RATING),0) avg_rate from t_rate group by MOVIE_ID ")
avgRateDF.show()
avgRateDF.createTempView("avg_rate_score")
//t_movies  和  t_rate
val threeDF = spark.sql("select t3.avg_rate,t3.ACTORS,count(1) ct  from (select * from t_movies t1 " +
  "inner join avg_rate_score t2 on t1.MOVIE_ID= t2.MOVIE_ID ) t3 group by avg_rate,ACTORS order by ct desc limit 8 ")
threeDF.show()
println("3.不评分段的演员参演数量前8名")

threeDF.write.mode("overwrite")
  .jdbc("jdbc:mysql://localhost:3306/198_movies_recomm?useUnicode=true&characterEncoding=utf8", "198_movies_recomm.3_rate_top8", prop)

      1. 不同评分段的类型占比

该分析关注不同评分分段内电影类型的数量占比。通过旭日图,我们可以清晰地看到各种类型电影在不同评分段的分布情况,了解哪些类型更受观众喜爱,哪些类型在特定评分段内更具竞争力。

  1. 分析结果图如下

  1. 核心代码如下:

val fourDF = spark.sql("select t3.avg_rate,t3.GENRES,count(1) ct  from (select * from t_movies t1 " +
  "inner join avg_rate_score t2 on t1.MOVIE_ID= t2.MOVIE_ID ) t3 group by avg_rate,GENRES ")
println("4.不同评分段的类型占比")
fourDF.show()
fourDF.write.mode("overwrite")
  .jdbc("jdbc:mysql://localhost:3306/198_movies_recomm?useUnicode=true&characterEncoding=utf8", "198_movies_recomm.4_rate_prepertion", prop)

      1. 不同类型演员前5名称

本分析按演员类型分组,统计每种类型中参演电影数量最多的前5名演员。这有助于我们了解哪些类型的演员更受欢迎,以及他们在电影市场中的地位和影响力。

  1. 分析结果图如下

  1. 核心代码如下:

 val fiveDF = spark.sql("select GENRES,count(distinct ACTORS) ct from t_movies group by GENRES")
println("5.不同类型演员数量占比top5")
 fiveDF.show()
 fiveDF.write.mode("overwrite")
   .jdbc("jdbc:mysql://localhost:3306/198_movies_recomm?useUnicode=true&characterEncoding=utf8", "198_movies_recomm.5_geners_prepertion", prop)

      1. 电影国家分布占比

该分析按照电影制作国家进行分组统计,并计算各国电影的数量占比。通过饼状图,我们可以直观地看到电影市场的国家分布格局,了解哪些国家的电影在全球范围内更具影响力

  1. 分析结果图如下

  1. 核心代码如下:

val rate_tendency = spark.sql("select RATING rating,count(1) ct from t_rate group by RATING order by RATING ")
println("1.电影的评分分布")
rate_tendency.show()
rate_tendency.write.mode("overwrite")
  .jdbc("jdbc:mysql://localhost:3306/198_movies_recomm?useUnicode=true&characterEncoding=utf8", "198_movies_recomm.1_rate_tendency", prop)

    1. javaWeb可视化

在Java Web项目中,结合HTML、ECharts、Spring Boot和MySQL等技术进行前后台搭建,可以构建一个功能丰富、交互性强的Web应用程序。以下是一个基于这些技术的Java Web前后台搭建的文字描述:

      1. 前端搭建:

HTML: 使用HTML来构建网页的基本结构和内容。通过定义HTML标签和属性,可以创建出各种页面元素,如标题、段落、图片、链接、表格、表单等。

CSS: 通过CSS为网页添加样式和布局。CSS可以控制HTML元素的外观和位置,使得页面更加美观和易于阅读。在项目中,可以将CSS样式定义在单独的文件中,并在HTML中通过链接引入。

JavaScript: 利用JavaScript为网页添加动态交互功能。JavaScript可以处理用户的输入、控制页面的行为、与服务器进行异步通信等。在项目中,可以使用JavaScript库(如jQuery)来简化代码编写,提高效率。

ECharts: 借助ECharts库,为网页添加丰富的图表展示功能。ECharts支持多种图表类型,如折线图、柱状图、饼图等,并且具有高度的可定制性和交互性。通过将ECharts图表嵌入到HTML页面中,可以直观地展示数据和进行数据分析。

      1. 后端搭建:

Spring Boot: 使用Spring Boot框架来构建后端服务。Spring Boot简化了Spring应用的初始搭建和开发过程,通过自动配置和约定优于配置的理念,可以快速开发、测试和部署Spring应用。在项目中,可以利用Spring Boot的Web模块和数据库访问模块,构建出稳定可靠的Web服务。

Java: 采用Java语言进行后端开发。Java是一种广泛使用的编程语言,具有跨平台、面向对象、多线程等特点。在Spring Boot项目中,可以使用Java编写控制器、服务、数据访问对象等组件,实现业务逻辑和数据访问功能。

MySQL: 使用MySQL数据库来存储和管理数据。MySQL是一个开源的关系型数据库管理系统,具有高性能、可扩展性和易用性等优点。在项目中,可以通过JDBC或JPA等持久层框架,实现与MySQL数据库的交互操作。

文件夹结构: 根据项目需求,设计合理的文件夹结构来组织代码和资源文件。例如,可以将源代码放在src目录下的main/java目录下,将资源配置文件放在resources目录下,将静态资源(如图片、CSS、JavaScript文件)放在static目录下,将模板文件(如HTML文件)放在templates目录下。这样可以提高代码的可读性和可维护性。

4、项目资料包

资料目录图

代码结构图

5、如何获取

获取直达-> www.baiyuntu.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/14950.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CANoe工具使用技巧 --- 如何使用 “on ethernetPacket “事件处理程序

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…

数据库5(MySQL版)

作业要求 触发器 mysql> create trigger after_order_insert -> after insert on orders -> for each row -> update goods set num num - new.onum where gid new.gid; mysql> create trigger after_order_delete -> after delete on or…

【异常解决】在idea中提示 hutool 提示 HttpResponse used withoud try-with-resources statement

博主介绍&#xff1a;✌全网粉丝22W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

浅析Ruby类污染及其在Sinatra框架下的利用

和JavaScript中的原型链污染类似&#xff0c;Ruby中也存在类似的概念——类污染&#xff0c;两者都是对象进行不安全的递归合并导致的。 网上也没有相关的分析文章&#xff0c;只有下面这篇文章应该是第一次谈到这个问题 Class Pollution in Ruby: A Deep Dive into Exploiti…

SamWaf开源轻量级的网站应用防火墙(安装包),私有化部署,加密本地存储的数据,易于启动,并支持 Linux 和 Windows 64 位和 Arm64

一、SamWaf轻量级开源防火墙介绍 &#xff08;文末提供下载&#xff09; SamWaf网站防火墙是一款适用于小公司、工作室和个人网站的开源轻量级网站防火墙&#xff0c;完全私有化部署&#xff0c;数据加密且仅保存本地&#xff0c;一键启动&#xff0c;支持Linux&#xff0c;Wi…

14vue3实战-----获取用户信息和用户的菜单树信息

14vue3实战-----获取用户信息和用户的菜单树信息 1.获取用户信息1.1封装接口1.2优化 2.获取用户的菜单树信息 1.获取用户信息 1.1封装接口 后端有根据id获取用户信息的接口&#xff0c;前端需要把该接口封装一下: service/login/login.ts&#xff1a; import hyRequest from…

洛谷算法1-3 暴力枚举

目录 1 P2241统计方形 2 三连击 3 选数 4 P1088 [NOIP2004 普及组] 火星人 5 P3799 小 Y 拼木棒 排列组合 6 P2392 kkksc03考前临时抱佛脚 7 P2036 [COCI2008-2009 #2] PERKET 1 P2241统计方形 思路&#xff1a; 本题中&#xff0c;矩阵数量正方形数量长方形数量&#xff0…

CSS Overflow 属性详解:控制内容溢出的利器

在前端开发中&#xff0c;处理内容溢出是一个常见的需求。CSS 提供了 overflow 属性&#xff0c;帮助我们控制当内容超出元素框时的显示方式。本文将详细介绍 overflow 属性的各种取值及其应用场景。 1. 什么是 overflow 属性&#xff1f; overflow 属性用于控制当元素的内容…

链表和 list

一、单链表的模拟实现 1.实现方式 链表的实现方式分为动态实现和静态实现两种。 动态实现是通过 new 申请结点&#xff0c;然后通过 delete 释放结点的形式构造链表。这种实现方式最能体 现链表的特性&#xff1b; 静态实现是利用两个数组配合来模拟链表。一个表示数据域&am…

面向对象程序设计-实验3

题目1 &#xff08;给出题目描述&#xff09;设计一个类CRectangle 代码清单&#xff1a; #include<iostream> using namespace std; class CRectangle { public: CRectangle() { m_l1.0; m_w1.0; } void get() { cin>>m_l; if(m_l>50) { m_l1.0; } cin&g…

2025.1.8(qt图形化界面之消息框)

笔记&#xff08;后期复习补充&#xff09; 作业 1> 手动将登录项目实现&#xff0c;不要使用拖拽编程 并且&#xff0c;当点击登录按钮时&#xff0c;后台会判断账号和密码是否相等&#xff0c;如果相等给出登录成功的提示&#xff0c;并且关闭当前界面&#xff0c;发射一…

windows10 wsa 安卓子系统终结版

windows10 wsa 安卓子系统终结版 链接&#xff1a;https://pan.xunlei.com/s/VOIdoPPmqdUcgw3daFSbh2dAA1?pwdbe3r# windows10 wsa 安卓子系统终结版&#xff0c;包含三个文件. 1: windows10 wsa v2407.40000.4.0 x64 安卓子系统终结版。 2: Apk lnstaller v1.7 用于识别A…

计算机网络应用层:模型、系统与协议全解析!!!

应用层 应用层对应用程序的通信提供服务 应用层协议定义: 应用进程交换的报文类型&#xff0c;请求还是响应? 各种报文类型的语法&#xff0c;如报文中的各个字段及其详细描述&#xff0c; 字段的语义&#xff0c;即包含在字段中的信息的含义。 进程何时、如何发送报文&#x…

【分布式理论8】分布式调用之:四种IO模型

文章目录 一. 四种IO模型1. 同步阻塞 IO&#xff08;Blocking IO&#xff09;2. 同步非阻塞 IO&#xff08;Non-blocking IO&#xff09;3. IO 多路复用&#xff08;IO Multiplexing&#xff09;4. 异步 IO&#xff08;Asynchronous IO&#xff09;在 RPC 中的作用5. 总结 选择…

元宇宙中的隐私与数据保护:Facebook 的挑战与机遇

随着数字技术的飞速发展&#xff0c;元宇宙&#xff08;Metaverse&#xff09;正逐渐成为未来互联网的新舞台。Meta&#xff0c;作为这一领域的先行者&#xff0c;正面临着隐私与数据保护的双重挑战。本文将探讨 Meta 在元宇宙中的隐私与数据保护问题&#xff0c;并分析其可能的…

Word中Ctrl+V粘贴报错问题

Word中CtrlV粘贴时显示“文件未找到&#xff1a;MathPage.WLL”的问题 Word的功能栏中有MathType&#xff0c;但无法使用&#xff0c;显示灰色。 解决方法如下&#xff1a; 首先找到MathType安装目录下MathPage.wll文件以及MathType Commands 2016.dotm文件&#xff0c;分别复…

Stability AI 联合 UIUC 提出单视图 3D 重建方法SPAR3D,可0.7秒完成重建并支持交互式用户编辑。

Stability AI 联合 UIUC 提出一种简单而有效的单视图 3D 重建方法 SPAR3D&#xff0c;这是一款最先进的 3D 重建器&#xff0c;可以从单视图图像重建高质量的 3D 网格。SPAR3D 的重建速度很快&#xff0c;只需 0.7 秒&#xff0c;并支持交互式用户编辑。 相关链接 论文&#xf…

Spring Cloud 04 - 负载均衡和外部服务访问

Ribbon & Feign 文章目录 Ribbon & Feign一&#xff1a;Ribbon负载均衡1&#xff1a;介绍 2&#xff1a;ribbon的五大核心组件二&#xff1a;Feign外部接口访问1&#xff1a;Feign概述2&#xff1a;Feign vs OpenFeign3&#xff1a;使用示例3.1&#xff1a;注解支持3.2…

力扣--链表

相交链表 法一&#xff1a; 把A链表的节点都存HashSet里&#xff0c;遍历B链表找相同的节点 法二&#xff1a; 把A、B指针都移到末尾&#xff0c;再同时往回走&#xff0c;每次往回走都比较 当前节点的下一节点&#xff08;a.next b.next ?)是否相同&#xff0c;当不相同…

antd pro常见代码示例-ProTable

1、protable使用 这是antd Pro 封装的一个table组件&#xff0c;提供了很多好用的方法&#xff0c; proTable地址&#xff1a; protable官网 代码示例&#xff1a; <ProTableactionRef{actionRef}pagination{{ //分页设置defaultPageSize: 10,showQuickJumper: true,sh…