
协同过滤模型AUC 0.97被用户嫌弃,补完机器学习基础我才懂PR曲线的价值去年年底,我负责的推荐系统模块终于要推上线了。模型用的是经典的协同过滤,离线跑完一轮测试集,AUC 冲到 0.97,召回率 0.91,当时觉得稳了。可灰度第 2 天,用户投诉群炸了--「为什么给我推看过八百遍的内容」「全是和我口味无关的冷门物品」。我对着监控面板发呆:所有离线指标都接近满分,协同过滤的得分分布也没有明显异常,问题到底出在哪?直到后来我咬牙把亚马逊云科技上整套机器学习基础啃完,才在 ROC 和 PR 曲线的交叉推导里发现了盲点:协同过滤这类极度依赖隐式反馈、正负样本严重倾斜的数据,AUC 这张“好学生成绩单”会骗人。这门机器学习基础课从混淆矩阵的代数定义讲起,用交互式实验让你亲眼看着同一份协同过滤预测结果,在 ROC 和 PR 曲线上画出截然不同的形状,直接帮我避免了把用户劝退的灾难。如果你也正在调推荐模型,或者在指标上被老板质疑过,不妨跟着我的踩坑经历往下看。我为什么一开始只信 AUC刚接手推荐项目时,我对评估指标的理解基本来自博客和比赛经验。比赛里大家都用 AUC,我也就默认协同过滤的离线验证只认这一个数。实现上我选的是基于用户的协同过滤,利用近三个月的行为日志做相似度计算,再对未交互物品打分排序。当时我还特意用机器学习入门里提到的方式做了简单的数据预处理:剔除冷启动用户,对点击时长做了对数平滑,然后切分训练集和验证集。# 基于用户的协同过滤评分预测(部分代码) def predict(user_id, item_id, user_sim, ratings): # 找出与目标用户最相似的前K个用户 neighbors sorted(user_sim[user_id].items(), keylambda x: x[1], reverseTrue)[:50] weighted_sum 0.0 sim_sum 0.0 for neighbor, sim in neighbors: if item_id in ratings[neighbor]: weighted_sum sim * ratings[neighbor][item_id] sim_sum abs(sim) if sim_sum 0: return 0.0 return weighted_sum / sim_sum用这份代码跑完验证集,AUC 稳稳 0.97,让我以为自己很快就能交出漂亮的推荐模块。可后面一连串的投诉让我意识到:协同过滤的高 AUC 或许只是数字幻觉。当时的我完全不了解,同样的协同过滤预测概率,用 PR 曲线评估会得到完全相反的结论--这个道理,直到我补完机器学习基础才彻底想通。上线后用户差评如潮,我开始怀疑一切灰度发布第二个工作日,产品经理拿着用户反馈的截图找我:推荐列表里充斥大量用户已经购买过的物品,新内容占比不到 8%,而且多数点击来自价格敏感型用户,但推荐的全是高价冷门货。我重新拉了日志,发现协同过滤的预测分分布极度右偏:90% 以上的物品得分在 0.02 以下,只有少部分热门物品集中 0.8 以上。这直接导致阈值调高一点点就推不出新物品,调低一点点就推一堆毫不相干的东西。这时我想起AWS 基础知识里曾提过,线上效果恶化往往不是模型本身错,而是评估体系没对齐业务目标。推荐场景里正样本是极其稀疏的,用户真正点击过的物品占候选集的千分之一甚至更低。而协同过滤这类算法输出的概率分布天然不均衡,这种情况下 ROC 曲线因为同时观察真阳性率和假阳性率,会被海量的负样本“撑高”,从而把模型真实排序能力的缺陷掩盖掉。我需要重新审视每一个评估指标--而这恰好是机器学习基础课程里着重强调的环节。补上机器学习基础:重新认识混淆矩阵我花了一个周末集中把机器学习基础中关于评估指标的章节过了一遍。课程不是从公式罗列开始,而是先给你一个真实数据集,让你在AWS机器学习提供的在线 Notebook 里直接计算混淆矩阵。当我把协同过滤在验证集上的混淆矩阵打出来时,才第一次看清楚问题全貌:from sklearn.metrics import confusion_matrix # y_true: 用户是否真实点击,y_pred_binary:根据阈值0.5二值化协同过滤得分 import numpy as np y_true test_logs[click].values y_pred_score collaborative_filtering.predict(test_logs[[user_id, item_id]]) y_pred_binary (y_pred_score 0.5).astype(int) cm confusion_matrix(y_true, y_pred_binary) print(cm) # 输出示例: # [[48230 120] # [ 350 80]] # 真阴性 TN 极大,真阳性 TP 极小,典型的类不平衡机器学习基础用几段推导把准确率、精准率、召回率和 F1 的适用场景串了起来,尤其强调了一个协同过滤工程师必须刻进脑子的规则:对于排序类任务,只看准确率毫无意义,因为负样本太多,哪怕全部预测负类,准确率也能接近 99%。我立刻意识到,自己之前用 AUC 作为唯一指标,是因为漏掉了这门机器学习基础所强调的“业务代价矩阵”--把不喜欢的物品推到用户眼前,造成的体验损失远比漏推一部好电影更大。课程的交互实验让我可以对协同过滤的同一份预测结果,拖拽阈值实时观看混淆矩阵四个格子的变化,那个“啊哈”瞬间比读十篇论文都来得直接。从 ROC 到 PR 曲线,协同过滤的评估拐点理解了混淆矩阵只是开头。机器学习基础紧跟着引入 ROC 曲线和 PR 曲线,并且用同一份协同过滤的验证数据画出两条曲线做对比。这是我当时画的两幅图:from sklearn.metrics import roc_curve, precision_recall_curve import matplotlib.pyplot as plt fpr, tpr, _ roc_curve(y_true, y_pred_score) precision, recall, _ precision_recall_curve(y_true, y_pred_score) plt.subplot(1,2,1) plt.plot(fpr, tpr) plt.title(ROC Curve (AUC0.97)) plt.subplot(1,2,2) plt.plot(recall, precision) plt.title(PR Curve (AP0.41)) plt.show()同一份协同过滤的预测分数,ROC 曲线上华丽得让人想立刻发版,而 PR 曲线上的平均精度(AP)只有 0.41。课程里用公式一步一步推导了为什么在负样本爆炸的情况下,ROC 的假阳性率会被迅速拉低,制造出 AUC 虚高的假象;而 PR 曲线只关注正类的预测质量,更能反映协同过滤推荐给用户的 top-N 列表到底有多少是真正相关的。亚马逊云科技机器学习的这门基础课还给出了一个实用口诀:当正样本比例低于 10%,PR 曲线比 ROC 更诚实;低于 1%,必须放弃 AUC 改用 PR-AUC 或 normalized DCG。按这个标准重新评估我的协同过滤,把阈值从 0.5 降到 0.35 后,PR 曲线的平均精度从 0.41 提到 0.68,召回率从 0.55 跃升到 0.89,而准确率只损失了 4 个百分点。这些调整如果继续靠盲调,恐怕要折腾一个月--机器学习基础让你掌握的是「问正确问题」的能力,而不仅仅是调参技巧。多分类扩展与代价敏感评估接下来业务有了新需求:把协同过滤的推荐分成「强推」「弱推」「不推」三类,引入多分类评估。机器学习基础里面对于多分类的混淆矩阵、宏平均和微平均的处理也给了完整框架。我把每个用户-物品对的得分用两个阈值切出三个区间,然后计算每一类的 precision 和 recall,最终用加权 F1 衡量整体效果。这一轮优化我把推荐系统的用户负反馈率从发版初期的 18% 压到了 5%,点击率提升了 42%。更重要的是,机器学习管道中后续加入的数据漂移监控,让我每月都能用最近的日志回放一遍评估指标,一旦 PR 曲线出现退化就启动模型重训,而不再依赖离线的 AUC 报警。AWS机器学习课程中对于特征工程和数据预处理的讲解,也让我回头检查了协同过滤输入的稀疏矩阵,发现不少交互日志其实需要更细粒度的清洗--补上这些基础之后,整个推荐系统的稳定性明显提升。学完后的回滚清单:给同样搞协同过滤的你这次事故最后变成了一次系统性反思,我把补救过程中学到的东西整理成一份清单,希望帮你绕过我踩过的坑:至少看两个指标:协同过滤上线前,必须同时输出 PR 曲线下的平均精度(AP)和 normalized DCG,单靠 AUC 就是在蒙着眼睛开车。机器学习基础的交互实验能让你在半小时内建立这种双指标意识。阈值不能拍脑袋:用课程里教的阈值寻优方法,在 PR 曲线上找 F1 最大点或满足业务召回底线的最低阈值,比固定 0.5 靠谱得多。理解混淆矩阵的代价:不同推荐错误的代价是不一样的,把“不相关物品推给用户”的惩罚权重设高,在机器学习基础里专门有一节教你如何构建代价矩阵并嵌入评估流程。管道化监控:学完机器学习管道后,我会在每次训练协同过滤模型后自动输出评估快照,包括混淆矩阵、PR 曲线数据点,并上传到 S3 以备回归分析--这些是AWS机器学习平台上很容易实现的操作。补足特征和数据预处理短板:模型效果的天花板很多时候在数据,特征工程和数据预处理的细节能直接决定协同过滤的正负样本比例,花一周啃下这部分,省下的是反复调参的几个月。如果对深度学习感兴趣,可以接着用深度学习入门把协同过滤升级为神经协同过滤(NCF),但建议先打好机器学习基础,否则评估环节会重蹈覆辙。线上灰度前别偷懒:任何模型在灰度阶段都该用小流量做一次完整的评估复盘,包括混淆矩阵各格计数、PR 曲线形状、top-N 推荐列表的人工抽检--这些习惯正是机器学习基础这门课程反复强调的工程素养。