基于大数据Spark电影数据分析可视化系统 大数据 Hadoop 机器学习预测算法 爬虫 电影推荐 票房预测 猫眼电影 计算机(全套源码+教程+开发笔记+文档)✅

博主介绍:✌全网粉丝50W+,前互联网大厂软件研发、集结硕博英豪成立软件开发工作室,专注于计算机相关专业项目实战6年之久,累计开发项目作品上万套。凭借丰富的经验与专业实力,已帮助成千上万的学生顺利毕业,选择我们,就是选择放心、选择安心毕业✌
> 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅

1、2026年计算机专业毕业设计选题大全(建议收藏)✅

2、大数据、计算机专业选题(Python/Java/大数据/深度学习/机器学习)(建议收藏)✅

1、项目介绍

技术栈:
大数据、Hadoop、Spark、Hive、虚拟机、python语言、Django框架、MySQL数据库、
猫眼电影、电影票房、协同过滤推荐算法、电影推荐、机器学习、票房预测

1、预测总票房----机器学习随机森林回归模型 (machine文件夹)
2、电影推荐----机器学习之基于用户协同过滤推荐算法 (recommend文件夹)
(1)机器学习部分:cosine_similarity 是一个用于计算两个向量之间相似度的函数,属于 sklearn.metrics.pairwise 模块,它在机器学习、数据挖掘和推荐系统中广泛使用。

2、项目界面

(1)电影数据大屏

在这里插入图片描述

(2)电影类型分析
在这里插入图片描述

(3)电影评分分析
在这里插入图片描述

(4)电影时间分析

在这里插入图片描述

(4)票房分析

在这里插入图片描述

(5)数据中心

在这里插入图片描述

(6)电影推荐
在这里插入图片描述

(7)词云图分析

在这里插入图片描述

(8)票房预测

在这里插入图片描述

(9)我的收藏

在这里插入图片描述

(10)后台管理
在这里插入图片描述

(11)spark数据分析

在这里插入图片描述

(12)数据采集

在这里插入图片描述

3、项目说明

摘 要
在电影产业规模持续扩张、市场竞争日益激烈的背景下,电影数据已成为驱动行业发展的核心要素。从电影项目的前期策划、中期发行,到观众的观影决策,再到行业趋势研究,精准且深入的数据分析都发挥着关键作用。本研究基于Spark技术开发的电影数据分析系统,深度融合大数据处理与机器学习算法,致力于为电影行业全链条提供高效、精准的数据支持与决策依据。
系统以Python作为核心开发语言,结合Django框架搭建起稳定、高效的Web应用架构,确保系统具备良好的扩展性与交互性。MySQL数据库用于存储结构化数据,保障数据的安全性与便捷查询;Hadoop、Spark和Hive构成大数据处理核心,实现海量电影数据的分布式存储与高效计算,能够快速完成复杂的数据清洗、转换和分析任务;Echarts可视化库则将分析结果以直观、美观的折线图、柱状图、饼图等形式呈现,助力用户快速理解数据背后的规律。
系统功能全面且实用,涵盖数据采集、多维度分析、票房预测、电影推荐等多个模块。数据采集模块采用Selenium爬虫技术,实时获取猫眼电影网站数据,确保数据的时效性与准确性;多维度分析模块从电影类型、评分、时间、票房等多个角度展开深度剖析,挖掘电影市场潜在规律;票房预测模块基于机器学习随机森林回归模型,结合电影类型、发行地区、首周票房等关键因素,输出可靠的票房预测结果;电影推荐模块运用协同过滤推荐算法,根据用户观影历史和行为数据,实现个性化电影推荐。
经严格测试与优化,系统在功能完整性、数据准确性、运行稳定性及性能表现上均达到预期标准。无论是高并发场景下的响应速度,还是复杂数据处理任务的执行效率,都能满足用户需求。未来,系统将持续优化算法模型,提升预测与推荐的精准度;拓展数据采集维度,纳入更多元化数据源;并探索与人工智能前沿技术的深度融合,进一步增强系统的智能化水平,为电影行业的数字化、智能化发展提供更强大的助力。

关键字:电影数据分析;Spark;机器学习;协同过滤推荐算法;数据可视化;Python 语言

在这里插入图片描述

4、核心代码


#导包
from pyspark.sql import SparkSession
from pyspark.sql.functions import monotonically_increasing_id
from pyspark.sql.types import StructType,StructField,IntegerType,StringType,FloatType
from pyspark.sql.functions import count,mean,col,sum,when,max,min,avg,explode,split,row_number,year,month
from pyspark.sql.window import Window


