1. 项目概述:基于DeepFM的影视推荐系统实战
最近花了三周时间,从零搭建了一套完整的影视推荐系统。这个项目采用Django+Vue.js全栈架构,核心推荐算法使用了PyTorch实现的DeepFM模型,同时整合了爬虫数据采集和可视化数据分析模块。作为一个同时涉及前后端开发和机器学习落地的综合项目,过程中踩了不少坑,也积累了一些值得分享的经验。
这个系统最核心的价值在于解决了传统推荐系统的两个痛点:一是通过DeepFM模型融合了低阶特征组合和高阶特征交互,显著提升了推荐准确率;二是设计了完善的冷启动策略,当新用户或数据不足时能自动降级到基于流行度的推荐,保证系统可用性。前端采用Vue3+Element Plus构建响应式界面,后端用Django REST framework提供API服务,整体架构清晰、扩展性强。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术栈选型与架构设计
2.1 为什么选择这些技术?
前端选择Vue3的原因:
- 组合式API更适合复杂交互场景(如推荐结果实时刷新)
- Element Plus组件库能快速搭建管理后台界面
- Pinia的状态管理机制完美适配推荐系统的多状态需求
- ECharts对可视化分析的支持度最好
后端选择Django的考量:
- ORM层对MySQL的友好支持简化了数据操作
- Django REST framework的序列化器完美适配前端数据格式
- 内置的Admin站点快速生成管理后台
- JWT认证机制保障接口安全
深度学习框架选型:
- PyTorch的动态图特性便于调试推荐模型
- 与Python生态的无缝集成(NumPy/Pandas等)
- 丰富的预构建层简化DeepFM实现
2.2 系统架构图解
code复制[前端Vue3] ←HTTP→ [Django REST API] ←→ [MySQL]
↑
↓
[PyTorch模型服务]
↑
↓
[爬虫服务] → [数据清洗] → [特征工程]
关键设计决策:
- 前后端完全分离,通过CORS处理跨域
- 模型训练与服务分离,通过接口提供推荐
- 使用Redis缓存热门推荐结果
- 定时任务更新模型和数据集
3. 核心功能实现细节
3.1 DeepFM模型实现
模型结构代码关键部分:
python复制class DeepFM(nn.Module):
def __init__(self, feature_sizes, embedding_size=4):
super().__init__()
# FM部分
self.fm_linear = nn.Embedding(sum(feature_sizes), 1)
self.fm_embeddings = nn.Embedding(sum(feature_sizes), embedding_size)
# Deep部分
self.deep = nn.Sequential(
nn.Linear(len(feature_sizes)*embedding_size, 64),
nn.ReLU(),
nn.Linear(64, 32),
nn.ReLU(),
nn.Linear(32, 1)
)
def forward(self, x):
# FM二阶交叉项
fm_embeds = self.fm_embeddings(x)
fm_term = 0.5 * (torch.sum(fm_embeds, dim=1)**2 -
torch.sum(fm_embeds**2, dim=1))
# Deep部分
deep_input = fm_embeds.view(x.size(0), -1)
deep_term = self.deep(deep_input)
# 合并输出
return torch.sigmoid(fm_term + deep_term).squeeze()
参数调优经验:
- 嵌入维度设为4-8效果最佳(测试集AUC提升约3%)
- 使用AdamW优化器比普通Adam更稳定
- 学习率设为0.001配合余弦退火策略
- Batch size设置为256时训练效率最高
3.2 冷启动策略实现
python复制def get_recommendations(user_id):
if not user_id: # 未登录用户
return get_popular_movies()
user_ratings = Rating.objects.filter(user_id=user_id).count()
if user_ratings < 5: # 新用户冷启动
return hybrid_recommend(user_id)
# 正常推荐流程
return deepfm_recommend(user_id)
def hybrid_recommend(user_id):
# 混合内容相似度和协同过滤
watched = History.objects.filter(user_id=user_id).values_list('movie_id')
similar_movies = ContentSimilarity.get_similar(watched)
cf_movies = UserCF.recommend(user_id)
return merge_results(similar_movies, cf_movies)
3.3 特征工程关键步骤
-
用户特征:
- 年龄分段(one-hot编码)
- 性别(二进制编码)
- 活跃度(登录频率分桶)
-
电影特征:
- 类型(multi-hot编码)
- 上映年份(分 decade处理)
- 豆瓣评分(标准化到0-1)
-
交叉特征:
- 用户年龄×电影类型
- 用户性别×电影主演性别
- 时间衰减因子(最近浏览权重更高)
重要提示:特征分箱时建议使用qcut而非等距分箱,能更好处理长尾分布
4. 系统部署与性能优化
4.1 后端API性能优化
通过Django Debug Toolbar分析发现,推荐接口的N+1查询问题严重。优化措施:
- 使用select_related/prefetch_related:
python复制ratings = Rating.objects.select_related('movie').filter(user=user)
- 添加数据库索引:
sql复制CREATE INDEX idx_user_movie ON ratings (user_id, movie_id);
- 引入缓存层:
python复制from django.core.cache import cache
def get_recs(user_id):
cache_key = f'recs_{user_id}'
if result := cache.get(cache_key):
return result
# ...计算逻辑...
cache.set(cache_key, result, timeout=3600)
return result
4.2 前端性能关键指标
通过Lighthouse测试,优化前后对比:
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 首屏加载 | 4.2s | 1.8s |
| 推荐接口响应 | 680ms | 220ms |
| 内存占用 | 85MB | 52MB |
优化手段:
- 推荐结果分页加载(每页10条)
- 图片懒加载+WebP格式转换
- 组件级代码分割
- Pinia状态持久化
5. 踩坑实录与解决方案
5.1 模型训练常见问题
问题1:损失函数震荡不收敛
- 原因:特征尺度不一致
- 解决:对数值特征做标准化
python复制from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
train_features = scaler.fit_transform(train_features)
问题2:过拟合严重
- 现象:训练AUC 0.92 → 测试AUC 0.68
- 解决方案:
- 添加Dropout层(p=0.3)
- 早停机制(patience=5)
- L2正则化(weight_decay=1e-4)
5.2 前后端联调陷阱
跨域问题:
python复制# settings.py
CORS_ALLOWED_ORIGINS = [
"http://localhost:8080",
"http://your-production-domain.com"
]
INSTALLED_APPS += ['corsheaders']
接口版本控制:
python复制# urls.py
urlpatterns = [
path('api/v1/recommend/', RecommendView.as_view()),
]
5.3 数据采集注意事项
豆瓣爬虫需要特别注意:
- 设置合理延迟(≥3秒/请求)
- 使用随机User-Agent
- 处理反爬机制:
python复制headers = {
'User-Agent': random.choice(user_agents),
'Referer': 'https://movie.douban.com/'
}
6. 项目扩展方向
- 实时推荐:接入Kafka处理用户实时行为
- 多模态推荐:结合封面图片视觉特征
- AB测试框架:对比不同算法效果
- 边缘部署:使用ONNX格式部署模型到移动端
这个项目最让我惊喜的是DeepFM在CTR预估上的表现——相比传统的矩阵分解方法,AUC提升了15%以上。不过要提醒的是,推荐系统是个持续优化的过程,上线后还需要建立完善的数据监控和模型迭代机制
