拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Python电影数据可视化与票房预测:从MySQL到回归建模全流程

简介基于Python的电影数据可视化及票房影响因素分析与预测源码包面向计算机相关专业正在准备毕业设计的学生以及需要项目实战练习的初学者。围绕“数据可视化”和“票房影响因素分析预测”两个核心任务资源完整覆盖了数据采集、数据库构建、可视化呈现、特征分析与预测建模等环节既可作为毕业设计也可用于课程设计或期末大作业。包内共38个文件包括6个Python脚本、3个Jupyter Notebook、SQL数据库脚本、PDF说明文档以及24张结果图表。Python脚本按职责拆分为主程序、数据库连接、数据获取、基础信息查询等模块结构清晰Notebook分别演示了基于Pandas和SQL的数据可视化与预测流程PDF文档则提供项目说明便于快速上手。整个压缩包仅5.18MB容量小、易部署当前已有425人学习/下载。除了开箱即用、确保可运行的源码资源还附带豆瓣电影数据库脚本和两种预测结果图谱方便读者直观理解电影票房与评分、类型、地区等因素的关系并基于完整代码快速复现实验或进行二次扩展是完成相关毕业设计、实战练习的优质参考。1. 基于 python 的电影数据可视化与票房预测先搞清楚这包源码能干什么做毕设最怕的不是没思路而是拿到一份源码包解压之后满屏的 .py 和 .ipynb却不知道第一步该点哪里。这份“基于 python 的电影数据可视化及票房影响因素分析与预测”就是典型的毕设全家桶爬虫采集、MySQL 建库、Pandas / SQL 双线可视化、回归建模预测票房一条链全给齐了。它能直接回答三个问题票房受什么影响、这些影响怎么画出来讲清楚、新片票房能不能估个区间。适合三类人计算机相关专业做毕设的学生、课程设计需要完整案例的本科生、以及想练 Python 数据分析和可视化实战的初学者。它的价值不在于算法多前沿而在于流程完整、能跑通、有结果图改改就能变成你自己的项目。2. 先把项目跑起来环境配置、目录解读与运行顺序2.1 拿到压缩包先别双击代码目录结构决定了你的上手路径解压之后你会发现这个项目分得挺有条理根目录放的是入口脚本和文档src 目录放的是业务模块result 目录里全是运行后产出的图片。很多学生上来就打开 predict.ipynb 一顿乱跑结果报错“找不到 movie_basic”原因就是没按顺序来。我把这包源码的关键文件和职责整理成了下面这张表照着它走不会迷路文件 / 目录职责运行时机douban.sql建库建表 数据插入最先执行导入 MySQLsrc/database.py数据库连接与查询封装被其他模块 importsrc/movie_basic.py基础信息入库与操作数据库导入后运行src/movie_detail.py详情数据票房、评分人数等处理基础数据之后src/unit.py工具函数文本清洗、日期格式化被调用src/main.py业务主入口串联整个流程想看整体跑通时运行visualization_pandas.ipynbPandas 数据探索与可视化数据入库后逐个 Cell 跑visualization_sql.ipynbSQL 查询 可视化对照同上predict.ipynb特征构造 票房预测建模最后运行attachfile.py外部数据补充如豆瓣详情抓取按需容易触发反爬我一般建议的顺序是先导douban.sql建库再跑main.py验证链路然后打开visualization_pandas.ipynb从头到尾执行一遍最后才是predict.ipynb。这个顺序的好处是每一步的输入都是上一步的输出排查问题时能快速定位是数据问题还是代码问题。2.2 环境准备Python 版本、依赖与第一条能跑通的命令这个项目是基于 Python 3 开发的如果你机器上装的是 3.8 到 3.10基本不会有什么兼容问题。要是你直接上了 Python 3.12 或 3.13后面装 pandas、matplotlib 的旧版本可能会翻车这点我放在避坑章节细说。先检查环境python --version pip list | findstr pandas mysql matplotlib scikit-learn jupyter如果没有 jupyter用pip install jupyter装上。这里有一点要特别注意项目里既有.py脚本又有.ipynb笔记本说明作者开发时是脚本开发和交互式探索混用的。你在跑 .ipynb 之前一定要先确认 notebook 的内核Kernel选的是你装好依赖的那套环境Jupyter 默认的 Python 环境很容易和命令行里的python不是同一个。# 建议直接在项目根目录创建虚拟环境把依赖装干净 python -m venv venv venv\Scripts\activate pip install pandas matplotlib pymysql sqlalchemy scikit-learn jupyter装完后分别测试两个核心配置一个是数据库连接另一个是 matplotlib 绘图后端。很多人卡在“代码没报错但图画不出来”多半是 notebook 里没有加%matplotlib inline或者画完图没调用plt.show()。这个项目的结果图都输出成了 PNG 文件存在 result 目录说明作者把 matplotlib 配成了 Agg 后端这种模式适合批处理但渲染不出来交互图。2.3 main.py 到底做了什么一张调用链图理顺业务逻辑我拆过不少毕设项目main.py写得怎么样基本能反映整个项目的质量。这个项目的main.py起的是调度作用它做的事情可以概括为连接 MySQL从movie_basic和movie_detail两张表里读数据做一些清洗和加工然后调用可视化函数生成图表最后把图表和统计结果输出到 result 目录。# main.py 核心逻辑简化后的执行流 import database from movie_basic import MovieBasic from movie_detail import MovieDetail if __name__ __main__: conn database.get_connection() basic MovieBasic(conn) detail MovieDetail(conn) basic_data basic.load_all() detail_data detail.load_all() merged basic_data.merge(detail_data, onmovie_id) # 产出核心分析图表 draw_boxplot(merged, rating_vs_boxoffice.png) draw_scatter(merged, rating, boxoffice, rating_boxoffice.png) draw_top10(merged, top10_boxoffice.png)这段代码透露出几个关键信息第一movie_basic和movie_detail之间靠movie_id关联这决定了数据库里的表结构是主外键设计第二票房和评分的散点图是必出的图说明评分的解释力是分析重点后面的预测模型大概率也用到了评分作为特征。你拿到源码后第一步不是改代码而是把database.py里的连接参数改成你自己的 MySQL 账号密码然后跑一遍main.py能出图就说明从数据库到可视化的链路通了。3. 把数据拆开看数据库结构、SQL 可视化与 Pandas 探索主线3.1 douban.sql 里藏着什么表结构与关联字段douban.sql是整个项目的地基。这个文件建了两张核心表一张存电影基础信息另一张存票房和评分等指标数据。我用 MySQL 客户端连上之后执行SHOW TABLES能看到表名再用DESC看字段结构。这类毕设项目典型的表设计是movie_basic表存电影 ID、片名、导演、主演、类型、地区、上映日期、片长movie_detail表存电影 ID、票房、豆瓣评分、评分人数、预算、首日票房之类的衍生指标。-- 查看建表语句理解字段设计 SHOW CREATE TABLE movie_basic; SHOW CREATE TABLE movie_detail; -- 看看数据量和数据质量 SELECT COUNT(*) AS total, COUNT(DISTINCT movie_id) AS unique_movies FROM movie_basic; SELECT COUNT(*) AS total, COUNT(boxoffice) AS has_boxoffice FROM movie_detail;如果total和unique_movies不一致说明数据有重复后续做关联分析前需要去重。这个检查动作看起来基础但在毕设答辩时老师问“你怎么确保数据质量”你就可以拿这个回答先检查主键唯一性再做缺失值统计。项目里自带一张db_struct.png就是表结构关系图答辩 PPT 里可以直接用不用自己再画。3.2 database.py 与 unit.py连接池、查询封装与工具函数database.py在这个项目里是一个黑匣子但也是你必须读懂的第一个文件。因为所有 .ipynb 都要连数据库如果连接方式不对后面全是无用功。常见的实现方式有两种一种是用pymysql直接建连接另一种是用sqlalchemy做 ORM。这个项目我推测用的是 pymysql 加一个简单的单例连接因为文件里还有get_connection这种典型函数名。# database.py 常见实现模式 import pymysql def get_connection(): conn pymysql.connect( hostlocalhost, port3306, userroot, passwordyour_password, # 改成你自己的密码 databasemovie_db, # 改成 douban.sql 里建的库名 charsetutf8mb4, cursorclasspymysql.cursors.DictCursor ) return conn连上数据库之后unit.py就派上用场了。它通常提供日期格式化、文本清洗、票房金额字符串转数字这类工具函数。比如“1.2亿”这种字符串没法直接参与运算必须通过unit.py里的函数解析成120000000后面画图、建模才正常。拿到源码后我建议你先打开unit.py看看里面封装了哪些函数这些函数后续在可视化 notebook 里会被反复导入理解了它们你去看可视化代码就不吃力。3.3 visualization_sql.ipynb用 SQL 跑票房分布与排行这份 notebook 的价值在于它展示了“SQL 查什么图表就画什么”的对照思路。它的套路是先用 SQL 查出一个结果集然后把这个结果集喂给 matplotlib画成图。这种做法的好处是数据处理的逻辑全在 SQL 里可视化代码非常干净答辩时逻辑链路很清晰。-- 典型查询不同类型电影的平均票房 SELECT type, AVG(boxoffice) AS avg_boxoffice FROM movie_basic b JOIN movie_detail d ON b.movie_id d.movie_id GROUP BY type ORDER BY avg_boxoffice DESC LIMIT 10;从这份 SQL 可以提炼出两个分析点一是“类型对票房有没有影响”二是“上映年份和票房的关系”。作者把结果画成了柱状图和折线图存在 result 目录里文件名带p (5).png、p (12).png这种编号。你复现的时候不要跳着跑 Cell因为后面的 Cell 可能复用了前面的 DataFrame 变量。visualization_pandas.ipynb则是另一条线纯 Pandas 处理侧重点在相关性分析和分布特征。我用一个比喻来帮你理解这两份 notebook 的分工SQL 版像是先定好问题再去查数Pandas 版像是把数据全拉进来再慢慢探索、看哪个特征有戏。前者适合验证已知结论后者适合发现未知规律。一份毕设里两条线都出现覆盖面就完整了。3.4 从 DataFrame 到图表Pandas 线怎么画相关性Pandas 主线里最常用的操作是merge、groupby和corr。作者会把movie_basic和movie_detail拼起来然后做几组相关性分析典型的是“豆瓣评分 vs 票房”“评分人数 vs 票房”。这种相关性分析看起来简单但却是整份毕设的“论点支撑”因为后面预测模型的特征选择就是从这些相关性结果里挑的。import pandas as pd import matplotlib.pyplot as plt # 从数据库读数据注意这里用的是 SQL 查询 df pd.read_sql_query( SELECT b.movie_id, b.type, d.rating, d.boxoffice, d.rating_count FROM movie_basic b JOIN movie_detail d ON b.movie_id d.movie_id, conn ) # 相关性矩阵 corr df[[rating, boxoffice, rating_count]].corr() print(corr) # 画散点图横轴评分纵轴票房 plt.figure(figsize(8, 5)) plt.scatter(df[rating], df[boxoffice], alpha0.6) plt.xlabel(豆瓣评分) plt.ylabel(票房) plt.title(评分与票房的关系) plt.savefig(result/scatter_rating_boxoffice.png, dpi150)这段代码要注意两个参数alpha0.6是透明度数据重叠特别多的时候调低透明度才能看出密度分布dpi150控制输出图的分辨率答辩投屏建议不低于 150。画完散点图之后通常在旁边附一个相关系数矩阵代码里corr()一行就出来了数值越接近 1 说明正相关性越强。这个环节是整份项目最容易出彩的地方因为你能用数据说话评分高的电影不一定票房高但评分人数多、讨论度高的电影票房通常不差。4. 票房预测不是玄学特征构造、回归建模与 predict.ipynb 拆解4.1 预测模型该选什么先定任务再定模型别一上来就跑神经网络很多拿到这份源码的人第一反应是“票房预测是不是得上深度学习”。实际上对于毕设级别的项目来说深度学习的解释性太差答辩时很难讲清楚。电影票房预测在学术界和企业里更多是用回归模型你可以把它看成一道经典的回归题输入是一堆电影属性评分、类型、档期、导演热度等输出是票房的数值或区间。predict.ipynb这个文件承载的就是这个任务。里面最核心的预处理工作是把电影类型这种文本字段变成模型能吃的数值常见做法是 One-Hot 编码或者标签编码。作者大概率用了 scikit-learn 的LabelEncoder或OneHotEncoder因为这是最标准的选择。# predict.ipynb 核心流程读取、预处理、切分、训练 import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelEncoder, StandardScaler from sklearn.ensemble import RandomForestRegressor from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_absolute_error, r2_score # 1. 读取合并后的数据 df pd.read_sql_query( SELECT b.type, b.region, b.release_date, d.rating, d.rating_count, d.boxoffice FROM movie_basic b JOIN movie_detail d ON b.movie_id d.movie_id, conn ) df df.dropna(subset[boxoffice]) # 2. 文本字段编码 le_type LabelEncoder() df[type_encoded] le_type.fit_transform(df[type]) # 3. 特征与标签 features [rating, rating_count, type_encoded] X df[features] y df[boxoffice] # 4. 标准化 切分 scaler StandardScaler() X_scaled scaler.fit_transform(X) X_train, X_test, y_train, y_test train_test_split( X_scaled, y, test_size0.2, random_state42 ) # 5. 线性回归作为基线 lr LinearRegression() lr.fit(X_train, y_train) y_pred lr.predict(X_test) print(R2:, r2_score(y_test, y_pred)) print(MAE:, mean_absolute_error(y_test, y_pred))这里解释四个关键点。第一dropna(subset[boxoffice])是必须的票房是标签缺失了没法预测直接丢掉比填充更稳妥。第二random_state42是随机种子固定之后每次运行结果一致答辩时可以复现不固定的话每次跑 R2 都不一样老师一问就穿帮。第三test_size0.2表示拿 20% 的数据做验证这个比例是这类项目常用的默认值。第四先用线性回归做基线再上随机森林对比这是非常成熟的建模套路能体现你的思路。4.2 特征不是越多越好为什么要谨慎处理“导演”和“主演”预测票房最容易踩的坑是把“导演”和“主演”直接丢进模型。原因很简单这些字段的高基数问题会把你模型的自由度炸掉。一个数据集里如果有 500 个导演One-Hot 编码之后就是 500 列稀疏特征模型还没开始学就过拟合了。比较务实的做法是只保留头部导演比如票房 Top 20 的导演或者把导演转成“历史平均票房”这类聚合特征。# 把导演转成聚合特征导演历史平均票房 director_avg_box df.groupby(director)[boxoffice].transform(mean) df[director_power] director_avg_box # 再配合主演数量 df[cast_count] df[cast].apply(lambda x: len(str(x).split(/)))transform(mean)是个很高级的用法它不改变行数把每个导演的平均票房映射回原始行这样就能作为一个特征参与建模。这种方式比 one-hot 导演名要稳得多答辩时讲出来会显得你有工程经验。主演同理可以统计主演数量、主演中是否有头部演员但要克制特征总数控制在 5 到 8 个就够用了别一上来堆 20 个特征。4.3 读懂预测结果图预测1.png 和预测2.png 代表什么项目 result 目录里有预测1.png和预测2.png两张结果图这两张图是你答辩时“证据链”的关键。预测1.png通常是真实票房和预测票房的散点对比图横轴真实值、纵轴预测值如果点都贴在对角线上说明模型拟合好如果点散成一片云说明模型基本没学到东西。预测2.png一般是特征重要性排序图如果用的随机森林或者残差图。# 随机森林做对比并输出特征重要性 rf RandomForestRegressor(n_estimators200, max_depth8, random_state42) rf.fit(X_train, y_train) print(rf.feature_importances_) # 画真实值 vs 预测值散点图 plt.figure(figsize(6, 6)) plt.scatter(y_test, rf.predict(X_test), alpha0.6) plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], r--) plt.xlabel(真实票房) plt.ylabel(预测票房) plt.savefig(result/预测1.png, dpi150)n_estimators200和max_depth8这两个参数是随机森林最常用的组合前者是树的数量后者是树的深度上限。树太少欠拟合树太多训练慢且提升有限深度限制是为了防止单棵树把训练集背下来。如果你跑出来的 R2 是负的基本可以断定是数据量太少或者特征和票房没什么关系这时候优先检查电影类型和评分是不是真的有区分度而不是急着换复杂模型。5. 避坑实录环境、编码与数据库导入的五个坑5.1 Python 3.12 装不上旧版 pandas版本冲突问题现象执行pip install pandas时报错或者提示找不到匹配版本更常见的是装上了但pymysql无法导入。原因Python 3.12 移除了不少旧 API这个项目开发时大概率用的是 3.8-3.10 版本部分依赖的编译版本没跟上。解决不要硬扛直接换 Python 3.10或者用 conda 建一个 3.10 的环境。如果你必须留在 3.12那就把所有依赖装最新版然后做好修改微量代码兼容的心理准备。5.2 MySQL 导入 douban.sql 后中文乱码现象用 Navicat 或命令行导入douban.sql后表里电影名全是乱码查询时一片问号。原因SQL 文件是 UTF-8 编码保存的但 MySQL 客户端连接时用了默认的 latin1 或 gbk 字符集导入时字符集不匹配。解决导入前先执行SET NAMES utf8mb4;或者用命令行加参数导入mysql -u root -p --default-character-setutf8mb4 douban.sql导入后如果还乱码检查表的排序规则是否为utf8mb4_general_ci不是就改表。这是语言编码的坑和你自己的数据无关。5.3 pandas 画图中文变方框现象matplotlib 输出图片里所有汉字都是空心的方框x 轴标签、标题全部乱码。原因matplotlib 默认字体不支持中文。这个坑几乎每个 Python 数据分析项目都会遇到不是这个包独有的问题。解决在代码开头强制指定中文字体import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] # 黑体 plt.rcParams[axes.unicode_minus] False # 解决负号显示异常这里第二个配置很容易漏。设置了第一个不设置第二个坐标轴上的负号会变成一个方块答辩时一眼就能看出你没处理干净。5.4 attachfile.py 跑一半卡住或被拦截现象attachfile.py运行到中途卡住或者返回一堆异常状态码程序最终抛异常退出。原因这个脚本的作用是补充外部数据比如豆瓣详情页的额外字段会对目标网站发起批量请求。没有做请求频率限制就会触发站点的反爬机制轻则限流重则封 IP。解决不要一次性跑全量。筛选少量缺失数据的样本且每次请求之间加延时import time import requests for movie_id in sample_ids: resp requests.get(url, headersheaders, timeout5) if resp.status_code 200: parse_and_store(resp) time.sleep(2) # 每次请求间隔 2 秒别太贪如果仅仅是毕设展示我的建议更直接跳过这个脚本直接用douban.sql里已有的数据完成分析和预测外部补充数据做演示加分项不做也影响不到主体流程。5.5 predict.ipynb 跑完报“ValueError: could not convert string to float”现象训练模型时报错提示字符串无法转成浮点数通常定位到特征矩阵 X 上。原因特征里有文本字段比如类型字段还是“剧情 / 喜剧”这种原始字符串没做编码就直接丢进了回归模型。这个错误在数据清洗不彻底的时候极其常见。解决在训练前加一个检查print(df.dtypes) # 看看哪些列还是 object 类型 # 对 object 类型做 LabelEncoder 或 OneHotEncoder这里要记住fit_transform和transform必须用同一个编码器对象很多人在训练集上做了编码测试集忘了做或者用了重新 new 出来的编码器实测必然报错。提示以上五个坑是复现这类电影数据分析项目的典型问题如果你在运行阶段遇到别的异常先看堆栈信息最后一行是哪个模块抛的错再回对应章节排查。6. 从复现到改造换数据源、换模型把毕设变成自己的作品代码能跑通只是第一步答辩时最怕的是被问“哪里是你改的”。我建议你从下面三个方向里挑一个动手改改动量不大但足够在答辩时讲出属于你的增量。第一个方向是换数据源。douban.sql里是电影数据你完全可以把表结构改成电视剧数据或者换成某个垂直领域的数据比如图书销量、游戏评分表结构基本不用大改只需要修改字段名和 SQL 查询语句。第二个方向是换模型。predict.ipynb用了线性回归和随机森林你可以再尝试XGBoost或LightGBM甚至做一个简单的集成投票对比 R2 和 MAE这一组对比实验写进论文里就是第五节“模型对比分析”。第三个方向是加一个结论页。把可视化图片和模型结果汇总到一个报告.ipynb里用gridspec布局把散点图、柱状图、特征重要性图拼成一张大图导出 PDF 直接当论文插图用。# 用交叉验证替代单次 train_test_split结论更稳 from sklearn.model_selection import cross_val_score scores cross_val_score(rf, X_scaled, y, cv5, scoringr2) print(5折交叉验证 R2: %.3f ± %.3f % (scores.mean(), scores.std()))cross_val_score的意义在于单次切分的 R2 可能忽高忽低而 5 折交叉验证的均值和标准差更能反映模型真实水平。答辩时你拿着这个结果说“模型 R2 均值在 0.6 以上且五折波动小于 0.05”说服力会强很多。从那以后我每次拿到新的源码包都会强制走一遍“先看主流程、再跑一次、再改一处”的流程不急着浏览全部代码只改最影响结果的那一环。希望帮到你。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门