if __name__ == '__main__':
    #构建
    spark = SparkSession.builder.appName("sparkSQL").master("local[*]"). \
        config("spark.sql.shuffle.partitions", 2). \
        config("spark.sql.warehouse.dir", "hdfs://node1:8020/user/hive/warehouse"). \
        config("hive.metastore.uris", "thrift://node1:9083"). \
        enableHiveSupport(). \
        getOrCreate()


    #读取
    catMovieData = spark.read.table("catMovieData")

    #需求一 类型分析 统计
    explode_df = catMovieData.withColumn("type",explode(split(col("type"),"-")))
    result1 = explode_df.groupBy("type").agg(count("type").alias("type_count"))

    # sql
    result1.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "movieTypeCount"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result1.write.mode("overwrite").saveAsTable("movieTypeCount", "parquet")
    spark.sql("select * from movieTypeCount").show()

    #需求二 票房TOP10
    sorted_df =catMovieData.orderBy(col("allBoxOffice").desc())
    result2 = sorted_df.limit(10)

    # sql
    result2.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "boxTopMovie"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result2.write.mode("overwrite").saveAsTable("boxTopMovie", "parquet")
    spark.sql("select * from boxTopMovie").show()

    #需求三 类型最大票房
    result3 = explode_df.groupBy("type").agg(
        max("firstBoxOffice").alias("max_firstBoxOffice"),
        max("allBoxOffice").alias("max_allBoxOffice")
    )

    # sql
    result3.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "typeMaxBox"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result3.write.mode("overwrite").saveAsTable("typeMaxBox", "parquet")
    spark.sql("select * from typeMaxBox").show()

    #需求四 国家统计
    explode_df2 = catMovieData.withColumn("country",explode(split(col("country"),",")))

    result4 = explode_df2.groupBy("country").agg(count("country").alias("country_count"))

    # sql
    result4.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "mcountryCount"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result4.write.mode("overwrite").saveAsTable("mcountryCount", "parquet")
    spark.sql("select * from mcountryCount").show()

    #需求五 评分分类

    catMovieData = catMovieData.withColumn(
        "rateCategory",
        when(col("rate") == 0, None).otherwise(
            when((col("rate") >= 10) & (col("rate") < 20), "半星").
            when((col("rate") >= 20) & (col("rate") < 30), "1星").
            when((col("rate") >= 30) & (col("rate") < 40), "1.5星").
            when((col("rate") >= 40) & (col("rate") < 50), "2星").
            when((col("rate") >= 50) & (col("rate") < 60), "2.5星").
            when((col("rate") >= 60) & (col("rate") < 70), "3星").
            when((col("rate") >= 70) & (col("rate") < 80), "3.5星").
            when((col("rate") >= 80) & (col("rate") < 90), "4星").
            when((col("rate") >= 90) & (col("rate") < 100), "4.5星")
        )
    )

    filter_df = catMovieData.filter(col("rate") != 0)
    result5 = filter_df.groupBy("rateCategory").count()

    # sql
    result5.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "starCategory"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result5.write.mode("overwrite").saveAsTable("starCategory", "parquet")
    spark.sql("select * from starCategory").show()

    #需求6 按类型票房分析
    grouped_df = explode_df.groupBy("type","title").agg({"allBoxOffice":"sum"})
    grouped_df = grouped_df.withColumnRenamed("sum(allBoxOffice)","allBoxOffice")

    window = Window.partitionBy("type").orderBy(col("allBoxOffice").desc())
    ranked_df = grouped_df.withColumn("row_num",row_number().over(window))
    #过滤出每组的前十
    result6 = ranked_df.filter(col("row_num") <= 10).drop("row_num")

    # sql
    result6.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "perTypeBox"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result6.write.mode("overwrite").saveAsTable("perTypeBox", "parquet")
    spark.sql("select * from perTypeBox").show()


    #需求7 按类型评分
    filter_df2 = explode_df.filter(col("rate") != 0)
    result7 = filter_df2.groupBy("type","rate").agg(count("rate").alias("rate_count"))

    # sql
    result7.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "perTypeRate"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result7.write.mode("overwrite").saveAsTable("perTypeRate", "parquet")
    spark.sql("select * from perTypeRate").show()

    #需求8类型平均时长
    result8 = explode_df.groupBy("type").agg(avg("duration").alias("avg_duration"))

    # sql
    result8.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "typeAvgTime"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result8.write.mode("overwrite").saveAsTable("typeAvgTime", "parquet")
    spark.sql("select * from typeAvgTime").show()

    #需求9 年度平均评分分析
    time_df1 = catMovieData.withColumn("releaseTime",col("releaseTime").cast("date"))

    time_df2 = catMovieData.withColumn("year",year(col("releaseTime")))

    result9 = time_df2.groupBy("year").agg(avg("rate").alias("year_rate"))

    # sql
    result9.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "mYearRate"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result9.write.mode("overwrite").saveAsTable("mYearRate", "parquet")
    spark.sql("select * from mYearRate").show()

    #需求十 国家平均
    result10 = explode_df2.groupBy("country").agg(avg("rate").alias("avg_rate"))

    # sql
    result10.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "mCountryRate"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result10.write.mode("overwrite").saveAsTable("mCountryRate", "parquet")
    spark.sql("select * from mCountryRate").show()

    #需求十一 类型
    result11 = explode_df.groupBy("type").agg(avg("rate").alias("avg_rate"))

    # sql
    result11.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "mTypeRate"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result11.write.mode("overwrite").saveAsTable("mTypeRate", "parquet")
    spark.sql("select * from mTypeRate").show()


    #需求十二 时间分析
    result12 = time_df2.groupBy("year").agg(count("year").alias("year_count"))

    # sql
    result12.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "mYearCount"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result12.write.mode("overwrite").saveAsTable("mYearCount", "parquet")
    spark.sql("select * from mYearCount").show()

    #月度
    time_df3 = time_df1.withColumn("month",month(col("releaseTime")))
    result13 = time_df3.groupBy("month").agg(count("month").alias("year_count"))

    # sql
    result13.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "mMonthCount"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result13.write.mode("overwrite").saveAsTable("mMonthCount", "parquet")
    spark.sql("select * from mMonthCount").show()

    #时长分析
    catMovieData = catMovieData.withColumn(
        "durationCategory",
        when(col("duration") == 0, None).otherwise(
            when((col("duration") >= 0) & (col("rate") < 50), "很短").
            when((col("duration") >= 50) & (col("rate") < 80), "较短").
            when((col("duration") >= 80) & (col("rate") < 120), "中").
            when((col("duration") >= 120) & (col("rate") < 150), "较长").
            otherwise('很长')
        )
    )

    filter_df4 = catMovieData.filter(col("duration") != 0)
    result14 = filter_df4.groupBy("durationCategory").count()

    # sql
    result14.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "mTimeCategory"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result14.write.mode("overwrite").saveAsTable("mTimeCategory", "parquet")
    spark.sql("select * from mTimeCategory").show()

    #需求15 各类型平均票房
    result15 = explode_df.groupBy("type").agg(
        avg("allBoxOffice").alias("avg_allBoxOffice")
    )

    # sql
    result15.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "mTypeAvgBox"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result15.write.mode("overwrite").saveAsTable("mTypeAvgBox", "parquet")
    spark.sql("select * from mTypeAvgBox").show()

    #各国家票房
    result16 = explode_df2.groupBy("country").agg(
        avg("allBoxOffice").alias("avg_allBoxOffice")
    )

    # sql
    result16.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "mCountryAvgBox"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result16.write.mode("overwrite").saveAsTable("mCountryAvgBox", "parquet")
    spark.sql("select * from mCountryAvgBox").show()


    #年度平均票房

    result17 = time_df2.groupBy("year").agg(
        avg("allBoxOffice").alias("avg_allBoxOffice")
    )

    # sql
    result17.write.mode("overwrite"). \
        format("jdbc"). \
        option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
        option("dbtable", "mYearAvgBox"). \
        option("user", "root"). \
        option("password", "root"). \
        option("encoding", "utf-8"). \
        save()

    result17.write.mode("overwrite").saveAsTable("mYearAvgBox", "parquet")
    spark.sql("select * from mYearAvgBox").show()

🍅✌感兴趣的可以先收藏起来,点赞关注不迷路,想学习更多项目可以查看主页,大家在毕设选题,项目编程以及论文编写等相关问题都可以给我留言咨询,希望可以帮助同学们顺利毕业!🍅✌

5、源码获取方式

🍅由于篇幅限制,获取完整文章或源码、代做项目的,拉到文章底部即可看到个人联系方式。🍅

点赞、收藏、关注,不迷路,下方查看👇🏻获取联系方式👇🏻

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值