分数,而非判决
到现在,你已经会读混淆矩阵、会算精确率和召回率了。但所有这些数字背后藏着一个假设:模型已经做出了"是"或"否"的判定。然而现实中,几乎每个分类器——逻辑回归、随机森林、以Sigmoid收尾的神经网络——都不会直接递给你一个判决,它递给你的是一个分数:一个常在 0 到 1 之间的数,表示它对正类倾向有多强。
要把分数变成决定,你需要一个阈值——一条切分线。分数高于这条线,就判为正;低于它,就判为负。常见的默认值 0.5 看起来很自然,但它只是一种约定,并非法则。把阈值往上挪,你就更严格(正例更少);往下挪,你就更宽松。你之前学过的每个指标——精确率、召回率、F1——都悄悄取决于你把这条线划在哪里。
ROC 曲线:一次看尽所有阈值
与其锁定一个阈值,不如把*所有*阈值都试一遍,再把结果画出来?这正是 [[roc-curve|ROC 曲线]]所做的事。对每一个可能的切分点,它衡量两件事:真正例率(即召回率——你抓到的真实正例所占的比例)和假正例率(你错误标记的真实负例所占的比例)。把假正例率放在横轴、真正例率放在纵轴,再让阈值从严到宽地扫过,连成的点迹就是 ROC 曲线。
看清两个角,画面就清晰了。在很严的阈值下(要求极高分),你几乎什么都不标记:两个比率都接近 0,落在左下角。在很宽的阈值下,你什么都标记:两个比率都接近 1,落在右上角。一个只会瞎猜的无用模型,会沿着从一角到另一角的对角线走。好模型则向左上角拱起——在抓住大量真正例的同时,把假正例压得很低。曲线越贴近那个左上角,模型就越好。
TPR 1 | ____------ good model (bows to top-left) | _--/ | _/ .... random guess (diagonal) | _/ .... | / .... 0 |/ ...______________________ 0 1 FPR
AUC:把曲线压成一个数
一整条曲线很难塞进表格,于是人们用 [[auc|AUC]] 来概括它——即 *ROC 曲线下的面积*。完美的模型填满整个方框:AUC = 1.0。瞎猜走对角线,把方框切成两半:AUC = 0.5。所以 AUC 介于 0.5(毫无价值)与 1.0(完美无缺)之间,越大越好。AUC 低于 0.5 意味着模型比随机还差——通常说明你的标签弄反了。
AUC 有一个优美而直观的含义:它是模型给*随机抽取的一个正例*打出的分数高于*随机抽取的一个负例*的概率。换句话说,它衡量的是排序质量——模型把正例排在负例之上的能力——而且这一衡量*与任何阈值无关*。这正是 AUC 在回答"模型好不好?"时如此受欢迎的原因:它评判的是分数本身,而非某个任意的切分点。
当 ROC 说谎:类别失衡与 PR 曲线
ROC 有一个盲点,而它恰恰在现实最棘手处暴露出来:[[class-imbalance|类别失衡]]。设想欺诈检测,每 1000 笔交易里只有 1 笔是欺诈。假正例*率*的分母是那一大堆负例,因此即便有成千上万次误报,它也几乎纹丝不动。一个模型可以拿出漂亮的 0.95 AUC,却仍把每一起真欺诈埋在误报的大山之下——因为 ROC 曲线从不去看你*标记出来*的案例里到底有多少是对的。
这正是 [[precision-recall-curve|精确率-召回率曲线]]大显身手之处。它把精确率(在我标记的全部里,有多少是对的?)对召回率(在所有真实正例里,我抓到了多少?)作图,同样扫过每一个阈值。由于精确率只盯着你的正类预测,它*不会*被一片浩瀚的简单负例稀释。在正例稀少的问题上,一个在 ROC 上看似不错的平庸模型,会暴露出一条可怜下垂的 PR 曲线——这才是"你的警报有多常出错"的诚实写照。
为你的真实问题选定阈值
曲线和 AUC 告诉你模型的*潜力*。可上线时仍需要一个数:阈值。而正确的阈值不是数学问题,而是*代价*问题。要问:哪种错误更伤人?把一封真实的工作邀约扔进垃圾箱(假正例)的垃圾邮件过滤器,远比放过一封垃圾邮件糟糕,于是你调高阈值以保护精确率。漏掉一个真实肿瘤(假负例)的癌症筛查是灾难性的,于是你调低阈值以保护召回率,宁可接受更多可由复查排除的误报。
- 写下你的问题中每种错误的代价——以金钱、伤害或用户信任来计。要具体;模糊的直觉只会带来模糊的阈值。
- 选出这些代价所对应的指标:漏检致命就追求高召回率,误报昂贵就追求高精确率,两者都重要就用 F1 或加权折中。
- 在验证集上扫过各个阈值,记录每个阈值下的该指标,挑出使其最大的那个阈值。
- 锁定该阈值,再在从未碰过的测试集上报告最终数字,确保这一选择没有被悄悄过拟合。
把这几层理清,你就再也不会被单一数字蒙骗了。AUC 与曲线为模型排序,且对任何阈值都成立;阈值把分数变成行动,必须反映真实世界的代价;在所选阈值下的精确率与召回率才是你的用户真正要承受的。一个 AUC 高达 0.99 的模型,若其工作点悄悄牺牲了你最承受不起的那种错误,依然可能是错的工具。