找回密码
 立即注册
首页 业界区 业界 基于Surprise和Flask构建个性化电影推荐系统:从算法到 ...

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

臧莞然 5 天前
一、引言:推荐系统的魔法与现实意义

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


  • 核心算法层:Surprise库实现SVD矩阵分解;
  • 数据处理层:Pandas进行数据清洗与特征工程;
  • 交互展示层:Flask框架构建RESTful API与前端模板;
  • 数据源:MovieLens 100k数据集(包含943用户×1682电影的10万条评分)。
三、环境准备与数据集加载
  1. # 安装依赖(在终端执行)
  2. !pip install surprise pandas flask scikit-surprise
  3. # 数据加载脚本
  4. import pandas as pd
  5. from surprise import Dataset, Reader
  6. # 加载评分数据
  7. ratings = pd.read_csv('ml-100k/u.data',
  8.                      sep='\t',
  9.                      names=['user_id', 'item_id', 'rating', 'timestamp'])
  10. # 定义Surprise数据格式
  11. reader = Reader(rating_scale=(1,5))
  12. data = Dataset.load_from_df(ratings[['user_id', 'item_id', 'rating']], reader)
复制代码
四、协同过滤核心:SVD矩阵分解实现

4.1 算法原理简析

SVD(奇异值分解)将用户-物品评分矩阵分解为:
  1. 复制代码
  2. R ≈ P * Σ * Q^T
复制代码
其中:

  • P:用户潜在特征矩阵
  • Q:物品潜在特征矩阵
  • Σ:奇异值对角矩阵
通过分解后的矩阵预测缺失评分,实现推荐。
4.2 Surprise实现代码
  1. from surprise import SVD, accuracy
  2. from surprise.model_selection import train_test_split
  3. # 划分训练集/测试集
  4. trainset, testset = train_test_split(data, test_size=0.25)
  5. # 初始化SVD模型
  6. model = SVD(n_factors=100,  # 潜在因子数
  7.            n_epochs=20,     # 迭代次数
  8.            lr_all=0.005,    # 学习率
  9.            reg_all=0.02)    # 正则化系数
  10. # 训练模型
  11. model.fit(trainset)
  12. # 评估模型
  13. predictions = model.test(testset)
  14. accuracy.rmse(predictions)  # 输出RMSE评估指标
复制代码
五、用户画像构建与相似度计算

5.1 用户特征提取
  1. def get_user_features(user_id):
  2.     # 获取用户评分记录
  3.     user_ratings = ratings[ratings['user_id'] == user_id]
  4.    
  5.     # 计算评分分布特征
  6.     avg_rating = user_ratings['rating'].mean()
  7.     rating_counts = user_ratings['rating'].value_counts().sort_index()
  8.    
  9.     # 获取用户潜在向量
  10.     user_vector = model.pu[user_id-1]  # Surprise内部使用0-based索引
  11.    
  12.     return {
  13.         'avg_rating': avg_rating,
  14.         'rating_distribution': rating_counts.to_dict(),
  15.         'latent_factors': user_vector
  16.     }
复制代码
5.2 用户相似度计算
  1. from surprise.prediction_algorithms.matrix_factorization import SVD
  2. def find_similar_users(target_user, n=5):
  3.     # 获取所有用户潜在向量
  4.     users = model.pu
  5.    
  6.     # 计算余弦相似度
  7.     similarities = []
  8.     for user in users:
  9.         sim = cosine_similarity(users[target_user-1], user)
  10.         similarities.append((sim, user))
  11.    
  12.     # 返回最相似的n个用户
  13.     return sorted(similarities, reverse=True, key=lambda x: x[0])[:n]
复制代码
六、Flask推荐服务实现

6.1 Web服务架构设计
  1. /                   -> 主页(用户输入界面)
  2. /recommend/<user_id>-> 推荐结果页
  3. /user/<user_id>     -> 用户画像页
