当前位置: 首页 > news >正文

基于Surprise和Flask构建个性化电影推荐系统:从算法到全栈实现

一、引言:推荐系统的魔法与现实意义

在Netflix每年节省10亿美元内容采购成本的背后,在YouTube占据用户80%观看时长的推荐算法中,推荐系统正悄然改变内容消费模式。本文将带您从零开始构建一个具备用户画像展示的电影推荐系统,通过协同过滤算法捕捉用户偏好,用Flask框架实现可视化交互。项目完成后,您将理解推荐系统的核心原理,并掌握从数据预处理到Web部署的全流程。

二、技术栈解析与项目架构

  1. 核心算法层:Surprise库实现SVD矩阵分解;
  2. 数据处理层:Pandas进行数据清洗与特征工程;
  3. 交互展示层:Flask框架构建RESTful API与前端模板;
  4. 数据源:MovieLens 100k数据集(包含943用户×1682电影的10万条评分)。

三、环境准备与数据集加载

# 安装依赖(在终端执行)
!pip install surprise pandas flask scikit-surprise# 数据加载脚本
import pandas as pd
from surprise import Dataset, Reader# 加载评分数据
ratings = pd.read_csv('ml-100k/u.data', sep='\t', names=['user_id', 'item_id', 'rating', 'timestamp'])# 定义Surprise数据格式
reader = Reader(rating_scale=(1,5))
data = Dataset.load_from_df(ratings[['user_id', 'item_id', 'rating']], reader)

四、协同过滤核心:SVD矩阵分解实现

4.1 算法原理简析

SVD(奇异值分解)将用户-物品评分矩阵分解为:

复制代码R ≈ P * Σ * Q^T

其中:

  • P:用户潜在特征矩阵
  • Q:物品潜在特征矩阵
  • Σ:奇异值对角矩阵

通过分解后的矩阵预测缺失评分,实现推荐。

4.2 Surprise实现代码

