基于Surprise和Flask构建个性化电影推荐系统:从算法到全栈实现
一、引言:推荐系统的魔法与现实意义
在Netflix每年节省10亿美元内容采购成本的背后,在YouTube占据用户80%观看时长的推荐算法中,推荐系统正悄然改变内容消费模式。本文将带您从零开始构建一个具备用户画像展示的电影推荐系统,通过协同过滤算法捕捉用户偏好,用Flask框架实现可视化交互。项目完成后,您将理解推荐系统的核心原理,并掌握从数据预处理到Web部署的全流程。
二、技术栈解析与项目架构
- 核心算法层:Surprise库实现SVD矩阵分解;
- 数据处理层:Pandas进行数据清洗与特征工程;
- 交互展示层:Flask框架构建RESTful API与前端模板;
- 数据源: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 SVD
def 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, request
app = 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>
八、系统优化方向
- 冷启动问题:集成内容过滤(使用电影元数据)
- 实时更新:添加增量训练模块
- 深度学习扩展:尝试Neural Collaborative Filtering
- 性能优化:使用Faiss实现近似最近邻搜索
- 可视化增强:添加评分分布热力图、用户-物品关系图
九、完整项目部署指南
下载MovieLens数据集:https://grouplens.org/datasets/movielens/
创建项目目录结构:
movie_rec_system/
├── app.py
├── templates/
│ ├── index.html
│ ├── profile.html
│ └── recommendations.html
├── static/
│ ├── css/
│ └── js/
└── ml-100k/
├── u.data
├── u.item
└── ...
启动服务:
python app.py
十、结语:推荐系统的未来展望
随着Transformer架构在自然语言处理领域的成功,推荐系统正在经历从协同过滤到序列建模的范式转变。未来工作可以将用户行为序列建模为时间序列,使用Transformer捕捉长期兴趣,同时结合多模态数据(如海报图像、剧情简介)构建更全面的用户画像。
注:实际部署时应添加异常处理、日志记录等生产级功能。
通过这个项目,您不仅掌握了推荐系统的核心技术,还完成了从算法实现到Web服务的完整工程实践。这种全栈能力正是构建智能应用的关键竞争力。
基于Surprise和Flask构建个性化电影推荐系统:从算法到全栈实现的更多相关文章
- 基于Spark Mllib,SparkSQL的电影推荐系统
本文测试的Spark版本是1.3.1 本文将在Spark集群上搭建一个简单的小型的电影推荐系统,以为之后的完整项目做铺垫和知识积累 整个系统的工作流程描述如下: 1.某电影网站拥有可观的电影资源和用户 ...
- Python全栈工程师之从网页搭建入门到Flask全栈项目实战(1) - ES6标准入门和Flex布局
1.简述 1.什么是ES6?ES6, 全称 ECMAScript 6.0,是 JavaScript 的下一个版本标准,2015年6月份发版.ES6的主要目的是为了解决 ES5 的先天不足. 2.了解E ...
- 转】用Hadoop构建电影推荐系统
原博文出自于: http://blog.fens.me/hadoop-mapreduce-recommend/ 感谢! 用Hadoop构建电影推荐系统 Hadoop家族系列文章,主要介绍Hadoop家 ...
- Python基于机器学习方法实现的电影推荐系统
推荐算法在互联网行业的应用非常广泛,今日头条.美团点评等都有个性化推荐,推荐算法抽象来讲,是一种对于内容满意度的拟合函数,涉及到用户特征和内容特征,作为模型训练所需维度的两大来源,而点击率,页面停留时 ...
- 基于Mahout的电影推荐系统
基于Mahout的电影推荐系统 1.Mahout 简介 Apache Mahout 是 Apache Software Foundation(ASF) 旗下的一个开源项目,提供一些可扩展的机器学习领域 ...
- 基于pytorch的电影推荐系统
本文介绍一个基于pytorch的电影推荐系统. 代码移植自https://github.com/chengstone/movie_recommender. 原作者用了tf1.0实现了这个基于movie ...
- 基于Spark的电影推荐系统(电影网站)
第一部分-电影网站: 软件架构: SpringBoot+Mybatis+JSP 项目描述:主要实现电影网站的展现 和 用户的所有动作的地方 技术选型: 技术 名称 官网 Spring Boot 容器 ...
- 基于Spark的电影推荐系统(推荐系统~2)
第四部分-推荐系统-数据ETL 本模块完成数据清洗,并将清洗后的数据load到Hive数据表里面去 前置准备: spark +hive vim $SPARK_HOME/conf/hive-site.x ...
- 基于Spark的电影推荐系统(推荐系统~4)
第四部分-推荐系统-模型训练 本模块基于第3节 数据加工得到的训练集和测试集数据 做模型训练,最后得到一系列的模型,进而做 预测. 训练多个模型,取其中最好,即取RMSE(均方根误差)值最小的模型 说 ...
- 基于Spark的电影推荐系统(推荐系统~7)
基于Spark的电影推荐系统(推荐系统~7) 22/100 发布文章 liuge36 第四部分-推荐系统-实时推荐 本模块基于第4节得到的模型,开始为用户做实时推荐,推荐用户最有可能喜爱的5部电影. ...
随机推荐
- 0424-字节输出流FileOutputStream
package A10_IOStream; import java.io.FileOutputStream; import java.io.IOException; import java.util. ...
- 独立开发经验谈:如何通过 Docker 让潜在客户快速体验你的系统
我在业余时间开发了一款自己的独立产品:升讯威在线客服与营销系统.陆陆续续开发了几年,从一开始的偶有用户尝试,到如今线上环境和私有化部署均有了越来越多的稳定用户,在这个过程中,我也积累了不少如何开发运营 ...
- AllPairs工具助力正交表测试用例设计
AllPairs工具助力正交表测试用例设计 正交表法是一种高效的测试方法,特别适用于软件测试中需要处理多个控件及其多种取值组合的情况.以下是对正交表法的详细解释: 一.正交表法概述 正交表法是一种利用 ...
- 更换Linux系统镜像源
更换Linux系统镜像源 切换镜像源通常是为了提高软件包下载的速度和稳定性.以下是CentOS 7切换镜像源的一般步骤: 一.安装wget(如果尚未安装) 首先,需要确保系统中安装了wget工具,因为 ...
- 大数据HDFS集群相关概念
一.Zookeeper服务 端口 描述 配置路径 2181 主要使用端口,对cline端提供服务.连接方式jdbc:hive2://ip:2181 conf/zoo.cfg中clientPort 21 ...
- TIPTOP应付账款流程学习
应付账款流程与应收账款流程是财务管理的开端,也是财务工作的主要流程. 企业的应付账款有很多种,如原材料的应付账款.电力能源的应付账款.房租的应付账款等,大头是原材料的应付账款,以下详细说明. 在讲解之 ...
- Luogu P9055 [集训队互测 2021] 数列重排 题解 [ 紫 ] [ 构造 ] [ 数学 ]
数列重排:差点就场切的神仙构造,最后一步想假了,导致我模拟赛荣获 25+5+0 的好成绩! 这题部分分很有启发性,跟着一步一步打基本能想到正解的构造,但也有可能想偏部分分的意思,想假策略. 构造 先看 ...
- C#进行word模板占位符替换的几种工具
word模板中,包含一些需要替换的项,比如{{姓名}} {{年龄}}或者$姓名$ $年龄$,从数据库获取信息后,对模板进行替换操作生成新的word文档. 简单对以下四种工具做了一下测试: 1.NPOI ...
- Flink学习(一) 行情介绍
想进大厂,必须掌握 Flink 技术!!! 随着大数据时代的发展.海量数据的实时处理和多样业务的数据计算需求激增,传统的批处理方式和早期的流式处理框架也有自身的局限性,难以在延迟性.吞吐量.容错能力, ...
- 全程不用写代码,我用AI程序员写了一个飞机大战
前言 还在为写代码薅头发吗?还在为给出的需求无处下手而发愁吗?今天宏哥分享一款开发工具的插件,让你以后的编程变得简单起来. 作为一个游戏编程小白,能完成自己工作就不错了,还能玩别的,这在以前想都不敢想 ...