资讯动态

Python机器学习毕业设计:电影推荐系统与票房预测实战

发布时间:2026/10/3 12:35:57 来源:尧图企业网站定制
简介这份资源面向计算机相关专业的毕业生与课程设计学习者提供一套基于Python与机器学习算法的电影推荐系统及票房预测系统完整方案可用于毕业设计、期末大作业等高分场景。压缩包共59个文件约30.95MB包含16个py源码文件、16个csv数据集、23张png图表、2个md说明文档及1份pdf报告覆盖数据预处理、特征工程、模型训练与结果可视化全流程。推荐系统部分涉及协同过滤、基于内容的推荐及KNN、SVD等混合模型票房预测部分则采用线性回归与随机决策树并配有特征可视化脚本与数据分析报告。目前已有343人学习代码注释详尽新手也能理解部署目录按data、prediction、ensemble_recommender等模块划分便于按需查阅与二次开发。1. 电影推荐与票房预测一个毕业设计为什么能同时踩中两个机器学习高频场景做毕业设计选题时很多同学会陷入两难推荐系统看起来太烂大街票房预测又怕数据拿不到。但把这两个场景放进同一个项目里反而能形成一条完整的技术闭环——推荐系统解决“用户看什么”票房预测解决“片方赚多少”两者共享同一套数据清洗、特征工程和模型评估流程。这个标题下的项目本质上是用 Python 和机器学习算法把电影领域的两个核心问题串起来一个基于用户行为做协同过滤或内容推荐一个基于上映前可获取的特征做回归预测。适合谁适合正在找毕业设计方向、想用 Python 把机器学习从课本推到可运行系统的本科生也适合刚入门机器学习、想找一个有真实数据感、能写进简历的练手项目。热搜词里“python机器学习”“电影推荐系统”“票房预测系统”反复出现说明这个组合的检索需求一直很稳不是短期噱头。2. 推荐系统选型协同过滤、矩阵分解还是内容推荐先看数据长什么样2.1 三种主流推荐路线的适用边界电影推荐系统在毕业设计里最常见的三种做法基于用户的协同过滤UserCF、基于物品的协同过滤ItemCF、矩阵分解SVD/NMF以及基于内容TF-IDF 余弦相似度。选哪个不取决于哪个“高级”而取决于你手头有什么数据。如果你拿到的是 MovieLens 这类标准数据集用户-物品评分矩阵比较稠密UserCF 和 ItemCF 都能跑出可解释的结果。UserCF 适合用户兴趣相似度高的场景比如影迷社区ItemCF 适合物品之间关联强的场景比如“看了这部也看那部”的推荐位。矩阵分解在评分预测任务上通常比邻域方法更稳因为它把稀疏矩阵拆成隐向量能缓解数据稀疏问题。内容推荐则完全不依赖用户行为只要有电影元数据类型、导演、演员、简介就能给新用户做推荐冷启动友好但精度上限低。我一般会建议主推矩阵分解做评分预测辅以 ItemCF 做相似电影推荐内容推荐作为冷启动兜底。这样论文里既有对比实验系统里也有实际可用的推荐结果。2.2 用 Surprise 库跑通矩阵分解的最小代码# 安装pip install scikit-surprise from surprise import Dataset, Reader, SVD from surprise.model_selection import train_test_split from surprise import accuracy # 加载 MovieLens-100k格式user item rating timestamp reader Reader(line_formatuser item rating timestamp, sep\t) data Dataset.load_from_file(ml-100k/u.data, readerreader) # 划分训练集和测试集random_state 固定保证可复现 trainset, testset train_test_split(data, test_size0.2, random_state42) # 使用 SVD 矩阵分解n_factors 是隐向量维度n_epochs 是迭代轮数 algo SVD(n_factors50, n_epochs20, lr_all0.005, reg_all0.02) algo.fit(trainset) # 预测并评估 predictions algo.test(testset) accuracy.rmse(predictions, verboseTrue)这段代码的核心逻辑是把评分数据加载成 Surprise 能识别的格式用 SVD 做矩阵分解最后用 RMSE 衡量预测评分和真实评分的差距。参数方面n_factors控制隐向量维度太小欠拟合太大容易过拟合50 是常见起点n_epochs是 SGD 迭代次数20 到 50 之间看收敛情况lr_all是学习率0.005 比较稳reg_all是正则化系数防止过拟合。跑完如果 RMSE 在 0.9 左右说明模型基本可用。失败时先看数据格式对不对Surprise 对分隔符和列顺序很敏感line_format写错会直接报错。2.3 物品相似度计算与推荐结果生成矩阵分解给出的是评分预测但用户需要的是“推荐列表”。常见做法是用 ItemCF 计算物品相似度然后对用户看过的电影找相似电影。import pandas as pd from sklearn.metrics.pairwise import cosine_similarity # 构建用户-物品评分矩阵 ratings pd.read_csv(ml-100k/u.data, sep\t, names[user, item, rating, ts]) matrix ratings.pivot_table(indexuser, columnsitem, valuesrating).fillna(0) # 计算物品之间的余弦相似度 item_sim cosine_similarity(matrix.T) item_sim_df pd.DataFrame(item_sim, indexmatrix.columns, columnsmatrix.columns) def recommend_similar(item_id, top_n10): # 取相似度最高的 top_n 个物品排除自身 sim_scores item_sim_df[item_id].sort_values(ascendingFalse)[1:top_n1] return sim_scores # 示例找与电影 1 最相似的 10 部 print(recommend_similar(1))这里用余弦相似度衡量物品向量之间的夹角值越接近 1 越相似。pivot_table把长表转成宽表缺失值填 0 表示未评分。注意填 0 会引入“未评分等于不喜欢”的偏差更严谨的做法是用均值填充或只对共同评分用户计算相似度。毕业设计里如果只求跑通填 0 可以接受但论文里要说明这个简化。3. 票房预测系统从数据获取到特征工程哪些字段真正影响预测3.1 票房预测的数据来源与字段选择票房预测比推荐系统更依赖外部数据。常见做法是从公开数据平台抓取电影元数据预算、类型、导演、演员、上映时间、时长、制片公司和上映后数据首周票房、排片率、上座率。但毕业设计里最容易踩的坑是用了上映后才有的数据去预测上映前的结果这叫数据泄漏模型指标会虚高答辩时容易被问住。我一般会严格区分两类特征上映前可获取的预算、类型、导演历史票房、演员热度、档期、是否续集和上映后才有的首周票房、观众评分、社交媒体讨论量。如果做“上映前预测”只能用前者如果做“上映后修正预测”可以加入首周数据。论文里最好两种都做对比一下加入首周数据后 RMSE 下降多少这本身就是个有价值的实验。3.2 用 Pandas 做特征工程与缺失值处理import pandas as pd import numpy as np # 假设已有电影数据表 movies.csv df pd.read_csv(movies.csv) # 处理预算去掉货币符号转成数值缺失值用中位数填充 df[budget] df[budget].replace([\$,], , regexTrue).astype(float) df[budget] df[budget].fillna(df[budget].median()) # 类型做 one-hot 编码取前 10 个高频类型 genres df[genres].str.get_dummies(sep|) top_genres genres.sum().sort_values(ascendingFalse).head(10).index genres genres[top_genres] # 上映月份提取档期对票房影响很大 df[release_date] pd.to_datetime(df[release_date], errorscoerce) df[release_month] df[release_date].dt.month df[is_summer] df[release_month].isin([6, 7, 8]).astype(int) df[is_holiday] df[release_month].isin([1, 2, 12]).astype(int) # 合并特征 features pd.concat([df[[budget, popularity, runtime]], genres, df[[is_summer, is_holiday]]], axis1) features features.fillna(0)这段代码做了四件事预算字段清洗、类型 one-hot、档期特征提取、缺失值填充。budget里的货币符号和逗号必须去掉否则astype(float)会报错。类型字段用str.get_dummies按|拆分只保留高频类型避免维度爆炸。档期特征里暑期档和贺岁档通常是票房高峰做成 0/1 变量让模型更容易捕捉。popularity和runtime如果有缺失填 0 或中位数都行但要在论文里说明。3.3 回归模型对比线性回归、随机森林和 XGBoost 的 RMSE 差异票房预测本质是回归任务。毕业设计里至少跑三个模型做对比线性回归基线、随机森林非线性、XGBoost集成学习。评价指标用 RMSE 和 R²。from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression from sklearn.ensemble import RandomForestRegressor from xgboost import XGBRegressor from sklearn.metrics import mean_squared_error, r2_score import numpy as np X features y df[revenue].fillna(df[revenue].median()) X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) models { LinearRegression: LinearRegression(), RandomForest: RandomForestRegressor(n_estimators100, random_state42), XGBoost: XGBRegressor(n_estimators100, learning_rate0.1, random_state42) } for name, model in models.items(): model.fit(X_train, y_train) pred model.predict(X_test) rmse np.sqrt(mean_squared_error(y_test, pred)) r2 r2_score(y_test, pred) print(f{name}: RMSE{rmse:.2f}, R2{r2:.4f})参数上随机森林的n_estimators从 100 起步树越多越稳但计算越慢XGBoost 的learning_rate控制每棵树的贡献0.1 是常用值调小到 0.05 通常能提升一点精度但需要更多树。如果 XGBoost 的 RMSE 明显低于线性回归说明特征和票房之间确实存在非线性关系论文里可以展开分析特征重要性。注意票房数据通常右偏严重取对数后再预测往往效果更好np.log1p(y)是个实用技巧。4. 避坑与排查推荐和票房预测里最容易翻车的五个地方4.1 评分矩阵稀疏导致推荐结果全是热门电影现象不管给哪个用户推荐出来的都是那几部最热门的电影个性化推荐形同虚设。原因评分矩阵太稀疏大部分用户只评了几部电影相似度计算时共同评分项太少模型退化成“推荐大家都看的”。解决降低相似度计算的共同评分阈值或者改用矩阵分解隐向量能在低维空间捕捉用户偏好不依赖共同评分。另外可以在推荐列表里加入多样性约束比如强制每个类型至少出现一部。4.2 票房预测用了上映后数据导致指标虚高现象模型 RMSE 很低R² 接近 0.9但答辩时被问“首周票房是上映后才知道的你怎么预测”原因特征里混入了上映后才能获取的字段比如首周票房、观众评分、社交媒体热度。解决严格按时间切分特征上映前预测只能用上映前可获取的数据。如果要做上映后修正单独建一个模型论文里分开报告指标。4.3 类型字段 one-hot 后维度爆炸现象电影类型有几十种one-hot 后特征维度从几十涨到几百模型训练变慢还容易过拟合。原因低频类型出现次数太少对模型没有泛化价值。解决只保留高频类型或者把低频类型合并成“其他”。常见做法是取累计出现次数前 80% 的类型剩下的归为一类。这样既保留了主要信息又控制了维度。4.4 缺失值填充方式不一致导致训练和预测行为不同现象训练时用中位数填充预测时用 0 填充模型在测试集上表现正常上线后预测结果离谱。原因填充逻辑没有封装成统一的预处理管道训练和推理走了两套代码。解决用 sklearn 的Pipeline把填充、编码、模型串起来训练和预测都走同一个管道。或者至少把填充值保存下来预测时用同样的值。4.5 随机种子不固定导致实验结果无法复现现象每次跑代码得到的 RMSE 都不一样论文里写的结果和别人复现的对不上。原因train_test_split和模型初始化没有固定random_state。解决所有涉及随机的地方都设random_state42包括数据划分、模型初始化、交叉验证。这不是玄学是保证实验可复现的基本操作。5. 把两个系统串成一个可演示的毕业设计接口设计、评估报告和答辩技巧5.1 用 Flask 把推荐和预测封装成两个 API毕业设计最终要能演示。推荐系统和票房预测系统可以各自封装成一个 REST API前端用一个简单页面调用。推荐接口接收用户 ID返回推荐电影列表预测接口接收电影特征返回预测票房。from flask import Flask, request, jsonify import pickle app Flask(__name__) # 加载训练好的模型和推荐器 with open(svd_model.pkl, rb) as f: svd_model pickle.load(f) with open(xgb_model.pkl, rb) as f: xgb_model pickle.load(f) app.route(/recommend, methods[GET]) def recommend(): user_id int(request.args.get(user_id)) # 这里简化处理取用户未看过的电影按预测评分排序 # 实际代码需要维护用户已看列表和候选电影集 candidates [1, 2, 3, 4, 5] # 示例候选 preds [(i, svd_model.predict(user_id, i).est) for i in candidates] preds.sort(keylambda x: x[1], reverseTrue) return jsonify({user_id: user_id, recommendations: [i for i, _ in preds[:5]]}) app.route(/predict, methods[POST]) def predict(): data request.json features [[data[budget], data[popularity], data[runtime], data[is_summer], data[is_holiday]]] pred xgb_model.predict(features)[0] return jsonify({predicted_revenue: float(pred)}) if __name__ __main__: app.run(debugTrue)这个示例把两个模型加载进来推荐接口返回 top-5 电影 ID预测接口返回票房数值。实际项目中推荐接口需要维护用户已看列表和候选电影集预测接口需要和训练时的特征顺序完全一致。debugTrue只用于开发演示时关掉。5.2 评估报告里必须写清楚的四个指标论文里的评估部分不能只写“效果不错”。推荐系统至少写 RMSE评分预测、PrecisionK、RecallK、覆盖率。票房预测至少写 RMSE、MAE、R²、特征重要性排序。PrecisionK 衡量推荐列表里有多少是用户真正喜欢的RecallK 衡量用户喜欢的电影有多少被推荐出来覆盖率衡量系统能推荐出多少不同电影避免全是热门。票房预测的特征重要性可以用 XGBoost 的feature_importances_直接输出预算、档期、导演历史票房通常是前三。5.3 答辩时被问“创新点在哪”怎么答毕业设计的创新点不一定是算法创新。把两个场景串起来、做了完整的特征工程对比、实现了可演示的系统、分析了数据泄漏的影响这些都是工程层面的创新。我一般会建议准备三个回答方向第一推荐和预测共享了同一套数据清洗和特征工程流程减少了重复开发第二对比了多种模型并给出了选型依据不是随便挑一个第三系统可演示、代码可复现不是只跑了个 notebook。如果答辩老师追问算法细节就回到 SVD 的隐向量含义和 XGBoost 的 boosting 原理这两个讲清楚就够用了。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