机器学习人工智能【免费下载链接】SurpriseA Python scikit for building and analyzing recommender systems项目地址https://gitcode.com/gh_mirrors/su/Surprise点击查看免费下载Surprise 是基于 Python 的推荐系统构建与分析工具库其surprise/prediction_algorithms/knns.py模块提供了一组直接源于基础最近邻nearest neighbors思路的协同过滤算法。本文以 doc/source/knn_inspired.rst 为主线逐一讲解 KNNBasic、KNNWithMeans、KNNWithZScore、KNNBaseline 的预测公式、参数默认值与底层实现并深入sim_options相似度配置与bsl_options基线配置的完整细节。读完本文你将能够根据业务场景选择合适的 k-NN 变体、正确配置相似度与基线参数并通过actual_k字段与get_neighbors()方法获得可验证的预测细节与最近邻结果。一、k-NN 启发算法总览Surprise 文档将这一类算法统称为 k-NN inspired algorithms它们都直接衍生于基础的最近邻方法对一个待预测的 (user, item) 组合先找到与该用户或该物品最相似的一批用户或物品再用这些邻居的评分做加权聚合得到预测值。所有这类算法都继承自抽象基类SymmetricAlgo定义于 surprise/prediction_algorithms/knns.py。所谓对称symmetric指算法既可以基于用户user-based也可以基于物品item-based运行当sim_options[user_based]为真时x 表示用户、y 表示物品反之则颠倒。SymmetricAlgo在fit()中根据该开关统一选取n_x、xr、yr等内部结构并用switch(u, i)方法完成用户/物品角色的切换四个算法因此共享同一套框架仅预测公式不同。关于 k 值的一个重要提醒actual_k文档中特别强调了一个易被忽略的事实实际参与聚合的邻居数必然小于或等于 k。原因有二数据中可能根本不存在足够数量的邻居邻居集合 Nᵏᵢ(u) 与 Nᵏᵤ(i) 只包含相似度为正的邻居——将负相关用户或物品的评分纳入聚合没有意义。对于每一次预测真实的邻居数量可以通过预测对象Prediction的details字典中的actual_k字段获取。Prediction是定义于 surprise/prediction_algorithms/predictions.py 的命名元组包含uid、iid、r_ui、est、details五个字段其中details还带有was_impossible与reason等诊断信息。这一行为在测试中得到了直接验证tests/test_algorithms.py 的test_knns用例断言对所有不可能预测之外的样本必须满足min_k pred.details[actual_k] k。二、KNNBasic最朴素的加权最近邻KNNBasic 是四者中最基础的协同过滤算法其预测值即为邻居评分的相似度加权平均用户视角user-basedr̂_ui Σ_{v ∈ Nᵏᵢ(u)} sim(u, v) · r_vi / Σ_{v ∈ Nᵏᵢ(u)} sim(u, v)物品视角item-basedr̂_ui Σ_{j ∈ Nᵏᵤ(i)} sim(i, j) · r_uj / Σ_{j ∈ Nᵏᵤ(i)} sim(i, j)实现于 surprise/prediction_algorithms/knns.py。其核心estimate()流程为从yr[y]取出所有与 y 相关的邻居评分用heapq.nlargest(self.k, ...)按相似度取出前 k 个然后只累加sim 0的项若正相似度邻居数actual_k min_k则抛出PredictionImpossible(Not enough neighbors.)预测值回退为全局评分均值见AlgoBase.default_prediction()surprise/prediction_algorithms/algo_base.py。参数一览参数含义默认值k聚合时考虑的最大邻居数实际数 ≤ k见上文 actual_k 说明40min_k聚合所需的最少邻居数不足时预测被设为全局评分均值1sim_options相似度度量配置字典见下文相似度配置{}verbose是否打印基线估计、相似度计算等过程信息True三、KNNWithMeans考虑用户均值的变体KNNBasic 的一个明显弱点是评分尺度差异有些用户习惯打高分有些则普遍给低分。KNNWithMeans 在聚合前先对每个评分减去其归属用户或物品的均值从而消除这种系统性偏差用户视角r̂_ui μ_u Σ sim(u, v)·(r_vi − μ_v) / Σ sim(u, v)物品视角r̂_ui μ_i Σ sim(i, j)·(r_uj − μ_j) / Σ sim(i, j)实现见 surprise/prediction_algorithms/knns.py。fit()阶段会计算每个 x 的均值存入self.meansestimate()中邻居贡献被替换为sim * (r - self.means[nb])最终以self.means[x]为基准累加。与 KNNBasic 不同的是当actual_k min_k时KNNWithMeans不会抛异常而是将邻居聚合项置零预测直接退化为均值 μ_u或 μ_i若sum_sim为零例如所有邻居相似度都不为正同样通过捕获ZeroDivisionError返回均值。参数与 KNNBasic 完全相同k40、min_k1、sim_options{}、verboseTrue。四、KNNWithZScore基于 z-score 标准化的变体KNNWithZScore 在均值的基础上进一步考虑了评分的波动性用 z-score 标准化消除用户或物品评分方差的影响用户视角r̂_ui μ_u σ_u · [ Σ sim(u, v)·((r_vi − μ_v)/σ_v) ] / Σ sim(u, v)物品视角r̂_ui μ_i σ_i · [ Σ sim(i, j)·((r_uj − μ_j)/σ_j) ] / Σ sim(i, j)实现见 surprise/prediction_algorithms/knns.py。fit()阶段计算每个 x 的均值与标准差存入self.means、self.sigmas有一个值得注意的边界处理若某个用户或物品的 σ 为 0则用整体标准差self.overall_sigma对所有评分求标准差代替避免除零。预测时邻居贡献为sim * (r - self.means[nb]) / self.sigmas[nb]最后再乘回目标 x 的self.sigmas[x]还原尺度当actual_k min_k或sum_sim为零时同样回退为均值。参数与前面一致k40、min_k1、sim_options{}、verboseTrue。五、KNNBaseline引入基线评分的变体KNNBaseline 是四个算法中原理最高级的一个它把预测拆成两部分一个全局的基线评分b_ui 加上邻居残差的加权和用户视角r̂_ui b_ui Σ sim(u, v)·(r_vi − b_vi) / Σ sim(u, v)物品视角r̂_ui b_ui Σ sim(i, j)·(r_uj − b_uj) / Σ sim(i, j)其中基线评分由 b_ui μ b_u b_i 给出μ 为全局均值b_u、b_i 为用户、物品偏置。该算法对应 Koren 2010 年论文《Factor in the Neighbors: Scalable and Accurate Collaborative Filtering》中第 2.2 节的公式 (3)。实现见 surprise/prediction_algorithms/knns.py。fit()中先通过compute_baselines()求得self.bu, self.bi再计算相似度矩阵。estimate()与前面几个算法的显著差异在于若用户或物品未知不会抛异常而是直接返回基线值global_mean bu[u] bi[i]缺失项按 0 计邻居的残差以邻居自身的基线global_mean bx[nb] by[y]为参照actual_k min_k或sum_sim 0时同样退化为纯基线预测。KNNBaseline 专属参数除k、min_k、sim_options、verbose外KNNBaseline 还接受bsl_options字典来配置基线计算方法详见下文基线配置。文档明确建议为获得最佳预测效果应使用pearson_baseline相似度度量——它与基线评分天然配套。六、sim_options相似度度量配置全解k-NN 类算法的相似度计算由sim_options字典控制文档见 doc/source/prediction_algorithms.rst底层实现见 surprise/prediction_algorithms/algo_base.py 的compute_similarities()。所有键均为可选键含义默认值name相似度度量名称取值于surprise.similarities模块cosine、msd、pearson、pearson_baselinemsduser_based相似度在用户之间还是物品之间计算。该开关对算法性能有巨大影响Truemin_support相似度不为零所需的最少共同物品数user-based或共同用户数item-based。即当I_uv min_support 时 sim(u,v) 01shrinkage收缩shrinkage参数仅对pearson_baseline有效100四种相似度的数学定义与实现均在 surprise/similarities.pyxCython 实现性能关键路径cosinesimilarities.pyx余弦相似度仅利用共同评分项计算。msdsimilarities.pyxMean Squared Difference先算平均平方差 msd (1/|I_uv|)·Σ(r_ui − r_vi)²再映射为 sim 1/(msd 1)1仅为避免除零。pearsonsimilarities.pyx皮尔逊相关系数可视为均值中心化后的余弦。注意若无共同评分对象相似度为 0而非 −1。pearson_baselinesimilarities.pyx以基线 b_ui 代替均值做中心化的皮尔逊系数并施加收缩因子 (|I_uv| − 1)/(|I_uv| − 1 shrinkage)shrinkage0 即不收缩可缓解仅少量评分时的过拟合。该函数内部将min_support强制提升为至少 2因为收缩在支撑为 1 时无意义。配置示例以下片段取自 examples/similarity_conf.py展示两种典型配置并用cross_validate评估from surprise import Dataset, KNNBasic from surprise.model_selection import cross_validate data Dataset.load_builtin(ml-100k) # 示例一余弦相似度基于物品item-item sim_options { name: cosine, user_based: False, # compute similarities between items } algo KNNBasic(sim_optionssim_options) cross_validate(algo, data, verboseTrue) # 示例二pearson_baseline 相似度shrinkage 设为 0即不收缩 sim_options {name: pearson_baseline, shrinkage: 0} algo KNNBasic(sim_optionssim_options) cross_validate(algo, data, verboseTrue)若传入了sim_options中不存在的相似度名称compute_similarities()会抛出NameError并列出允许的取值cosine、msd、pearson、pearson_baseline。七、bsl_options基线估计配置全解KNNBaseline 以及pearson_baseline相似度都需要计算基线 b_u、b_i。Surprise 提供两种估计方法文档见 doc/source/prediction_algorithms.rst通过bsl_options字典的method键选择默认als底层分发逻辑见 algo_base.pyALS 与 SGD 的实现分别在 optimize_baselines.pyx 的baseline_als与baseline_sgd。两种方法都会最小化正则化平方误差Σ (r_ui − (μ b_u b_i))² λ(b_u² b_i²)且用户与物品偏置均从零初始化。ALS 方法参数键含义默认值reg_i物品正则化参数对应 λ₂10reg_u用户正则化参数对应 λ₃15n_epochsALS 迭代轮数Koren 原文描述的其实只是单轮 ALS10SGD 方法参数键含义默认值reg目标函数正则化参数对应 λ₁0.02learning_rateSGD 学习率对应 γ0.005n_epochsSGD 迭代轮数20示例片段取自 examples/baselines_conf.pyfrom surprise import BaselineOnly, Dataset, KNNBasic from surprise.model_selection import cross_validate data Dataset.load_builtin(ml-100k) # ALS 配置 bsl_options {method: als, n_epochs: 5, reg_u: 12, reg_i: 5} algo BaselineOnly(bsl_optionsbsl_options) cross_validate(algo, data, verboseTrue) # SGD 配置 bsl_options {method: sgd, learning_rate: 0.00005} algo BaselineOnly(bsl_optionsbsl_options) cross_validate(algo, data, verboseTrue) # 相似度也可以使用基线配置方式完全相同 bsl_options {method: als, n_epochs: 20} sim_options {name: pearson_baseline} algo KNNBasic(bsl_optionsbsl_options, sim_optionssim_options) cross_validate(algo, data, verboseTrue)注意最后一个例子KNNBasic 本身并不在预测公式中使用基线但pearson_baseline相似度内部需要基线因此它也会接受bsl_options通过**kwargs透传见 knns.py 的注释说明。若传入不存在的 method 值会抛出ValueError并提示可选值为als与sgd。八、从源码看 k-NN 的预测链路理解AlgoBase的公共方法有助于把上述知识串成完整调用链surprise/prediction_algorithms/algo_base.pyfit(trainset)各 k-NN 算法调用SymmetricAlgo.fit()初始化内部结构再执行各自的compute_baselines()仅 KNNBaseline与compute_similarities()得到 n_x × n_x 的相似度矩阵self.sim。predict(uid, iid, r_ui, clip, verbose)把原始 id 转换为内部 id转换失败标记为UKN__...调用子类实现的estimate()若抛出PredictionImpossible则回退到default_prediction()全局均值并在details中记录was_impossibleTrue与原因最后按clipTrue将估计值裁剪进评分尺度 [lower_bound, higher_bound]。test(testset)对测试集中每条 (uid, iid, r_ui) 逐条调用predict()返回Prediction列表供 accuracy.py 中的 RMSE、MAE 等指标计算。四个算法的estimate()都通过heapq.nlargest取前 k 个邻居且只累加正相似度——这正是actual_k k的代码级原因见 knns.py。九、实战获取最近邻与算法效果对比获取 k 个最近邻AlgoBase.get_neighbors(iid, k)algo_base.py可返回指定用户或物品的 k 个最近邻的内部 id适用于所有 k-NN 算法。示例 examples/k_nearest_neighbors.py 展示了完整的找 Toy Story 的 10 个最近邻电影流程from surprise import Dataset, KNNBaseline data Dataset.load_builtin(ml-100k) trainset data.build_full_trainset() sim_options {name: pearson_baseline, user_based: False} algo KNNBaseline(sim_optionssim_options) algo.fit(trainset) # 将原始电影 id 与名称互相映射读取 u.item 文件ISO-8859-1 编码 # ...详见 examples/k_nearest_neighbors.py 中的 read_item_names() toy_story_raw_id name_to_rid[Toy Story (1995)] toy_story_inner_id algo.trainset.to_inner_iid(toy_story_raw_id) toy_story_neighbors algo.get_neighbors(toy_story_inner_id, k10) # 再将内部 id 转回原始 id 与电影名打印即可其验证逻辑同样存在于测试中tests/test_algorithms.py 的test_nearest_neighbors断言同一数据集上 user-based 与 item-based 的 KNNBasic 得到的最近邻集合不同。各算法在 ml-100k 上的效果参照tests/test_algorithms.py 中固定了各算法在 MovieLens-100k 上的 RMSE 基准同一划分下可作为选型参照算法RMSE测试基准KNNBasiccosine1.1495KNNBasicmsd1.1337KNNBasicpearson1.1219KNNBasicpearson_baseline1.1242KNNWithMeans1.1043KNNWithZScore1.1118KNNBaseline1.0701从该基准可观察到在四个 k-NN 变体中引入基线评分的 KNNBaseline 通常取得最佳精度而相似度度量的选择msd 略优于 cosinepearson 系列更优也会显著影响 KNNBasic 的表现。十、选型建议追求极致简单、快速验证基线用KNNBasic()默认 msd 相似度即可。评分尺度因人/因物而异用KNNWithMeans它已消除均值偏移。评分尺度与波动性都需要校正用KNNWithZScore注意 σ0 时自动回退整体标准差。追求最优精度、可接受训练开销用KNNBaseline搭配sim_options{name: pearson_baseline}与适当的bsl_options。调节邻居数k控制聚合上限min_k控制最小支撑details[actual_k]可用来事后审计每次预测实际用到的邻居数。用户视角还是物品视角通过sim_options[user_based]切换对性能影响很大建议在具体数据上交叉验证对比。最后如需对k、min_k、sim_options、bsl_options做系统性调参可结合 doc/source/model_selection.rst 介绍的 GridSearchCV 使用四个算法的 dump/序列化支持见 tests/test_dump.py可直接用 surprise/dump.py 保存训练好的模型。赞分享机器学习人工智能【免费下载链接】SurpriseA Python scikit for building and analyzing recommender systems项目地址https://gitcode.com/gh_mirrors/su/Surprise点击查看免费下载相关推荐Surprise 基础算法全解NormalPredictor 与 BaselineOnly 基线模型的原理、配置与实战Surprise 基础算法全解NormalPredictor 与 BaselineOnly 基线模型的原理、配置与实战 本篇技术指南聚焦 Surprise 推机器学习人工智能Surprise 相似度模块深度解析cosine、msd、pearson 与 pearson_baseline 的数学原理与 sim_options 实战配置Surprise 相似度模块深度解析cosine、msd、pearson 与 pearson_baseline 的数学原理与 sim_options 实战配置机器学习人工智能CANN ops-nn ForeachSubListInplace 算子深度解析张量列表原地逐元素减法x1 - alpha·x2的原理与 aclnn 调用实战CANN ops nn ForeachSubListInplace 算子深度解析张量列表原地逐元素减法x1 alpha·x2的原理与 aclnn 调用人工智能算子库深度学习CANNAscend上一篇开源贡献指南如何为simple-evals项目提交PR下一篇httptap在多云环境中的终极部署指南10个关键策略创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?