The Number That Lied — 为什么AI评测从一开始就错了
那串骗人的数字 / The Number That Lied
> *Why AI Evaluation Was Wrong From the Start — A Chapter About a Number, a Bank, and the Question That Started a Revolution*
---
1.1 一通凌晨三点的电话 / A 3 AM Phone Call
2019 年 11 月的一个星期二,凌晨 3:17。陈思远的手机在床头柜上震动起来,屏幕上跳动着一个他这辈子都不想看到的名字 —— 风险管理部副总裁 Carlos Mendez。
这个电话用 47 秒改变了陈思远对 AI 评测的全部理解。
> This phone call — 47 seconds long — changed everything Chen Siyuan thought he knew about evaluation.
"陈,我们出事了。" Carlos 的声音没有任何情绪起伏,这比吼叫更让人脊背发凉,"过去 36 个小时,新上线的反欺诈模型批准了 87 笔高风险电汇,总金额 1.2 亿美元。我们有 95% 的把握认定这些交易是合成身份欺诈(synthetic identity fraud)。模型一个都没有拦下来。"
陈思远在床边坐直身体,脑子里浮现的第一个念头不是"模型怎么错了",而是"我们的 AUC 是 0.992,怎么可能?"
这不是一个新手的失误。这是一家市值排名前十的商业银行、由 12 名资深数据科学家与 3 名前学术界研究员组成的精英团队、使用 LightGBM 加上一整套自研特征工程 pipeline 打造的旗舰反欺诈模型。在离线测试中,模型的 AUC 达到了 0.992,召回率 96.4%,精确率 94.7%。它击败了所有 baseline 模型,并通过了风控委员会、合规部、技术委员会的三重审查。三周前在季度业务评审会上,CEO 还亲自表扬了这支团队。
而现在,1.2 亿美元的损失像冰水一样泼了下来。
"马上到总部," Carlos 说,"七楼战情室,所有人都到。"
陈思远挂了电话。太太在黑暗中问了一句:"又要去?"他说:"嗯。可能要几天。"
---
1.2 三周前的庆功宴 / The Celebration Three Weeks Ago
为了让你理解这场灾难的反差,我们必须先回到 21 天前。
10 月 21 日,星期一,下午 4:30。22 楼的小型会议室被布置成了一个简陋的庆功现场 —— 外卖披萨、香槟、一只印着 "Model v3.2 — Champion!" 的蛋糕。陈思远站在投影幕前,PPT 的最后一页写着:
> Model v3.2:业界领先的合成身份欺诈检测能力 > > - AUC: 0.992(baseline: 0.961) > - F1-score: 0.96 > - Recall @ 1% FPR: 91.4% > - 上线后预计每年减少损失 4,500 万美元
台下 12 张脸都在笑。Carlos 在角落里举着香槟杯,对 CFO 耳语着什么。CFO 在 iPad 上签了字。掌声响起。香槟的软木塞弹在天花板上,没人去捡。
没有人问那个本应被问的问题:这 0.992 究竟度量的是什么?
陈思远后来无数次回想这一刻,他意识到当时的每一个在场者 —— 包括他自己 —— 都默认了一个从未被讨论过、从未被写下来、从未被验证过的前提:
> 测试集上的优秀表现,会自动迁移到生产环境。
这种默认如此自然、如此普遍,以至于没有人觉得有必要把它说出来。它就像地心引力 —— 你不会在走路前先确认地球存在。但这一晚之后,陈思远知道:所有 AI 评测故事的原罪,就是把这条从未被审视的默认当成了真理。
数据科学家构建模型,模型在测试集上表现优异,团队庆祝,部署上线。没有人仔细审视过测试集本身,更没有人审视过"评测"这个动作究竟在度量什么、在度量谁的什么、在什么样的条件下度量、以及当条件改变时这个数字会变成什么。
我们都在用一把不知道刻度的尺子,去衡量一座山的海拔。
香槟的味道还没散,1.2 亿美元的教训就来了。
---
1.3 隐藏的假设:i.i.d. 与所有离线指标的"原罪" / The Hidden Assumption: i.i.d. and the Original Sin of Every Offline Metric
Carlos 在战情室里做的第一件事不是骂人,而是把陈思远叫到白板前:"用最简单的语言给我解释一下,为什么一个 AUC 0.992 的模型会让 1.2 亿美元的欺诈通过?"
陈思远在白板前站了很久,最后写下了一个缩写:
> i.i.d.
i.i.d. 是 *independent and identically distributed*(独立同分布)的缩写。这是几乎所有机器学习教科书的第一个前提假设,也是几乎所有离线评测指标 —— accuracy、precision、recall、F1、AUC、log-loss、PR-AUC、Brier score …… —— 能够成立的统计学根基。
它的精确含义是:训练数据中的每一个样本,都是从某个固定分布 $P$ 中独立采样而来;测试数据中的每一个样本,也是从同一个分布 $P$ 中独立采样而来。 当这个假设成立时,模型在测试集上的表现,就是它未来在生产环境中表现的无偏估计(unbiased estimator)。
用更数学的语言来说:若 $X_{\text{train}}, X_{\text{test}} \stackrel{\text{i.i.d.}}{\sim} P$,则对任意可学习函数 $f$,有
$$\mathbb{E}_{(x, y) \sim P}[\mathcal{L}(f(x), y)] \approx \frac{1}{N_{\text{test}}} \sum_{i=1}^{N_{\text{test}}} \mathcal{L}(f(x_i^{\text{test}}), y_i^{\text{test}})$$
也就是说,测试集上的损失期望 ≈ 生产环境中的损失期望。AUC 0.992 也就等价于"在生产中我有 99.2% 的概率把欺诈样本排在正常样本前面"。
但陈思远写下这两个字母的瞬间,他意识到:他们从来没有验证过 i.i.d. 是否成立。 不仅他们没验证,整个项目组没验证,风控委员会没验证,合规部没验证,CEO 更没验证。没有人验证,因为大家都不假思索地认为它成立。
但它不成立。它几乎从来都不成立。
1.3.1 训练-测试-生产的三重分离 / The Three-Way Split Between Train, Test, and Production
让我们具体拆解一下陈思远的团队到底做了什么。
他们的训练数据来自 2017 年 1 月至 2019 年 6 月的历史交易记录,标注由反欺诈运营团队人工打标 + 已知客户投诉回溯构成,总量约 470 万条。他们按照业界标准的 70/15/15 比例划分训练集、验证集、测试集。测试集上模型 AUC 0.992。
但生产环境中的数据是 2019 年 10 月以后的实时交易流。仅仅三个月的时间差,但在反欺诈这个领域,三个月足以让攻击者的策略发生质变。具体而言:
1. 数据生成机制变了:2019 年 Q3 起,一个有组织的犯罪团伙开始系统性使用合成身份(synthetic identity)发起攻击。所谓合成身份,是指用真实但无关的社安号、姓名、地址拼凑出的"全新"个人,这些人在信用局的数据库里没有任何历史行为模式。陈思远的训练数据中,几乎没有合成身份样本 —— 因为过去两年这种攻击模式占比不到 0.3%。 2. 行为模式变了:犯罪团伙还通过 bot network 模拟正常用户的"鼠标轨迹"和"页面停留时间",绕过了他们引以为傲的行为特征工程 pipeline。 3. 样本权重变了:2019 年 10 月银行的客户结构发生了变化 —— 由于一次营销活动,新增了 23 万年轻 Z 世代用户,这部分用户在历史数据中比例极低。
这三个变化意味着:测试集(2019 年 6 月以前的分布)和生产环境(2019 年 10 月以后的分布)根本不是 i.i.d.。它们来自两个不同的时间切片、不同的攻击者群体、不同的用户构成、不同的威胁模型。
> The test set was a snapshot. Production was a movie. We measured a photo and expected it to predict the plot.
这正是 i.i.d. 假设崩溃的方式。教科书不会告诉你 i.i.d. 是错的,教科书只会假设 i.i.d. 是对的。但生产环境从来不在教科书的假设里。
1.3.2 三种分布偏移 / The Three Kinds of Distribution Shift
学界把"训练分布 ≠ 生产分布"的现象统一称为 distribution shift(分布偏移)。但它有三种本质不同的形态,混淆它们是大多数 AI 项目灾难的根源。
第一种:Covariate Shift(协变量偏移) 输入 $X$ 的分布变了,但条件分布 $P(Y \mid X)$ 没变。
$$\forall x: \quad P_{\text{train}}(Y \mid X = x) \approx P_{\text{prod}}(Y \mid X = x)$$
$$P_{\text{train}}(X) \neq P_{\text{prod}}(X)$$
陈思远的反欺诈模型正是栽在了这里。攻击者使用的合成身份在特征空间中落在了训练集几乎从未覆盖的区域("covariate" = 输入特征)。模型在这些区域内的预测完全是外推(extrapolation),而外推在外监督学习中没有理论保证。
第二种:Concept Drift(概念漂移) 输入 $X$ 的分布可能没变,但条件分布 $P(Y \mid X)$ 变了。
$$\forall x: \quad P_{\text{train}}(Y \mid X = x) \neq P_{\text{prod}}(Y \mid X = x)$$
典型场景:用户的偏好变了、欺诈的定义变了、合规的边界变了。例如新冠疫情期间,"正常"的消费行为模式发生了剧变 —— 居家办公、外卖激增、旅游归零。一个用 2019 年数据训练的模型在 2020 年的生产环境中可能依然 AUC 很高,但它的"高"已经毫无意义,因为它在度量错误的概念。
第三种:Label Shift(标签偏移) 输出的类别先验变了。
$$P_{\text{train}}(Y) \neq P_{\text{prod}}(Y)$$
而条件分布 $P(X \mid Y)$ 没变。
最经典的例子是医疗诊断:训练时罕见病占比 1%,生产时筛查人群变了,罕见病占比变成 5%。这时模型在罕见病上的召回率会被严重稀释,整体 AUC 看起来变化不大,但对真正重要的少数类而言,模型可能完全失效。
陈思远的模型同时遭遇了三种偏移:
- Covariate shift:合成身份的特征空间是新区域
- Concept drift:犯罪团伙的"合法化伪装"改变了 $P(\text{fraud} \mid \text{behavior})$
- Label shift:营销活动带来新用户后,欺诈的 base rate 从 0.7% 升到了 1.4%
任何一个都会让测试集的 0.992 失去意义。三个同时发生,等于模型的预测与现实完全脱钩。
1.3.3 幸存者偏差:测试集本身就是有偏的 / Survivorship Bias: The Test Set Itself Is Biased
除了分布偏移,还有一层更隐蔽的偏差 —— 测试集本身的幸存者偏差。
陈思远的团队之所以能在测试集上拿到 0.992,有一个他们从未说出口的原因:他们选的那个测试集,本来就是最容易得到高分的。
具体来说:
1. 标注者偏差:测试集的"标签"是由反欺诈运营团队人工标注的。但运营团队只能在已经被前一代模型标记为可疑的交易中做最终确认。这意味着,测试集中真正困难的、"以假乱真"的样本,可能在标注阶段就被前一代模型过滤掉了,能进入测试集的反而是相对清晰的样本。这是一种 filter-induced bias。 2. 时间窗口偏差:测试集取自过去 18 个月。但过去 18 个月的"已确认欺诈"是已经成功作案、并且被发现的欺诈。还有大量未被发现的欺诈、未遂的欺诈、已发生但被错误归类的欺诈 —— 这些样本根本不在测试集中。模型在测试集上表现的"好",可能只是因为它识别的是已经被识别的欺诈。这是经典的 survivorship bias。 3. 定义漂移:测试集中"欺诈"的定义是 2018 年的定义。但合规团队在 2019 年 8 月悄悄更新了《欺诈判定操作指引 v3.2》,引入了"账户接管(account takeover)"作为新的欺诈子类。训练数据和测试数据都没有这个新类的标签,但生产数据中有。模型在测试集上学到的是旧世界的规则,但被要求在新世界里运行。
幸存者偏差最残酷的地方在于:测试集的纯净度本身就是它最大的缺陷。 我们精心清洗、严格筛选、严格匹配训练分布的测试集,恰恰是因为它和训练集长得太像,所以模型才能在它上面取得高分。但这个高分不是模型智能的证据,而是测试集无聊的证据。
> A perfect test set is a boring test set. And a boring test set cannot tell you anything about production.
---
1.4 "好"的三种定义:统计的、感知的、商业的 / Three Definitions of "Good"
陈思远的团队在白板前站了 4 个小时之后,Carlos 问了第二个问题:
"陈,假设我们接下来要重做这个模型。你告诉我,什么样的模型是好模型?"
陈思远张了张嘴,发现自己答不上来。
这个问题比看起来要难得多。因为"好"这个字在不同的人嘴里,意味着完全不同的东西:
1.4.1 统计意义的好:Statistical Goodness
对数据科学家而言,"好模型"几乎总是指统计意义上的好:在某个测试集上,某项指标达到了某个阈值。
- AUC > 0.99 ✓
- F1 > 0.95 ✓
- Recall @ 1% FPR > 90% ✓
这种定义的好处是可计算、可复现、可对比。两个数据科学家之间可以用一个数字决出胜负。它的代价是脱离语境:它不关心这个 0.99 是怎么来的,不关心它能不能迁移,不关心它对用户意味着什么。
陈思远在事故复盘会上承认,他过去 5 年的整个职业生涯几乎都在用这一定义。
1.4.2 用户感知的好:User-Perceived Goodness
但对最终用户而言,"好模型"是完全不同的东西。
一个普通客户不会去查 AUC。他会问:
- 我的交易是不是被无端拒绝?(false positive 的代价由用户承担)
- 我是不是需要反复做人脸验证?(latency 和 friction)
- 客服告诉我"系统怀疑我有风险",我是不是要解释半天?(用户感知到的"被怀疑")
- 我被错误标记后,信用分是不是降了?(下游连锁伤害)
在反欺诈这个场景里,一次误判对客户的伤害往往大于一次漏判对银行的伤害,因为客户是被冤枉的、没有申诉渠道、且要承担举证责任的人。这种伤害不会出现在 AUC 曲线里,但会出现在 NPS(Net Promoter Score)里、出现在 churn rate 里、出现在社交媒体的口碑里。
> *Statistical goodness is invisible to users. User-perceived goodness is invisible to data scientists. Both are equally real.*
1.4.3 商业意义上的好:Business Goodness
对 CEO 和 CFO 而言,"好模型"的最终定义只有一个:净商业价值。
- 模型减少了多少欺诈损失?
- 模型增加了多少客户流失?(这是隐性成本)
- 模型节省了多少人工审核成本?
- 模型引入了多少监管风险?
- 模型是否创造了新的交叉销售机会?(一个"好"的反欺诈模型可能同时是一个"好"的客户分层模型)
用公式表示,对一个反欺诈系统而言:
$$\text{Business Value} = \underbrace{L_{\text{fraud prevented}}}_{\text{TP savings}} - \underbrace{L_{\text{fraud missed}}}_{\text{FN cost}} - \underbrace{L_{\text{customer churn}}}_{\text{FP cost}} - \underbrace{L_{\text{ops cost}}}_{\text{review cost}} - \underbrace{L_{\text{regulatory}}}_{\text{compliance risk}}$$
注意:没有一项是 AUC。AUC 是一个 surrogate metric(替代指标),它是商业价值的一个代理,但绝不等同于商业价值。
1.4.4 三者的冲突:The Trilemma
这三类"好"之间存在系统性的冲突,而不是简单的优先级问题。
冲突 1:统计 vs 用户
要最大化 AUC,往往需要更复杂的特征、更深的模型、更多的推理时间。这会增加延迟、增加误判率、增加用户摩擦。一个 AUC 0.995 的模型可能比 AUC 0.985 的模型让用户更痛苦。
冲突 2:用户 vs 商业
对用户最友好的模型是"几乎不拒绝任何交易"的模型。但这种模型的召回率会暴跌,欺诈损失飙升,商业价值归零。
冲突 3:商业 vs 统计
商业价值最大的模型未必是 AUC 最高的模型。例如,一个保守的模型 AUC 0.97,但误判率极低、运营成本极低、客户零投诉,长期商业价值可能远超 AUC 0.995 但误判率 3% 的"炫技"模型。