首页
人工智能
网络安全
手机
搜索
登录
搜索
golden81
累计撰写
154
篇文章
累计收到
0
条评论
首页
栏目
首页
人工智能
网络安全
手机
包含标签 【推荐系统】 的文章
2025-4-27
基于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 访问:http://localhost:5000/ 十、结语:推荐系统的未来展望 随着Transformer架构在自然语言处理领域的成功,推荐系统正在经历从协同过滤到序列建模的范式转变。未来工作可以将用户行为序列建模为时间序列,使用Transformer捕捉长期兴趣,同时结合多模态数据(如海报图像、剧情简介)构建更全面的用户画像。 注:实际部署时应添加异常处理、日志记录等生产级功能。 通过这个项目,您不仅掌握了推荐系统的核心技术,还完成了从算法实现到Web服务的完整工程实践。这种全栈能力正是构建智能应用的关键竞争力。
2025年-4月-27日
5 阅读
0 评论
人工智能