news 2026/4/23 17:05:19

Day 90:【99天精通Python】项目篇(二) - 电影推荐系统 (下) - 算法实现与 API 开发

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Day 90:【99天精通Python】项目篇(二) - 电影推荐系统 (下) - 算法实现与 API 开发

Day 90:【99天精通Python】项目篇(二) - 电影推荐系统 (下) - 算法实现与 API 开发

前言

欢迎来到第90天!

在昨天,我们已经完成了数据探索和预处理,并计算出了用户之间的相似度矩阵。今天,我们要完成这个项目的最后两步:

  1. 编写推荐算法:根据相似度,为指定用户生成推荐列表。
  2. 封装为 API:使用 Flask 将推荐功能封装成一个 API 接口。

这将是我们 99 天旅程中的最后一个大型实战项目,它综合了数据分析、机器学习和 Web 开发的知识。

本节内容:

  • 实现 User-Based CF 推荐函数
  • 封装推荐逻辑为类
  • 搭建 Flask API 接口
  • 测试推荐效果
  • 项目总结与可扩展方向

一、推荐算法实现

我们的目标是:get_recommendations(user_id, num_recommendations=10)

算法步骤回顾:

  1. 找出与user_id最相似的 K 个邻居。
  2. 找出这些邻居"高分评价过"但user_id"没看过"的电影。
  3. 对这些电影进行加权评分,排序后返回 Top N。
importpandasaspdfromsklearn.metrics.pairwiseimportcosine_similarity# --- 以下代码为 Day 89 的回顾,假设已运行 ---movies=pd.read_csv("./ml-latest-small/movies.csv")ratings=pd.read_csv("./ml-latest-small/ratings.csv")df=pd.merge(ratings,movies,on="movieId")movie_matrix=df.pivot_table(index='userId',columns='title',values='rating')user_item_matrix=movie_matrix.fillna(0)user_similarity=cosine_similarity(user_item_matrix)user_sim_df=pd.DataFrame(user_similarity,index=user_item_matrix.index,columns=user_item_matrix.index)# --- 核心推荐函数 ---defget_recommendations(user_id,num_recommendations=10):# 1. 找到该用户的相似度向量,并排除自己similar_users=user_sim_df[user_id].drop(user_id).sort_values(ascending=False)# 2. 筛选 Top K 邻居 (这里我们简化,取所有相似度>0的用户)neighbors=similar_users[similar_users>0]ifneighbors.empty:returnpd.Series(dtype='float64')# 没有相似用户# 3. 找出用户看过的电影,用于过滤user_watched_movies=user_item_matrix.loc[user_id]user_watched_movies=user_watched_movies[user_watched_movies>0].index.values# 4. 计算推荐分数recommend_scores=pd.Series(dtype='float64')forneighbor_id,similarityinneighbors.items():# 获取邻居看过的电影neighbor_movies=user_item_matrix.loc[neighbor_id]formovie_title,ratinginneighbor_movies[neighbor_movies>4].items():# 只考虑高分电影ifmovie_titlenotinuser_watched_movies:# 累加分数 (相似度 * 邻居评分)recommend_scores.loc[movie_title]=recommend_scores.get(movie_title,0)+similarity*rating# 5. 返回 Top Nreturnrecommend_scores.sort_values(ascending=False).head(num_recommendations)# 测试recs=get_recommendations(1)print(recs)

二、代码封装

为了方便在 Flask 中调用,我们把整个逻辑封装成一个类。

# recommend_engine.pyimportpandasaspdfromsklearn.metrics.pairwiseimportcosine_similarityclassRecommendationEngine:def__init__(self,ratings_path,movies_path):self.movies=pd.read_csv(movies_path)self.ratings=pd.read_csv(ratings_path)self._prepare_data()def_prepare_data(self):print("正在准备数据...")df=pd.merge(self.ratings,self.movies,on="movieId")movie_matrix=df.pivot_table(index='userId',columns='title',values='rating')self.user_item_matrix=movie_matrix.fillna(0)print("正在计算相似度...")user_similarity=cosine_similarity(self.user_item_matrix)self.user_sim_df=pd.DataFrame(user_similarity,index=self.user_item_matrix.index,columns=self.user_item_matrix.index)print("引擎准备就绪!")defget_recommendations(self,user_id,n=10):# ... (将上面的函数逻辑搬到这里) ...# 注意修改变量名为 self.xxxsimilar_users=self.user_sim_df[user_id].drop(user_id).sort_values(ascending=False)# ... (后续逻辑同上)# 为了方便 API 返回,我们把结果转成 list of dictrecs_df=recs.reset_index()recs_df.columns=['title','score']returnrecs_df.to_dict('records')

三、Flask API 接口

现在,我们创建一个简单的 Flask 应用来暴露这个推荐服务。

# app.pyfromflaskimportFlask,jsonify,requestfromrecommend_engineimportRecommendationEngine# 假设上面的类已保存app=Flask(__name__)# --- 全局加载推荐引擎 (只在启动时加载一次) ---print("正在初始化推荐引擎,请稍候...")engine=RecommendationEngine("./ml-latest-small/ratings.csv","./ml-latest-small/movies.csv")@app.route("/recommend",methods=["GET"])defrecommend():# 从 URL 参数获取 user_iduser_id=request.args.get('user_id',type=int)ifnotuser_id:returnjsonify({"error":"缺少 user_id 参数"}),400try:recommendations=engine.get_recommendations(user_id)returnjsonify(recommendations)exceptKeyError:returnjsonify({"error":f"用户{user_id}不存在"}),404if__name__=="__main__":# host='0.0.0.0' 让局域网内其他设备也能访问app.run(debug=True,host='0.0.0.0',port=5001)

