安庆市网站建设_网站建设公司_动画效果_seo优化
2026/1/19 14:34:24 网站建设 项目流程

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聊天机器人 (上)(待更新)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询