复制代码
6.2 核心路由实现
  1. from flask import Flask, render_template, request
  2. app = Flask(__name__)
  3. @app.route('/')
  4. def index():
  5.     return render_template('index.html')
  6. @app.route('/recommend/<int:user_id>')
  7. def recommend(user_id):
  8.     # 生成推荐(Top-N推荐)
  9.     user_items = ratings[ratings['user_id'] == user_id]['item_id'].unique()
  10.     all_items = ratings['item_id'].unique()
  11.    
  12.     predictions = []
  13.     for item in all_items:
  14.         if item not in user_items:
  15.             pred = model.predict(str(user_id), str(item))
  16.             predictions.append((item, pred.est))
  17.    
  18.     # 按预测评分排序
  19.     recommendations = sorted(predictions, key=lambda x: x[1], reverse=True)[:10]
  20.    
  21.     # 获取电影元数据
  22.     movies = pd.read_csv('ml-100k/u.item',
  23.                         sep='|',
  24.                         encoding='latin-1',
  25.                         usecols=['movie id', 'movie title', 'release date', 'genres'])
  26.    
  27.     # 合并推荐结果与电影信息
  28.     recommended_movies = []
  29.     for item_id, score in recommendations:
  30.         movie = movies[movies['movie id'] == item_id].iloc[0]
  31.         recommended_movies.append({
  32.             'title': movie['movie title'],
  33.             'year': movie['release date'],
  34.             'genres': movie['genres'].split('|'),
  35.             'score': round(score, 2)
  36.         })
  37.    
  38.     return render_template('recommendations.html',
  39.                          movies=recommended_movies,
  40.                          user_id=user_id)
  41. @app.route('/user/<int:user_id>')
  42. def user_profile(user_id):
  43.     # 获取用户画像数据
  44.     profile = get_user_features(user_id)
  45.    
  46.     # 获取相似用户
  47.     similar_users = find_similar_users(user_id)
  48.    
  49.     return render_template('profile.html',
  50.                          profile=profile,
  51.                          similar_users=similar_users)
  52. if __name__ == '__main__':
  53.     app.run(debug=True)
复制代码
七、前端模板设计(Jinja2示例)

7.1 用户画像模板(profile.html)
  1.   <h2>用户画像:User {{ user_id }}</h2>
  2.   <p>平均评分:{{ profile.avg_rating | round(2) }}</p>
  3.   
  4.     {% for rating, count in profile.rating_distribution.items() %}
  5.       
  6.         ★{{ rating }}
  7.         
  8.          
  9.         
  10.         {{ count }}
  11.       
  12.     {% endfor %}
  13.   
  14.   
  15.   <h3>相似用户:</h3>
  16.   <ul >
  17.     {% for sim, user in similar_users %}
  18.       <li>User {{ user + 1 }} (相似度:{{ sim | round(3) }})</li>
  19.     {% endfor %}
  20.   </ul>
复制代码
7.2 推荐结果模板(recommendations.html)
  1.   <h2>为您推荐(User {{ user_id }})</h2>
  2.   {% for movie in movies %}
  3.    
  4.       <h3>{{ movie.title }} ({{ movie.year }})</h3>
  5.       <p>类型:{% for genre in movie.genres %}{{ genre }}{% endfor %}</p>
  6.       预测评分:★{{ movie.score }}
  7.    
  8.   {% endfor %}
复制代码
八、系统优化方向


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


  • 下载MovieLens数据集:https://grouplens.org/datasets/movielens/
  • 创建项目目录结构:
    1. movie_rec_system/
    2. ├── app.py
    3. ├── templates/
    4. │   ├── index.html
    5. │   ├── profile.html
    6. │   └── recommendations.html
    7. ├── static/
    8. │   ├── css/
    9. │   └── js/
    10. └── ml-100k/
    11.     ├── u.data
    12.     ├── u.item
    13.     └── ...
    复制代码
  • 启动服务:python app.py
  • 访问:http://localhost:5000/
十、结语:推荐系统的未来展望

随着Transformer架构在自然语言处理领域的成功,推荐系统正在经历从协同过滤到序列建模的范式转变。未来工作可以将用户行为序列建模为时间序列,使用Transformer捕捉长期兴趣,同时结合多模态数据(如海报图像、剧情简介)构建更全面的用户画像。
注:实际部署时应添加异常处理、日志记录等生产级功能。
通过这个项目,您不仅掌握了推荐系统的核心技术,还完成了从算法实现到Web服务的完整工程实践。这种全栈能力正是构建智能应用的关键竞争力。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册