ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

基于Python的电影推荐系统源码解析:从环境配置到协同过滤实战

基于Python的电影推荐系统源码解析:从环境配置到协同过滤实战 简介本资源是一套基于Python开发的电影推荐系统源码面向计算机专业初学者与Web开发入门者解决多平台电影数据整合、个性化推荐与用户交互管理等典型应用场景问题。压缩包共57个文件涵盖8个核心Python脚本如爬虫模块、数据库操作、主服务逻辑、8个HTML前端页面、11个CSS样式文件及7个PNG/JPG图像资源完整呈现前后端分离结构静态资源与模板目录清晰便于理解Flask框架下的Web应用组织方式。资源包大小为2.92MB轻量易部署适合课程设计、毕业设计或自学实践。代码包含多源爬虫腾讯、爱奇艺、搜狐、IMDb等、电影信息展示、观看状态标记、收藏功能及响应式前端界面提供可直接运行的完整闭环方案助读者掌握数据采集、Web开发与推荐逻辑集成的关键技能。 拿到这个“(源码)基于Python的电影推荐系统.zip”的时候大多数人的第一反应是解压、找README、跑起来。但我见过的真实情况是真正卡住你的往往不是推荐算法本身而是从解压到跑通的这条链路上布满了小坑。我帮人看过几十个类似的推荐系统项目包最常见的结果是——依赖装不上、数据路径不对、相似度矩阵算出来全是NaN最后项目就躺在硬盘里吃灰。这篇文章我会按照实际动手的顺序来拆解这个电影推荐系统源码包从解压方式、环境准备到数据处理、协同过滤的核心代码逻辑再到离线评测和打包分发规范。如果你是刚接触推荐系统的Python学习者或者想把这个项目改造成自己的课程设计、毕设项目这篇文章可以直接帮你省掉好几天的瞎折腾时间。我尽量把每一步“为什么这么做”也讲清楚而不是只丢给你一堆能跑的代码。1. 项目解压到跑起来的完整链路先把经典报错消干净1.1 解压环节file is not a zip file 的三种真实成因很多人第一步就栽在解压上。“(源码)基于Python的电影推荐系统.zip”这个名字很直白但你从网上下载的zip文件未必真的就是一个完好的zip。我遇到的报错大致有这么几类各有各的成因第一类是最常见的下载过程中文件损坏。尤其是一些网盘或镜像站中间断点续传没处理好zip的结尾少了关键数据块解压时就会提示file is not a zip file或者invalid zip archive: could not find eocd。EOCD是zip格式的结尾记录解压工具靠它定位文件目录一旦缺失或损坏整个压缩包就废了。解决办法是重新下载最好换个下载工具或者换条网络别在同一路径上反复试。第二类是文件被改名本质上根本不是zip。有些站点会把源码包用其他格式封装或者下载下来的是一个HTML跳转页面只是后缀写成了.zip。这种你直接在终端里用file命令看一眼就能识别出来file 电影推荐系统.zip如果输出显示HTML document或者gzip compressed data那就别硬解了先搞清楚你下载的到底是啥。第三类是压缩包本身没问题但解压工具或操作系统中文编码处理不当。Windows上尤其容易出现文件名乱码或解压中断。我的建议是尽量用7-Zip或者命令行工具少用系统自带的“全部提取”功能因为自带工具对特殊字符和长路径的容忍度比较低。Linux环境下一行命令就能解决大部分解压需求unzip 电影推荐系统.zip -d movie_recommend解压之后先别急着跑先看一下目录结构是否完整有没有README.md、requirements.txt这些关键文件。没有README的项目包通常意味着你需要花更多时间去猜作者的思路。1.2 Python虚拟环境与依赖清单这个项目是基于Python的那么Python版本选哪个就很关键。我见过太多人用系统自带的Python 3.6去跑一个需要Python 3.8的项目然后被各种语法错误和依赖冲突折磨。推荐系统项目常用的pandas、numpy、scikit-learn这些库新版本的API和老版本差异很大选错版本等于给自己挖坑。建议直接用虚拟环境隔离不要图省事装到全局。这一步非常关键因为推荐系统依赖的numpy、scipy版本如果和系统其他项目冲突你会花大量时间在“修好一个依赖又弄坏另一个”的循环里。python -m venv venv source venv/bin/activate # Windows下是 venv\Scripts\activate激活虚拟环境之后先升级pip再安装依赖pip install --upgrade pip pip install -r requirements.txt如果项目没有提供requirements.txt你需要根据代码里的import语句手动安装。一个基础版的电影推荐系统通常需要这些pandas数据处理和评分矩阵构建numpy数值计算scikit-learn相似度计算、train_test_splitscipy稀疏矩阵操作matplotlib可选用来画评测结果的图表有一个小技巧先单独安装numpy和pandas再装scikit-learn。因为scikit-learn在安装过程中会检查numpy的版本如果两者版本跨度太大可能出现二进制不兼容的问题。实测下来Python 3.9 numpy 1.23.x pandas 1.5.x scikit-learn 1.2.x这个组合跑推荐系统非常稳。1.3 验证安装三步确认环境没有“假成功”依赖装完不代表万事大吉。我习惯用三步验证法确保环境是真的能用而不是“看起来能用”。第一步导入所有核心库确认没有ImportErrorimport pandas as pd import numpy as np from sklearn.metrics.pairwise import cosine_similarity print(pd.__version__, np.__version__)第二步确认数据文件路径正确。很多源码包里会写死相对路径比如data/ml-latest-small/ratings.csv但你的解压目录层级和作者的不一定一样。这一步错的话代码会在pd.read_csv那行直接报FileNotFoundError。先手动确认一下你的当前工作目录和实际文件路径是否对得上。第三步跑一个最小数据集验证。如果项目自带示例数据直接用示例数据跑一遍主流程如果没有可以自己构造一个5行的小评分表测试相似度计算和推荐函数是否正常。这一步能帮你把“环境问题”和“算法问题”分开排查。2. 数据从哪来MovieLens数据集的取舍与预处理细节2.1 为什么选MovieLens而不自己爬电影推荐系统项目里绝大多数都基于GroupLens提供的MovieLens数据集。原因很简单干净、格式统一、有权威的评分数据。如果你打算自己写爬虫去抓电影评分数据那工作量绝对超乎想象——你不仅要处理网站的反爬机制还要面对数据清洗的巨坑同一个电影在不同网站上的名称不一致、用户ID体系混乱、时间戳格式千奇百怪。而MovieLens把这些全部做完了你拿到手就是规整的CSV文件。这个项目如果用的是ml-latest-small版本通常包含文件内容记录数约ratings.csvuserId, movieId, rating, timestamp100836movies.csvmovieId, title, genres9742tags.csvuserId, movieId, tag, timestamp3683100836条评分记录不算大pandas完全能轻松处理不需要上Spark之类的分布式框架。如果你的机器配置不错也可以换成完整版MovieLens 25M但算法逻辑不用改只是计算时间会变长。我不建议一上来就上大数据集。推荐系统项目的核心在于理解算法逻辑而不是比谁处理的数据量大。先用小数据集把流程跑通再逐步扩展这是最稳妥的学习路径。2.2 评分矩阵构建与数据清洗数据加载的方式没有太多玄学就是标准的pandas读取import pandas as pd ratings pd.read_csv(data/ml-latest-small/ratings.csv) movies pd.read_csv(data/ml-latest-small/movies.csv)但真正需要关注的是后续的清洗步骤。原始评分数据里有几类问题必须处理第一重复评分。同一个用户对同一部电影理论上只应该有一条评分记录但数据源偶尔会有重复。处理方式是按照userId和movieId做去重ratings ratings.drop_duplicates(subset[userId, movieId])第二评分时间跨度问题。有些推荐系统实现会把时间信息作为特征但基础版的协同过滤不需要时间戳直接用就行。如果你的版本想做时间衰减加权那才需要用到timestamp字段。第三数据稀疏度。MovieLens的评分矩阵非常稀疏100836条评分分布在9742部电影和610个用户上意味着大部分用户只看过其中很小一部分电影。这种稀疏矩阵在做相似度计算时如果不做处理很容易出现“分母为零”的情况。常见的处理方式是只保留评分次数达到一定阈值的用户和电影user_rating_count ratings.groupby(userId).size() keep_users user_rating_count[user_rating_count 5].index ratings ratings[ratings[userId].isin(keep_users)]这一步能显著减少相似度矩阵的稀疏性提升推荐效果。接下来构建用户-物品评分矩阵这是协同过滤的核心数据结构rating_matrix ratings.pivot_table( indexuserId, columnsmovieId, valuesrating, fill_value0 )注意这里我用了fill_value0把缺失值填为0。这种处理方式在计算余弦相似度时是合理的但要注意0在余弦相似度中被视为“无评分”而不是“评了0分”两者语义完全不同。MovieLens的评分范围是0.5到5.0不存在真正的0分所以用0填充行向量中的缺失位是安全的。2.3 冷启动数据如何做兜底冷启动是推荐系统绕不开的话题。新用户没有任何评分历史协同过滤算法完全无能为力——你没法找相似用户也没法基于历史行为推荐。项目里通常会用一种简单粗暴的方案兜底热度推荐。统计所有电影的平均评分和评分人数计算一个加权得分把得分最高的N部电影推给新用户。movie_stats ratings.groupby(movieId)[rating].agg([mean, count]) movie_stats[score] movie_stats[mean] * movie_stats[count] / (movie_stats[count] 5) hot_movies movie_stats.sort_values(score, ascendingFalse).head(20)这个公式本质上是贝叶斯平均的思想分母加5是一个平滑项避免只有1个人打了5分的冷门电影排到最前面。我建议在阅读源码时重点留意这个兜底逻辑在哪个模块实现——它通常独立于协同过滤主流程在接口层做判断如果用户评分历史为空走热度推荐否则走协同过滤。3. 推荐算法核心拆解协同过滤的实现逻辑与参数权衡3.1 UserCF找口味相似的人把他们的高分片单搬过来基于用户的协同过滤UserCF核心思想一句话就能说清找到和你口味最像的一群人把这些人评分高而你没看过的电影推荐给你。第一步是计算用户之间的相似度。方法有很多最常用的是余弦相似度。假设用户A的评分向量是[5, 0, 3, 4]用户B的评分向量是[4, 0, 3, 5]两者之间的余弦相似度可以这样理解把每个用户的评分向量看作高维空间中的一个点计算两个点之间的夹角余弦值值越接近1说明方向越一致即口味越相似。代码实现如下from sklearn.metrics.pairwise import cosine_similarity user_similarity cosine_similarity(rating_matrix) user_sim_df pd.DataFrame( user_similarity, indexrating_matrix.index, columnsrating_matrix.index )这个矩阵的规模是用户数乘以用户数。对于ml-latest-small的610个用户完全没问题但如果换成MovieLens 25M的上百万用户这个稠密矩阵会直接撑爆内存。所以工业实现多用稀疏矩阵近似最近邻搜索但那是另一个话题了项目阶段不必考虑。第二步是预测用户对未看过的电影的评分。常用公式是加权平均def predict_rating(user_id, movie_id, top_n10): if movie_id not in rating_matrix.columns: return 0 # 找到与目标用户最相似的top_n个用户 similar_users user_sim_df[user_id].sort_values(ascendingFalse).drop(user_id).head(top_n) # 过滤掉没看过该电影的用户 valid_users similar_users[rating_matrix[movie_id][similar_users.index] 0] if len(valid_users) 0: return 0 numerator sum(valid_users * rating_matrix[movie_id][valid_users.index]) denominator sum(valid_users) # 除以相似度之和得到加权平均 return numerator / denominator这里有一个细节权重是相似度分子是相似度乘以评分本质上是“相似用户的评分越高对预测结果的贡献越大”。最终预测值逼近3~4分是很正常的因为大家都在3~4分这个区间内打转。3.2 ItemCF从“我看过的片”出发找最像的下一部基于物品的协同过滤ItemCF逻辑刚好反过来先计算电影之间的相似度再根据用户看过的电影推荐那些和“已看过的高分电影”最相似的未看过的电影。电影之间的相似度怎么算同样是余弦相似度只不过这次把评分矩阵转置一下——把每部电影看作一个向量向量维度是所有用户对应位置的值是某个用户给这部电影的评分。item_similarity cosine_similarity(rating_matrix.T) item_sim_df pd.DataFrame( item_similarity, indexrating_matrix.columns, columnsrating_matrix.columns )预测用户对某部电影的评分时只看用户已经评过分的电影中哪些和这部电影相似def predict_item_rating(user_id, movie_id, top_n10): if movie_id not in item_sim_df.columns: return 0 # 找出该用户评过分的电影 user_rated rating_matrix.loc[user_id] user_rated user_rated[user_rated 0] if len(user_rated) 0: return 0 similar_items item_sim_df[movie_id][user_rated.index].sort_values(ascendingFalse).head(top_n) numerator sum(similar_items * user_rated[similar_items.index]) denominator sum(similar_items) return numerator / denominator这里的关键逻辑是如果用户给《黑客帝国》打了5分而《盗梦空间》和《黑客帝国》的相似度高达0.8那么系统对《盗梦空间》的预测评分就会比较高。3.3 二者对比与混合策略很多初学者会纠结该用UserCF还是ItemCF。我的建议是别纠结两个都实现然后做对比。它们的适用场景有明显差异维度UserCFItemCF适用场景用户少、物品多且用户兴趣变化快物品数量相对稳定用户兴趣变化较慢实时性用户行为实时更新推荐结果变化快物品相似度离线计算推荐结果相对稳定冷启动新用户无法推荐新物品可推荐新物品无法推荐新用户可根据历史偏好推荐解释性解释为“和你兴趣相似的用户也看了”解释为“因为你喜欢XX所以推荐YY”计算复杂度用户数平方物品数平方电影场景下ItemCF通常表现更好因为电影的数量相对稳定用户对电影的偏好短期不太会变。而在资讯、新闻这类物品更新极快的场景UserCF更合适。实际项目中我发现把两个结果做加权融合效果更好final_score 0.4 * usercf_score 0.6 * itemcf_score权重的选取可以根据离线评测结果来调不是拍脑袋定的。3.4 相似度计算公式的选择余弦相似度是默认选项但还有几个变体值得了解。皮尔逊相关系数在协同过滤中也经常使用它的特点是先对每个向量做中心化处理即减去均值再去计算相似度。这样做的意义在于消除用户的评分偏差——有的用户习惯给4分以上有的用户习惯给3分以下如果不做中心化这两个用户即使口味一致余弦相似度也会偏低。from scipy.stats import pearsonr def pearson_similarity(vec1, vec2): mask (vec1 0) (vec2 0) if mask.sum() 3: return 0 corr, _ pearsonr(vec1[mask], vec2[mask]) return corr这个实现里我做了一个过滤只有两个向量在相同位置都有有效评分的维度才参与计算同时要求至少有3个共同评分项否则直接返回0防止小样本下的巧合高相关。实际项目中如果评分数据的稀疏度比较高余弦相似度的表现通常比皮尔逊好因为皮尔逊对共同评分项的数量更敏感。但如果数据比较稠密皮尔逊能更好地消除用户评分习惯差异带来的偏差。4. 推荐效果怎么量化离线评测的实操方法4.1 训练集/测试集切分推荐系统项目不能只做“能不能跑通”还要回答“推荐效果好不好”。这个问题的标准答案来自离线评测。先用train_test_split把评分数据分成训练集和测试集from sklearn.model_selection import train_test_split train_data, test_data train_test_split(ratings, test_size0.2, random_state42)这里有一个容易被忽视的问题随机切分会把某个用户的所有评分同时分到训练集和测试集导致测试集里出现训练集从未见过的用户。这在电影推荐场景下其实是可以接受的因为推荐系统的核心任务是预测“已存在用户”对“未看过的电影”的评分。但如果你要做严格的用户隔离——即训练集和测试集的用户完全不重叠——需要按用户分组切分train_data ratings.groupby(userId).apply(lambda x: x.sample(frac0.8, random_state42)) test_data ratings.drop(train_data.index)按用户隔离的评测结果更能反映真实场景下的泛化能力因为现实中系统要服务的就是老用户对新物品的反应。无论用哪种切分方式都不要忘记设置random_state否则每次跑出来的结果都不一样没法对比调优。4.2 精确率、召回率、覆盖率、RMSE 的计算口径推荐系统的评测指标很多但基础版项目掌握四个就够用了。RMSE均方根误差用来衡量评分预测的准确性是回归类指标适合评估“预测分是否接近真实分”from sklearn.metrics import mean_squared_error import numpy as np rmse np.sqrt(mean_squared_error(y_true, y_pred))精确率和召回率则是推荐列表的排序指标。精确率表示推荐列表中有多少是用户真的喜欢的召回率表示用户喜欢的所有物品中有多少被推荐出来了。两者的计算逻辑是先定义“喜欢”的阈值比如评分大于等于4.0算喜欢然后对每个用户取推荐列表Top-K统计命中情况def precision_recall_at_k(predictions, k10, threshold4.0): user_est {} for uid, movie_id, true_rating, est in predictions: if uid not in user_est: user_est[uid] [] user_est[uid].append((movie_id, est)) precisions [] recalls [] for uid, items in user_est.items(): # 推荐列表取评分最高的k个 top_k sorted(items, keylambda x: x[1], reverseTrue)[:k] # 用户真实喜欢的电影 actual {movie_id for movie_id, _, _, _ in predictions if uid _uid and _ movie_id} # 实际统计 ... return np.mean(precisions), np.mean(recalls)覆盖率的含义是推荐系统能够推荐出多少不同的电影如果系统永远只推荐那20部热门电影覆盖率就会很低。基础做法是统计所有推荐列表中不同电影的数量除以总电影数。这四个指标从不同维度评估系统RMSE看预测精度精确率和召回率看推荐列表质量覆盖率看推荐多样性。一个优秀的推荐系统需要在它们之间取平衡。4.3 评测结果怎么用跑完评测之后你的工作还没结束。评测结果要用来指导调参。我自己的调参顺序是先看RMSE如果预测误差很大优先检查相似度计算是否正确、评分矩阵是否过于稀疏再看精确率10如果数值很低说明推荐列表相关性差可能需要调整相似用户数量top_n、是否对评分做中心化处理最后看覆盖率如果覆盖率很低考虑在推荐生成阶段加入随机性或者多样性惩罚。比较两个算法版本时一定要保持测试集一致。很多人在对比UserCF和ItemCF时每次都重新随机切分数据导致结果差异由随机性主导而非算法差异这个坑要避开。5. 代码结构里的隐藏信息读懂项目源码的阅读顺序5.1 从入口文件开始梳理主流程拿到源码别急着从头到尾读代码那会陷入细节的海洋。我的建议是先找到入口文件通常是main.py、run.py或者app.py从入口开始顺着调用链往下读。一个典型的电影推荐系统源码结构大概长这样movie_recommend/ ├── data/ │ ├── movies.csv │ ├── ratings.csv │ └── tags.csv ├── src/ │ ├── data_loader.py # 数据加载与预处理 │ ├── similarity.py # 相似度计算 │ ├── recommend.py # 推荐逻辑 │ ├── evaluate.py # 离线评测 │ └── main.py # 入口 ├── requirements.txt └── README.md读入口文件时重点关注几个问题数据从哪里加载推荐是实时计算还是离线预计算最终输出是什么格式搞清楚这些之后你再深入到具体模块。5.2 核心模块的依赖关系数据加载模块是整个项目的基础它决定了后续所有模块拿到的数据格式是什么。比如data_loader.py里如果已经做了评分矩阵的转换那么recommend.py就不需要再重复处理。相似度计算模块通常独立于推荐逻辑模块这是好的设计——你可以替换相似度算法而不影响其他部分。如果源码里把相似度计算和推荐逻辑耦合在同一个函数里那说明代码结构不好你在改造时要考虑拆开。推荐逻辑模块是整个项目的核心需要注意预测评分后的排序逻辑是直接用预测评分排序还是要在排序时加入惩罚项比如降低太热门电影的权重基础版的实现通常直接用预测评分排序但你的改进版可以从这里入手。5.3 常见运行问题与修复根据我帮人排查的经验代码运行时的报错集中在三个地方。第一个是FileNotFoundError。多半是因为工作目录不对在项目根目录下运行时代码里的相对路径才能正确解析。解决办法有两种一是写代码时用os.path.join(os.path.dirname(__file__), ...)基于当前文件位置定位二是运行时先cd到项目根目录。第二个是相似度矩阵维度不匹配。原因是训练集和测试集构建评分矩阵时列电影ID不一致。比如训练集里的电影集合是A测试集里的电影集合是BA和B不完全相同导致矩阵乘法或索引时出错。解决办法是在构建矩阵之前先取全量数据的电影ID集合保证训练和测试的列一致。第三个是内存溢出。虽然ml-latest-small不会爆内存但如果你换成了大数据集用户相似度矩阵的规模就是用户数的平方几百万用户直接就会OOM。优化思路是用稀疏矩阵存储或者采用分块计算。修复代码Bug时有几条经验可以分享先看报错堆栈的最后一行那是错误发生的位置打印中间变量的shape和dtype很多问题出在数据格式上改完代码后一定要重新跑评测而不是只看能不能运行。6. 发布与使用的产品思维从“能跑的脚本”到“合格的源码包”6.1 结构设计让拿到包的陌生人五分钟内跑起来很多课程设计或开源的电影推荐系统代码逻辑没问题但别人拿到之后根本跑不起来。差距不在算法而在“交付意识”。一份合格的源码zip包解压之后应该是这样的结构movie_recommend_system/ ├── README.md ├── requirements.txt ├── run.py ├── src/ │ ├── __init__.py │ ├── data_loader.py │ ├── models/ │ │ ├── __init__.py │ │ ├── user_cf.py │ │ └── item_cf.py │ ├── evaluate/ │ │ ├── __init__.py │ │ └── metrics.py │ └── utils/ │ ├── __init__.py │ └── common.py ├── data/ │ └── ml-latest-small/ │ ├── ratings.csv │ └── movies.csv ├── config/ │ └── config.yaml ├── output/ │ └── .gitkeep └── tests/ └── test_similarity.py特别注意几个细节完整的数据文件要不要打进zip包我建议打进去。虽然数据集可能几十MB但用户拿到就能直接跑体验远好于“请自行下载数据”这种提示。输出目录用.gitkeep占位避免空目录在打包时被忽略。测试文件虽然项目里常被删掉但保留一个最简单的单元测试能极大提升项目的可信度。6.2 README与使用说明的写法README是源码包的“第一印象”但大多数项目的README都写成了摆设。合格的README应该包含项目简介两三句话说明这个项目是什么、解决了什么问题环境要求Python版本、操作系统兼容性、依赖库版本快速开始从解压到跑出第一个推荐结果的完整命令序列目录结构说明每个文件/目录是干什么的配置说明如果有config文件说明每个参数的含义和调整方式常见问题把你自己踩过的坑写进去别人就不用再踩一遍快速开始的示例写法# 进入项目目录 cd movie_recommend_system # 创建并激活虚拟环境 python -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate # 安装依赖 pip install -r requirements.txt # 运行推荐系统 python run.py --user_id 1 --top_k 10好的README是写给别人看的但最终受益的是你自己——三个月后你回头再看这个项目README就是最好的回忆线索。6.3 打包与分发别在生产环境犯的错最后聊一下zip打包时的规范性。这个项目最终以.zip分发那就要保证压缩包本身的质量。打包前先清理掉不必要的文件__pycache__目录、.pyc文件、虚拟环境目录.venv、IDE配置目录.idea和.vscode、数据集缓存。这些文件加起来可能比源码还大而且会让用户困惑哪些是项目必需文件。Linux下打包时有一个经典坑如果你在项目目录内直接执行zip -r ../movie_recommend.zip .可能会把隐藏文件也包进去。没问题但要小心不要把父目录的路径层级打进去。规范的打包方式是先退到上层目录再指定打包目录名cd .. zip -r movie_recommend_system.zip movie_recommend_system这样解压出来就是一个顶级目录movie_recommend_system/而不是一堆散落的文件直接糊在解压目录里。打包完成后一定要做一次“干净环境验证”找另一台没有安装任何Python依赖的机器或者一个全新的虚拟环境严格按照README步骤跑一遍。只要这一步通过了这个zip包才算真正合格。这些看起来都是小事但恰恰是这些细节决定了你的项目是“一顿操作猛如虎人家一跑全是坑”还是“解压五分钟跑通两分钟”。我在实际排查这些推荐系统项目时最深的体会是代码本身往往没什么大问题问题几乎都出在环境、数据、路径这些“边缘环节”。所以这篇文章花了不少篇幅在讲这些看似与算法无关的事——但它们恰恰是让项目真正可用的关键。如果你准备基于这个源码包做二次开发我建议的路径是先完整跑通一遍流程再逐步阅读核心模块代码然后尝试替换相似度算法或评测指标最后再考虑引入新的数据集。每一步都做好记录这样你既能深入理解推荐系统的运作机制也能获得一个真正属于自己的项目。本文还有配套的精品资源点击获取
返回列表