from surprise import SVD, accuracy
from surprise.model_selection import train_test_split# 划分训练集/测试集
trainset, testset = train_test_split(data, test_size=0.25)# 初始化SVD模型
model = SVD(n_factors=100,  # 潜在因子数n_epochs=20,     # 迭代次数lr_all=0.005,    # 学习率reg_all=0.02)    # 正则化系数# 训练模型
model.fit(trainset)# 评估模型
predictions = model.test(testset)
accuracy.rmse(predictions)  # 输出RMSE评估指标

五、用户画像构建与相似度计算

5.1 用户特征提取

def get_user_features(user_id):# 获取用户评分记录user_ratings = ratings[ratings['user_id'] == user_id]# 计算评分分布特征avg_rating = user_ratings['rating'].mean()rating_counts = user_ratings['rating'].value_counts().sort_index()# 获取用户潜在向量user_vector = model.pu[user_id-1]  # Surprise内部使用0-based索引return {'avg_rating': avg_rating,'rating_distribution': rating_counts.to_dict(),'latent_factors': user_vector}

5.2 用户相似度计算

from surprise.prediction_algorithms.matrix_factorization import SVDdef find_similar_users(target_user, n=5):# 获取所有用户潜在向量users = model.pu# 计算余弦相似度similarities = []for user in users:sim = cosine_similarity(users[target_user-1], user)similarities.append((sim, user))# 返回最相似的n个用户return sorted(similarities, reverse=True, key=lambda x: x[0])[:n]

六、Flask推荐服务实现

6.1 Web服务架构设计

/                   -> 主页(用户输入界面)
/recommend/<user_id>-> 推荐结果页
/user/<user_id>     -> 用户画像页

6.2 核心路由实现

from flask import Flask, render_template, requestapp = Flask(__name__)@app.route('/')
def index():return render_template('index.html')@app.route('/recommend/<int:user_id>')
def recommend(user_id):# 生成推荐(Top-N推荐)user_items = ratings[ratings['user_id'] == user_id]['item_id'].unique()all_items = ratings['item_id'].unique()predictions = []for item in all_items:if item not in user_items:pred = model.predict(str(user_id), str(item))predictions.append((item, pred.est))# 按预测评分排序recommendations = sorted(predictions, key=lambda x: x[1], reverse=True)[:10]# 获取电影元数据movies = pd.read_csv('ml-100k/u.item', sep='|', encoding='latin-1',usecols=['movie id', 'movie title', 'release date', 'genres'])# 合并推荐结果与电影信息recommended_movies = []for item_id, score in recommendations:movie = movies[movies['movie id'] == item_id].iloc[0]recommended_movies.append({'title': movie['movie title'],'year': movie['release date'],'genres': movie['genres'].split('|'),'score': round(score, 2)})return render_template('recommendations.html', movies=recommended_movies,user_id=user_id)@app.route('/user/<int:user_id>')
def user_profile(user_id):# 获取用户画像数据profile = get_user_features(user_id)# 获取相似用户similar_users = find_similar_users(user_id)return render_template('profile.html',profile=profile,similar_users=similar_users)if __name__ == '__main__':app.run(debug=True)

七、前端模板设计(Jinja2示例)

7.1 用户画像模板(profile.html)

<div class="profile-card"><h2>用户画像:User {{ user_id }}</h2><p>平均评分:{{ profile.avg_rating | round(2) }}</p><div class="rating-distribution">{% for rating, count in profile.rating_distribution.items() %}<div class="rating-bar"><span class="rating-label">★{{ rating }}</span><div class="bar-container"><div class="bar" style="width: {{ (count / total_ratings) * 100 }}%"></div></div><span class="count">{{ count }}</span></div>{% endfor %}</div><h3>相似用户:</h3><ul class="similar-users">{% for sim, user in similar_users %}<li>User {{ user + 1 }} (相似度:{{ sim | round(3) }})</li>{% endfor %}</ul>
</div>

7.2 推荐结果模板(recommendations.html)

<div class="recommendations"><h2>为您推荐(User {{ user_id }})</h2>{% for movie in movies %}<div class="movie-card"><h3>{{ movie.title }} ({{ movie.year }})</h3><p>类型:{% for genre in movie.genres %}<span class="genre">{{ genre }}</span>{% endfor %}</p><div class="score">预测评分:★{{ movie.score }}</div></div>{% endfor %}
</div>

八、系统优化方向

  1. 冷启动问题:集成内容过滤(使用电影元数据)
  2. 实时更新:添加增量训练模块
  3. 深度学习扩展:尝试Neural Collaborative Filtering
  4. 性能优化:使用Faiss实现近似最近邻搜索
  5. 可视化增强:添加评分分布热力图、用户-物品关系图

九、完整项目部署指南

  1. 下载MovieLens数据集:https://grouplens.org/datasets/movielens/

  2. 创建项目目录结构:

    movie_rec_system/
    ├── app.py
    ├── templates/
    │   ├── index.html
    │   ├── profile.html
    │   └── recommendations.html
    ├── static/
    │   ├── css/
    │   └── js/
    └── ml-100k/├── u.data├── u.item└── ...
    
  3. 启动服务:python app.py

  4. 访问:http://localhost:5000/

十、结语:推荐系统的未来展望

随着Transformer架构在自然语言处理领域的成功,推荐系统正在经历从协同过滤到序列建模的范式转变。未来工作可以将用户行为序列建模为时间序列,使用Transformer捕捉长期兴趣,同时结合多模态数据(如海报图像、剧情简介)构建更全面的用户画像。

注:实际部署时应添加异常处理、日志记录等生产级功能。

通过这个项目,您不仅掌握了推荐系统的核心技术,还完成了从算法实现到Web服务的完整工程实践。这种全栈能力正是构建智能应用的关键竞争力。

http://www.xdnf.cn/news/58087.html

相关文章:

  • 基于 DeepSeek大模型 开发AI应用的理论和实战书籍推荐,涵盖基础理论、模型架构、实战技巧及对比分析,并附表格总结
  • 基于SpringBoot的在线抽奖系统测试用例报告
  • 【KWDB创作者计划】_针对KWDB时序数据库(多副本集群环境)进行压力测试
  • Redis 键管理
  • MyBatis框架—xml映射
  • 34、Spark实现读取XLS文件
  • iOS中使用AWS上传zip文件到Minio上的oss平台上
  • nvidia physx
  • C# 封装教程
  • MCP实践第一步--磕磕碰碰搭环境
  • TensorFlow中使用Keras
  • Spring如何通过XML注册Bean
  • C++23 让 Lambda 表达式中的 () 更可选:P1102R2 提案深度解析
  • Apache RocketMQ 荣获 2024 开源创新榜单“年度开源项目
  • 【网络安全】OWASP 十大漏洞
  • 大数据组件学习之--Kafka 安装搭建
  • 机器人进阶---视觉算法(五)仿射变换和投影变换有什么区别
  • 国产AI新突破!全球首款无限时长电影生成模型SkyReels-V2开源:AI视频进入长镜头时代!
  • LangChain + 文档处理:构建智能文档问答系统 RAG 的实战指南
  • 微服务划分的思考
  • 量子计算在金融领域的应用与展望
  • Unity接入安卓SDK(3)厘清Gradle的版本
  • AI助理iOS开发:Copilot for Xcode 下载与安装全指南
  • Java 自动装箱与拆箱:基本数据类型与包装类的转换
  • Ansys electronics安装多版本simulink打开s-function冲突解决方法
  • 用Mac M4构建多架构Docker镜像指南
  • CSS 中实现 div 居中有以下几种常用方法
  • 解决Chrome浏览器访问https提示“您的连接不是私密连接”的问题
  • Android 15强制edge-to-edge全面屏体验
  • (7)NodeJS的使用与NPM包管理器