基于Spark的短视频推荐系统设计与实现:协同过滤ALS算法与Django实践

发布时间:2026/8/31 17:24:34
基于Spark的短视频推荐系统设计与实现:协同过滤ALS算法与Django实践 之前在做毕业设计选型时很多同学纠结“推荐系统该用什么技术栈”。直接用 Python 写协同过滤显得不够大数据把 Hadoop、Spark 全搭上又担心学习成本和部署难度。本文分享一套完整的“基于 Spark 的个性化短视频推荐系统”设计方案技术栈采用 Hadoop Spark Django 的组合覆盖数据采集、离线推荐、Web 展示全流程。刚准备毕设、对推荐系统感兴趣的同学都能直接复用代码结构和实现思路都做了详细拆解希望能帮你少走弯路。1. 项目背景与系统价值1.1 短视频平台为什么需要个性化推荐短视频平台的核心指标是用户留存和观看时长。如果每个用户打开 App 看到的都是同样的内容内容生态就失去了活力。个性化推荐要解决的核心问题可以概括成一句话在正确的时机把正确的内容推给正确的人。从用户角度来说推荐系统能降低内容筛选成本让用户更快看到感兴趣的视频从平台角度来说推荐系统能提高内容分发效率让优质内容触达目标人群。对于刚接触推荐系统的同学来说可能觉得“推荐”是一个很高深的概念但它在工程实现上是有固定套路的先收集用户行为再建立用户和视频之间的关联模型最后生成推荐列表。本项目以一个简化但完整的短视频平台作为业务背景模拟用户对短视频的观看、点赞、收藏和评分行为使用 Spark 的机器学习库完成模型训练和推荐生成最终通过 Django 将推荐结果展示在网页上。1.2 为什么选择 Spark Hadoop Django 这套技术栈很多同学在做毕设时会纠结“大数据”和“Web”怎么结合这套组合的合理性主要体现在以下三点。第一数据存储和处理环节体现大数据思维。Hadoop 提供 HDFS 分布式文件系统适合存放海量用户行为日志Spark 基于内存计算比传统 MapReduce 更适合迭代式机器学习算法。在毕设的体量下虽然数据量还达不到“海量”但整个项目的数据流、处理逻辑都遵循真实大数据平台的设计思路。第二推荐算法有成熟的分布式实现。Spark MLlib 提供了 ALS交替最小二乘协同过滤算法可以很方便地完成矩阵分解生成用户对视频的预测评分。相比自己手写矩阵分解Spark 的分布式实现能让大家把精力集中在数据清洗、模型评估和系统集成上。第三Django 让推荐结果可视化。推荐系统最终要服务于用户Django 负责用户管理、视频展示、推荐结果渲染。Python 是 Spark 和 Django 的共同语言整个项目只需要掌握一种编程语言降低了开发和调试成本。1.3 毕设项目的合理定位这个项目的定位是“演示完整推荐链路”而不是追求工业界的推荐精度。工业级推荐系统通常包含多路召回、粗排、精排、重排等多个阶段还会用到深度学习模型。而毕设项目中我们更关注业务闭环是否完整从数据采集到推荐展示每个环节必须打通。技术栈是否主流大数据处理、机器学习、Web 开发都有体现。代码结构是否清晰模块解耦、接口规范、文档完整。算法原理是否理解到位能解释 ALS 算法是怎么工作的而不是只会调包。在这一前提下下面开始从原理到实现逐步拆解。2. 推荐系统核心原理2.1 推荐系统的三阶段流程工业界推荐系统虽然复杂但核心流程可以概括为召回、排序和重排三个阶段。召回从海量视频中粗筛出数百个候选视频主要解决“计算量太大”的问题。常用的召回策略包括协同过滤、基于内容的召回、热门补全等。排序对召回的候选视频精打分得到用户对每个视频的兴趣度。排序模型可以使用逻辑回归、GBDT、深度学习等。重排结合多样性、新鲜度、商业规则等约束对排序结果做微调最终生成展示列表。毕设项目中我们把“召回 排序”合并成一步直接使用 ALS 模型对全量用户生成 TopN 推荐列表。原因是数据量不大协同过滤可以直接完成矩阵分解和评分预测不需要复杂的多路召回架构。2.2 什么是协同过滤协同过滤是推荐系统中最经典的算法思想核心假设是相似口味的人会喜欢相似的内容相似内容会吸引相似的人。基于这个思想协同过滤分为两种主要类型基于用户的协同过滤User-Based CF先找到与当前用户兴趣相似的用户群再把相似用户喜欢的内容推荐给当前用户。适合用户量大、内容量相对小的场景。基于物品的协同过滤Item-Based CF先计算物品之间的相似度再根据用户历史行为推荐相似物品。适合物品量大、用户行为稠密的场景短视频平台高度依赖这类方法。ALS 算法是协同过滤的一种矩阵分解实现。它将用户-物品评分矩阵分解成两个低维矩阵相乘用户特征矩阵和物品特征矩阵。通过交替固定其中一个矩阵、优化另一个矩阵不断迭代逼近真实评分。用公式表示就是R(m×n) U(m×k) × V(n×k)^T其中 R 是评分矩阵U 是用户隐含特征矩阵V 是物品隐含特征矩阵k 是隐含特征维度。ALS 的核心步骤是固定物品特征矩阵 V求解用户特征矩阵 U。固定用户特征矩阵 U求解物品特征矩阵 V。重复迭代直到模型收敛或达到最大迭代次数。在 Spark MLlib 中ALS类已经封装好这一过程我们只需要构造好(userId, videoId, rating)三列数据即可。2.3 离线推荐与实时推荐的配合推荐系统按计算时效可以分为离线推荐和实时推荐。离线推荐基于历史数据周期性训练模型生成推荐结果存入数据库。优点是计算规模大、算法可以比较复杂缺点是推荐结果不够实时用户刚看完一个视频推荐列表不会立刻变化。实时推荐基于最近几分钟的行为日志实时计算用户当前最可能感兴趣的内容。实时计算对延迟要求高通常需要 Flink、Spark Streaming 等工具。对于毕设项目建议采用“离线推荐为主 简单在线兜底”的方案Spark 每天或每小时训练一次模型将推荐结果写入 MySQL当用户在线请求推荐列表时如果离线推荐结果为空则使用热门视频兜底。这样既满足业务闭环又不会引入过高的实时计算复杂度。3. 系统整体架构设计3.1 分层架构在动手写代码之前先明确系统架构。本项目按照数据流向分为四层用户行为数据 → 数据存储层 → 离线计算层 → Web 应用层层次技术选型职责数据采集层Python 脚本模拟生成用户观看、点赞、收藏、评分行为数据数据存储层Hadoop HDFS MySQLHDFS 存储原始行为日志MySQL 存储用户、视频、推荐结果离线计算层Spark MLlib Spark SQL数据清洗、特征提取、ALS 模型训练、推荐结果生成Web 应用层Django Bootstrap用户管理、视频展示、推荐结果渲染3.2 数据流转设计系统数据流转过程如下数据采集脚本生成用户行为日志上传到 HDFS 的/recsys/behavior目录。Spark 任务读取 HDFS 中的行为日志进行数据清洗和格式转换。清洗后的数据划分训练集和测试集训练 ALS 模型。模型对全量用户生成 TopN 视频推荐列表结果写回 MySQL。Django 接口从 MySQL 读取推荐结果渲染到用户页面。这种设计的优点是各模块职责单一、耦合度低。后续如果想接入真实用户行为数据只需要替换数据采集层Spark 任务和 Django 应用都不需要大改。3.3 核心模块划分在代码层面项目可以拆成几个独立模块data_generator/用户行为模拟数据生成脚本。spark_recsys/Spark 数据处理与 ALS 推荐任务包含数据清洗、模型训练、推荐结果导出。recsys_django/Django 项目包含用户认证、视频库管理、推荐接口、页面渲染。docs/需求文档、设计文档、测试文档。模块化的好处是方便分工和答辩讲解。论文或答辩 PPT 中可以直接用模块图展示系统设计思路。4. 环境准备与项目结构4.1 环境列表与版本说明版本需要根据你的实际环境调整下面给出的是常见组合重点演示配置思路组件版本建议说明操作系统Windows 10/11 或 Ubuntu 20.04建议 Win 虚拟机 Linux 组合也可以用 macOSPython3.8 / 3.9Spark 对 Python 版本有要求务必备注匹配Java JDK1.8 或 11Hadoop 和 Spark 依赖 Java 环境Hadoop3.x单机伪分布式即可Spark3.x选择与 Hadoop 兼容的版本Django3.x / 4.x建议用 3.2 LTSMySQL5.7 / 8.0存储业务数据和推荐结果PySpark与 Spark 对应pip 安装即可如果本机资源有限可以先将 Spark 配置为本地模式local[*]代码里不强制依赖 HDFS直接读取本地文件也可以。Hadoop 主要用来体现分布式存储能力在毕设中采用伪分布式即可满足需求。4.2 项目目录结构推荐使用下面的目录结构short-video-recsys/ ├── data_generator/ │ ├── generate_behavior.py │ └── behavior_data.csv ├── spark_recsys/ │ ├── data_clean.py │ ├── als_train.py │ └── recommend_export.py ├── recsys_django/ │ ├── manage.py │ ├── recsys/ │ │ ├── settings.py │ │ ├── urls.py │ │ └── wsgi.py │ ├── apps/ │ │ ├── users/ │ │ ├── videos/ │ │ └── recommend/ ├── docs/ │ ├── 需求文档.md │ └── 数据库设计.md └── requirements.txt4.3 初始化准备创建虚拟环境并安装依赖python -m venv venv source venv/bin/activate # Windows 下执行 venv\Scripts\activate pip install django pymysql pandas pyspark同时确认 Spark 的环境变量已配置export JAVA_HOME/usr/lib/jvm/java-8-openjdk-amd64 export HADOOP_HOME/opt/hadoop export SPARK_HOME/opt/spark export PATH$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$SPARK_HOME/bin5. 核心代码实现5.1 模拟用户行为数据生成推荐系统最理想的数据来源是真实业务日志但毕设环境拿不到这样的数据因此需要自己构造一份合理的模拟数据。模拟数据要符合基本业务逻辑用户更倾向于给看过且感兴趣的短视频高评分不同用户对视频类型有不同偏好。下面是生成模拟行为数据的脚本# 文件路径data_generator/generate_behavior.py import csv import random from datetime import datetime, timedelta # 用户ID范围 USER_NUM 100 VIDEO_NUM 500 # 视频类型 CATEGORIES [搞笑, 科技, 美食, 旅行, 游戏, 音乐, 舞蹈, 影视] # 生成视频信息表 def generate_videos(): videos [] for vid in range(1, VIDEO_NUM 1): uploader random.randint(1, 50) category random.choice(CATEGORIES) videos.append([vid, f视频标题{vid}, category, random.randint(10, 5000)]) with open(videos_data.csv, w, newline, encodingutf-8) as f: writer csv.writer(f) writer.writerow([video_id, title, category, play_count]) writer.writerows(videos) # 生成用户行为数据 def generate_behavior(): behaviors [] for uid in range(1, USER_NUM 1): # 每个用户观看20-80个视频 watched_count random.randint(20, 80) watched_videos random.sample(range(1, VIDEO_NUM 1), watched_count) for vid in watched_videos: # 评分 1-5 rating random.randint(3, 5) # 随机添加点赞和收藏 like random.randint(0, 1) favorite random.randint(0, 1) timestamp datetime.now() - timedelta(daysrandom.randint(0, 30)) behaviors.append([uid, vid, rating, like, favorite, timestamp.strftime(%Y-%m-%d %H:%M:%S)]) with open(behavior_data.csv, w, newline, encodingutf-8) as f: writer csv.writer(f) writer.writerow([user_id, video_id, rating, like, favorite, timestamp]) writer.writerows(behaviors) if __name__ __main__: generate_videos() generate_behavior() print(模拟数据生成完成)代码中设计了USER_NUM 100和VIDEO_NUM 500这个规模方便在单机环境快速跑通。如果想让推荐效果更明显可以增大用户数和视频数让用户画像更丰富。生成好的behavior_data.csv可以放到 HDFS 中也可以暂时放在本地Spark 读取路径决定。5.2 使用 Spark 完成数据清洗拿到原始行为数据后需要先做数据清洗。本阶段要处理的主要问题包括过滤缺失字段的脏数据。将时间戳字符串解析为标准格式。去除评分明显异常的记录。统计每个用户的行为数量排除行为过少的用户。下面用 PySpark 完成清洗和统计# 文件路径spark_recsys/data_clean.py from pyspark.sql import SparkSession from pyspark.sql.functions import col, to_timestamp, count spark SparkSession.builder \ .appName(ShortVideoRecsysDataClean) \ .master(local[*]) \ .config(spark.sql.shuffle.partitions, 10) \ .getOrCreate() # 读取CSV文件 df spark.read.csv( behavior_data.csv, headerTrue, inferSchemaTrue, encodingutf-8 ) # 数据清洗过滤空值、转换时间字段 df_clean df.filter( col(user_id).isNotNull() col(video_id).isNotNull() col(rating).isNotNull() ).withColumn( timestamp, to_timestamp(col(timestamp), yyyy-MM-dd HH:mm:ss) ) # 过滤评分异常数据 df_clean df_clean.filter((col(rating) 1) (col(rating) 5)) # 查看用户行为数量分布 user_behavior_count df_clean.groupBy(user_id).agg( count(video_id).alias(behavior_count) ) user_behavior_count.show(10) # 保存清洗后的数据 df_clean.write.mode(overwrite).csv(behavior_clean, headerTrue) print(数据清洗完成) spark.stop()这里需要注意master(local[*])表示使用本机全部 CPU 核心运行适合开发调试。如果部署到集群可以去掉master参数并通过spark-submit指定。5.3 ALS 推荐模型训练清洗完成后的数据就是标准的三元组(user_id, video_id, rating)。下面使用 Spark MLlib 的 ALS 算法训练推荐模型# 文件路径spark_recsys/als_train.py from pyspark.sql import SparkSession from pyspark.ml.evaluation import RegressionEvaluator from pyspark.ml.recommendation import ALS spark SparkSession.builder \ .appName(ShortVideoRecsysALS) \ .master(local[*]) \ .getOrCreate() # 读取清洗后的数据 df spark.read.csv(behavior_clean, headerTrue, inferSchemaTrue) df df.select( col(user_id).alias(userId), col(video_id).alias(videoId), col(rating).alias(rating) ) # 划分训练集和测试集 train_data, test_data df.randomSplit([0.8, 0.2], seed42) # 构建ALS模型 als ALS( maxIter10, # 最大迭代次数 regParam0.1, # 正则化参数防止过拟合 rank10, # 隐含特征维度 userColuserId, itemColvideoId, ratingColrating, coldStartStrategydrop # 遇到未知用户或物品时直接丢弃避免NaN ) # 训练模型 print(开始训练ALS模型...) model als.fit(train_data) # 在测试集上评估 predictions model.transform(test_data) evaluator RegressionEvaluator( metricNamermse, labelColrating, predictionColprediction ) rmse evaluator.evaluate(predictions) print(f测试集 RMSE {rmse}) # 保存模型 model.write().overwrite().save(als_model) print(ALS模型训练完成) spark.stop()关于几个关键参数这里做一下说明maxIter10ALS 迭代次数越大模型越容易收敛但训练时间也越长。毕设数据量小10 次足够。regParam0.1正则化系数控制模型复杂度。值过小容易过拟合值过大容易欠拟合实际中可以通过网格搜索调整。rank10隐含特征维度可以理解为用户兴趣和视频内容被压缩成的特征数。维度越高表达越强但计算量也越大。coldStartStrategydrop当测试数据中存在训练集没见过的用户或物品时直接丢弃预测结果否则会产生 NaN。评估指标 RMSE 表示预测评分与真实评分的均方根误差RMSE 越小说明模型预测越准确。在毕设中展示这个指标是用来证明模型有效性的重要论据。5.4 生成用户推荐列表模型训练完成后通过recommendForAllUsers为每个用户生成 TopN 推荐列表。推荐结果是数组类型需要做展开处理再写入 MySQL。# 文件路径spark_recsys/recommend_export.py from pyspark.sql import SparkSession from pyspark.ml.recommendation import ALSModel from pyspark.sql.functions import explode, col spark SparkSession.builder \ .appName(ShortVideoRecsysExport) \ .master(local[*]) \ .getOrCreate() # 加载已训练的模型 model ALSModel.load(als_model) # 为所有用户生成每个用户Top20推荐 user_recs model.recommendForAllUsers(20) # 将推荐数组展开为多行 user_recs_detail user_recs.select( col(userId), explode(col(recommendations)).alias(rec) ).select( col(userId), col(rec.videoId).alias(videoId), col(rec.rating).alias(predictRating) ) user_recs_detail.show(20, truncateFalse) # 写入数据库或HDFS user_recs_detail.write.mode(overwrite).csv(user_top20_recs, headerTrue) print(推荐结果生成完成) spark.stop()在 PySpark 中recommendations是一个结构体数组每个元素包含videoId和rating两个字段。explode函数将一行中的数组拆成多行便于后续处理。5.5 Django 后端接口实现Spark 计算得到的推荐结果最终要通过 Django 展示到页面上。Django 项目需要设计数据模型、接口视图和模板页面。先看数据模型设计# 文件路径recsys_django/apps/videos/models.py from django.db import models class Video(models.Model): video_id models.IntegerField(uniqueTrue, verbose_name视频ID) title models.CharField(max_length200, verbose_name视频标题) category models.CharField(max_length50, verbose_name视频分类) play_count models.IntegerField(default0, verbose_name播放量) cover_url models.URLField(blankTrue, verbose_name封面地址) class Meta: db_table video verbose_name 视频 def __str__(self): return self.title class UserBehavior(models.Model): user models.ForeignKey(users.UserProfile, on_deletemodels.CASCADE) video models.ForeignKey(Video, on_deletemodels.CASCADE) rating models.IntegerField(default0, verbose_name评分) created_time models.DateTimeField(auto_now_addTrue, verbose_name行为时间) class Meta: db_table user_behavior verbose_name 用户行为 class RecommendResult(models.Model): user models.ForeignKey(users.UserProfile, on_deletemodels.CASCADE) video models.ForeignKey(Video, on_deletemodels.CASCADE) predict_rating models.FloatField(default0, verbose_name预测评分) recommend_time models.DateTimeField(auto_nowTrue, verbose_name推荐时间) is_clicked models.BooleanField(defaultFalse, verbose_name是否点击) class Meta: db_table recommend_result verbose_name 推荐结果这里有两个关键点RecommendResult表用于存储 Spark 计算的推荐结果UserBehavior表用于存储用户在线产生的行为数据。接下来实现推荐接口# 文件路径recsys_django/apps/recommend/views.py from django.shortcuts import render from django.http import JsonResponse from django.views.decorators.http import require_GET from videos.models import RecommendResult, Video require_GET def recommend_list(request): 获取当前用户的个性化推荐视频列表 user_id request.GET.get(user_id) if not user_id: return JsonResponse({code: 1, msg: 缺少user_id参数}) # 查询该用户的推荐结果按预测评分降序 recs RecommendResult.objects.filter( user_iduser_id ).select_related(video).order_by(-predict_rating)[:20] video_list [ { video_id: rec.video.video_id, title: rec.video.title, category: rec.video.category, predict_rating: round(rec.predict_rating, 2) } for rec in recs ] return JsonResponse({code: 0, data: video_list})页面渲染部分可以加一个简单的 HTML 模板推荐给前端开发经验较少的同学使用 Django 模板引擎加 Bootstrap!-- 文件路径recsys_django/templates/recommend.html -- !DOCTYPE html html langzh-CN head meta charsetUTF-8 title个性化推荐/title link hrefhttps://cdn.staticfile.org/bootstrap/5.1.3/css/bootstrap.min.css relstylesheet /head body div classcontainer mt-4 h2为你推荐/h2 div classrow {% for rec in video_list %} div classcol-md-4 mb-3 div classcard div classcard-body h5 classcard-title{{ rec.title }}/h5 p classcard-text分类{{ rec.category }}/p p classcard-text推荐指数{{ rec.predict_rating }}/p /div /div /div {% endfor %} /div /div /body /html对应的视图函数可以写成def recommend_page(request): user_id request.GET.get(user_id, 1) recs RecommendResult.objects.filter( user_iduser_id ).select_related(video).order_by(-predict_rating)[:12] video_list [ { title: rec.video.title, category: rec.video.category, predict_rating: round(rec.predict_rating, 2) } for rec in recs ] return render(request, recommend.html, {video_list: video_list})这样就完成了从 Spark 到 Django 的完整闭环。系统启动后用户访问指定 URL 即可看到个性化推荐列表。6. 部署运行与推荐效果验证6.1 启动依赖服务如果使用 Hadoop HDFS 存储原始数据需要先启动 HDFSstart-dfs.sh jps看到NameNode和DataNode进程即说明启动成功。如果不使用 HDFS这一步骤可以跳过。然后准备 MySQL 数据库创建项目数据库并导入 Django 数据表mysql -uroot -p -e CREATE DATABASE recsys DEFAULT CHARACTER SET utf8mb4; cd recsys_django python manage.py makemigrations python manage.py migrate6.2 提交 Spark 离线任务运行数据清洗和模型训练# 方式一本地 Python 执行 python spark_recsys/data_clean.py python spark_recsys/als_train.py python spark_recsys/recommend_export.py # 方式二spark-submit 提交更贴近真实环境 spark-submit --master local[*] spark_recsys/als_train.py运行日志中会显示训练进度最后输出测试集 RMSE。将user_top20_recs中的结果导入 MySQL 表recommend_result。导入时可以使用 pandas 辅助import pandas as pd from sqlalchemy import create_engine recs_df pd.read_csv(user_top20_recs.csv) engine create_engine(mysqlpymysql://root:passwordlocalhost:3306/recsys?charsetutf8mb4) recs_df.to_sql(recommend_result, conengine, if_existsreplace, indexFalse)注意实际导入前要检查列名和数据类型是否与 Django 模型一致或通过 Django 脚本完成导入避免数据映射错误。由于RecommendResult涉及外键建议直接用 Django ORM 操作先查询对应的UserProfile和Video实例再创建推荐记录。6.3 启动 Django 并验证接口cd recsys_django python manage.py runserver 0.0.0.0:8000浏览器访问推荐页面http://127.0.0.1:8000/recommend/?user_id1页面上会展示该用户的个性化推荐视频列表。也可以通过 JSON 接口验证http://127.0.0.1:8000/api/recommend/?user_id1预期返回结构示例{ code: 0, data: [ { video_id: 321, title: 视频标题321, category: 科技, predict_rating: 4.87 }, { video_id: 87, title: 视频标题87, category: 搞笑, predict_rating: 4.65 } ] }7. 常见问题与排查思路问题现象常见原因解决思路Spark 启动时报 Java 版本错误JDK 版本与 Hadoop/Spark 不兼容切换到 JDK 1.8 或 11重新配置 JAVA_HOMEpyspark导入失败当前 Python 环境没有安装 PySpark执行pip install pyspark确认版本与 Spark 一致ALS 预测结果出现 NaN测试集中存在冷启动用户或物品设置coldStartStrategydropHadoop NameNode 启动失败未初始化 HDFS 或端口被占用执行hdfs namenode -format检查 9870 端口占用中文数据乱码CSV 文件编码问题或 MySQL 字符集问题CSV 统一使用 UTF-8MySQL 指定utf8mb4Django 页面无法加载推荐结果表为空或外键关联错误检查recommend_result中是否写入数据确认 Video 数据已导入Spark 任务运行内存不足本机内存太小或分区数设置不合理使用local[2]调大 JVM 内存参数recommendForAllUsers数据量过大用户数多、商品数多导致全量预测耗时按用户分组分批生成或用recommendForUserSubset排查系统问题时推荐按“数据流”顺序排查先看原始数据是否生成成功再看 Spark 清洗后的数据是否符合预期然后确认推荐结果是否写入数据库最后检查 Django 接口返回是否正常。从底层到顶层逐层定位可以快速缩小问题范围。8. 最佳实践与工程建议8.1 代码与开发规范模块间通过文件或数据库解耦。Spark 任务和 Django 应用不直接互相调用中间通过 HDFS 文件和 MySQL 表传递数据这样两个模块可以独立开发、独立测试。使用虚拟环境管理 Python 依赖。requirements.txt写明依赖库及版本方便论文附录和环境复现。配置集中管理。HDFS 路径、MySQL 地址、Spark 参数不要散落在代码中统一放到配置文件里。日志记录完整。Spark 任务打印关键步骤和指标Django 接口记录请求参数和响应状态为排错提供依据。8.2 数据与安全边界这个项目会涉及用户数据做设计和论文时要有数据安全意识。模拟数据不能包含真实用户信息。字段命名避免身份证、手机号等敏感信息演示时使用脱敏数据。不要在生产环境直接跑未经验证的 Spark 任务。修改模型参数或清洗逻辑后先在测试环境小数据量验证。数据库操作遵循最小权限原则。开发环境不要使用 root 账号连接业务库创建专用账号并授权必要的增删改查权限。删除或覆盖推荐结果表前先备份。推荐结果由 Spark 生成属于可恢复数据但涉及 MySQL 表结构变更时仍然要谨慎操作。8.3 系统扩展方向在毕设项目基础上如果想进一步体现深度可以从以下几个方向扩展引入实时推荐。使用 Spark Streaming 或 Flink 监听用户实时行为将最近点击的视频作为实时候选跟离线推荐结果融合。解决冷启动问题。新用户没有行为数据时ALS 无法生成推荐可以加入基于视频热门度和类目偏好的冷启动策略。增加多样性控制。推荐列表中同一类目的视频不要连续出现过多可以通过重排阶段按类目均匀抽取。加入内容特征。ALS 只用到了评分矩阵还可以将视频类目、封面图特征、文本特征拼接成向量使用深度学习模型排序。推荐效果评估。除了 RMSE还可以加入精确率、召回率、覆盖率、多样性等离线指标以及点击率、留存率等在线指标。毕设项目的评分不只是看代码能否运行更看重你对系统设计和算法原理的理解。建议在论文中画清楚系统架构图、数据 ER 图、流程时序图同时附上一份详细的测试报告这样整个项目的完整度和说服力会明显提升。做这个项目的过程中我最大的感受是推荐系统并不只是“训练一个模型”那么简单真正有价值的是把业务问题拆成数据问题、把数据问题拆成工程问题。从模拟数据生成到 Spark 建模再到 Django 展示每一步都需要想清楚数据从哪里来、到哪里去、中间经过了什么处理。希望这篇文章能给你一个清晰的项目框架照着这个思路去实现遇到问题也更容易定位。如果本文对你有帮助可以收藏备用后面实现过程中遇到具体报错欢迎在评论区交流讨论。