四、测试 API

  1. 启动 Flask 应用:python app.py
  2. 等待引擎初始化完成。
  3. 打开浏览器或 Postman,访问http://127.0.0.1:5001/recommend?user_id=1

你应该能看到类似这样的 JSON 返回:

[{"title":"Star Wars: Episode IV - A New Hope (1977)","score":10.5},{"title":"Fight Club (1999)","score":8.2},...]

五、项目总结与可扩展方向

至此,一个最基础的协同过滤推荐系统就完成了。虽然它很简单,但麻雀虽小,五脏俱全。

5.1 缺点与优化

  • 性能问题:每次推荐都要遍历大量用户,计算量巨大。生产环境中通常会离线计算好结果存入 Redis。
  • 冷启动问题:新用户没有评分,无法推荐。需要结合"热门推荐"等策略。
  • 稀疏性问题:用户-物品矩阵非常稀疏,影响相似度计算。可以使用矩阵分解等更高级的算法(如 SVD)。

5.2 可扩展方向

  • Item-Based CF:计算物品之间的相似度(买了"Python入门"的人还买了什么?),适合物品数量远小于用户数的场景。
  • 模型驱动:使用surprise库或深度学习(如LightGCN)来构建更精准的模型。
  • 前端集成:做一个漂亮的前端页面,调用 API 展示推荐结果。

六、小结

恭喜你,完成了这个贯穿数据分析、机器学习和 Web 开发的综合项目!

我们回顾一下这个项目的技术栈:

  • 数据处理:Pandas
  • 机器学习:Scikit-Learn (Cosine Similarity)
  • Web 服务:Flask

你已经证明了你有能力将多个领域的知识整合起来,解决一个复杂的实际问题。


七、课后作业

  1. Item-CF 实现:尝试实现基于物品的协同过滤,并对比与 User-CF 推荐结果的异同。
  2. API 健壮性:给 API 增加缓存(使用 Redis),对同一个用户 ID 的请求,1 小时内直接返回缓存结果。
  3. UI 界面:使用 Streamlit 或 Gradio(比 Flask 更简单的 UI 库),给你的推荐系统做一个简单的交互界面。

下节预告

Day 91:项目篇(三) - AI 聊天机器人 (上) - 结合 LangChain 与 Web- 推荐系统告一段落。明天,我们将启动最后一个终极项目:做一个带记忆、能联网、能读文档的 Web 版 AI 聊天机器人!


系列导航

  • 上一篇:Day 89 - 电影推荐系统 (上)
  • 下一篇:Day 91 - AI聊天机器人 (上)(待更新)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 11:12:13

Supertonic实战案例:教育领域语音合成应用

Supertonic实战案例:教育领域语音合成应用 1. 引言:设备端TTS在教育场景中的价值 随着在线教育和个性化学习的快速发展,文本转语音(Text-to-Speech, TTS)技术正成为提升教学体验的重要工具。从电子课本朗读、语言学习…

作者头像 李华
网站建设 2026/3/31 20:30:26

cy5.5-Galactooligosaccharide,cy5.5-低聚半乳糖,合成与反应原理

cy5.5-Galactooligosaccharide,cy5.5-低聚半乳糖,合成与反应原理Cy5.5-Galactooligosaccharide(Cy5.5-低聚半乳糖)是由Cy5.5染料与低聚半乳糖分子偶联形成的复合物。低聚半乳糖(Galactooligosaccharide,简称…

作者头像 李华
网站建设 2026/4/23 11:14:20

I2S协议数据帧格式在音频设备中通俗解释

拆解I2S协议:音频设备中如何精准传递“声音的0和1”你有没有想过,当你用蓝牙耳机听一首歌时,那串从手机传到耳机里的数字信号,到底是怎么被还原成清晰人声与细腻乐器的?在模拟信号早已退居二线的今天,数字音…

作者头像 李华
网站建设 2026/4/22 19:44:05

social-analyzer 怎么部署?用服务器搭建社交资料检索分析工具

如果你做过品牌监测、舆情分析、账号排查或 OSINT 相关工作,一定遇到过这些情况: 🔍 同一个用户名散落在多个平台,手动查太慢 😵 平台多、规则不一,检索流程非常碎片化 🧠 想做“是否存在/可信度/关联性”的基础分析,却没有统一工具 📊 需要把结果整理成结构化数…

作者头像 李华
网站建设 2026/4/23 12:35:50

Satty 怎么用?用服务器搭建 Linux 截图标注环境的实战教程

如果你平时主要在 Linux 环境下工作,无论是运维、开发,还是写文档、做教程,大概率都遇到过这些情况: 📸 需要截图说明问题,但服务器上没有顺手的标注工具 😵 截完图还得拷到本地,再用别的软件画框、打字 🧠 给同事/客户解释问题,截图不清晰,来回沟通成本很高 �…

作者头像 李华