🏠 总目录📚 本教程 14 · 辛普森悖论与七个陷阱 ← →
📑 本页目录(点开跳转)

14 · 辛普森悖论与七个陷阱

⏱ 34 分钟 | ⭐ 每一个都能让你得出完全相反的结论


🎯 一句话

数据不会说谎,但它会让你自己骗自己。 这一章是七个「结论看起来完全合理、但完全错误」的模式 —— 认出它们,比学任何新方法都值。

旧算法新算法9%2%7.8%3.4%老用户 ↑新用户 ↑总体 ↓两个子群都在涨,合起来却在跌
两条绿线是两个子群,都在上升;橙线是总体,却在下降。⭐ 原因不在数字本身,在流量分配:新算法 83% 的样本落在了天然难转化的新用户上。

🔄 陷阱一:辛普森悖论

每个子群里 A 都比 B 好,合起来却是 B 比 A 好。

一个实算的例子(下面的数字是跑出来的,不是编的):

新算法 vs 旧算法,看转化率 分人群看:

人群 旧算法 新算法 谁更好
老用户 900/10000 = 9.00% 190/2000 = 9.50% 新 ✅
新用户 40/2000 = 2.00% 220/10000 = 2.20% 新 ✅
总体 940/12000 = 7.83% 410/12000 = 3.42% 旧 ⭐💀

💀 新算法在两个人群里都更好,总体却差了一倍多。

新算法在【两个人群里都更好】,总体却差了一倍多

为什么会这样:

关键信息

老用户天然转化率高(9%),新用户天然低(2%)
流量分配:
· 老用户里,新算法只拿到 17% 的流量
· 新用户里,新算法拿到 83% 的流量 ⭐
新算法的样本大量集中在"天然难转化"的新用户上
总体平均被拖下来

🔑 根因:分组变量(新老用户)同时影响「分到哪个算法」和「结果」 —— 它是个混杂变量(第 13 章)。

⭐ 到底该信哪个?

结果对照

❓ 分人群的结论 vs 总体的结论,哪个对?
⭐ 答案取决于【为什么流量分配不均】:
情况 A:流量分配是【随机】的,只是碰巧不均
信【分人群】(要做分层加权)
情况 B:流量分配是【由某个机制决定】的
(比如新算法就是专门给新用户上的)
要问清楚你到底想回答什么问题

💡 这也是为什么 A/B 实验要随机分流 + 要查 SRM(第 12 章): 随机分流从源头上避免了辛普森悖论。 一旦出现 SRM,就要警惕这类反转。

🛠️ 二十行代码:复现它,然后修好它

import pandas as pd

df = pd.DataFrame([
    ("老用户", "旧", 900, 10000), ("老用户", "新", 190,  2000),
    ("新用户", "旧",  40,  2000), ("新用户", "新", 220, 10000),
], columns=["人群", "算法", "转化", "曝光"])
df["转化率"] = df["转化"] / df["曝光"]

print(df.pivot(index="人群", columns="算法", values="转化率"))
#            新      旧
# 新用户   0.0220  0.0200      ← 新算法赢
# 老用户   0.0950  0.0900      ← 新算法赢

g = df.groupby("算法")[["转化", "曝光"]].sum()
print(g["转化"] / g["曝光"])
# 新  0.0342      ← 反过来了 💀
# 旧  0.0783

# ⭐ 修法:分层加权(也叫标准化)—— 用【同一套人群权重】去加权两个算法
w = df.groupby("人群")["曝光"].sum() / df["曝光"].sum()     # 各人群在总体中的占比
rate = df.pivot(index="人群", columns="算法", values="转化率")
print((rate.T * w).T.sum())
# 新  0.0585      ✅ 和分人群的结论一致了
# 旧  0.0550

⭐ 「分层加权」这四个字是这一章唯一的技术解法: 悖论的根源是两个算法各自的人群构成不同, 所以只要强制它们用同一套人群权重,反转就消失了。

⚠️ 但要注意:这只在「流量分配本可以是随机的」时才有意义。 如果新算法根本就是为新用户设计的,那么加权后的数字回答的是 「假如把它推给现有人群构成会怎样」——是不是你要的问题,要自己想清楚。


📉 陷阱二:幸存者偏差

关键信息

「我们的付费用户满意度 4.8 分!」
不满意的早就退款走了,根本不在样本里
「模型上线后用户投诉少了」
可能是用户放弃投诉了

🔗 第 2 章的评估幸存者偏差是同一个东西的另一种形态: 你的样本是被某个过程筛选过的。

💀 它在建模里的重灾区:只能用「通过的人」训练

操作步骤

风控/信贷模型的死结:
被拒的申请人【没有"最后还没还款"这个标签】
你只能用通过审批的那批人训练
模型学到的是「在已通过的人里,谁会违约」
但它上线后要判断的是【全部申请人】 💀
一个典型的量级:
· 通过率 30% 的场景,训练样本只覆盖了申请人分布的 30%
· 在这 30% 上离线 AUC 0.78
· 换成"全部申请人 + 事后补到的真实表现"重新评估→只有 0.66 ⭐
掉的那 12 个点,全在「明显该拒、但模型从没见过」的那批人上

三个对策(按有效性排):

对策 说明 代价
随机放行一小撮 ⭐ 每天随机通过 0.5–2% 本该拒的申请 真金白银的坏账,但它是唯一的无偏样本
用外部数据补标签 征信、联合建模方的后续表现 覆盖不全、合规约束
把「被拒」当有信息的删失建模 而不是直接丢掉这些行 依赖假设,效果不如前两个

⭐ 注意第一条和第 7 章的随机流量是同一件事: 反馈闭环系统里,"花钱买一小块无偏数据"往往是最划算的一笔投资 —— 因为没有它,你连"模型在变好还是变坏"都无法判断。


🎢 陷阱三:均值回归

结果对照

现象:给「表现最差的 10% 用户」推送召回消息
下个月他们的活跃度明显上升
结论:推送有效!❌
真相:
「上个月表现最差」里有一部分是【偶然的低谷】
即使什么都不做,他们下个月也会回到正常水平

⭐ 识别方法:看对照组。 如果你按"最差 10%"筛人,必须在这批人里再随机分成实验组和对照组 —— 只和"他们自己上个月"比,一定会高估效果。

💀 这个陷阱在「挽留」「召回」「唤醒」类项目里几乎必然出现。

一个能自己心算的数字:

算一算

假设某指标 = 真实水平 + 噪声,相邻两期的相关系数 ρ = 0.6

挑出「第一期最低的 10%」这批人,

他们第二期的平均值会自动回升 —— 回升幅度约等于

【挑选时偏离均值的 (1 − ρ) 倍】= 40% ⭐

→ 你什么都不做,也能报告一个"活跃度提升 40%"的成功项目

⭐ 最阴险的一点:样本量越大,这个假效果的 p 值越小。 很多人以为「p < 0.001 总不会错了吧」—— p 值只否定「这是随机波动」,它从不证明「这是你的干预造成的」。 均值回归造成的差异是系统性的,不是随机的,所以它一定显著。


⏱️ 陷阱四:前视偏差(用了当时拿不到的信息)

关键信息

回测策略时用了「当天收盘价」来做当天早上的决策
回测收益爆表,实盘亏损

🔗 这是第 4 章特征穿越在分析场景的形态。 凡是「回测/复盘」类分析,都要问一句:这个数字在决策时点真的存在吗?


📊 陷阱五:只看相对值 / 只看绝对值

关键信息

「转化率提升 50%!」
从 0.02% 涨到 0.03%,实际多了 3 个订单 😐
「多了 500 个订单!」
总量 50 万,相对提升 0.1%,在噪声范围内 😐
⭐ 规则:永远同时报【相对值 + 绝对值 + 置信区间】

🧮 陷阱六:比率的陷阱

① 比率的平均 ≠ 平均的比率

算一算

两个城市的 CTR:10% 和 20%

❌ 平均 CTR = 15%

✅ 要按曝光量加权

如果城市 A 有 100 万曝光(10%),城市 B 有 1 万(20%)

→ 真实 CTR ≈ 10.1%,不是 15%

② 分母变化伪装成分子变化

信息关系

CTR 跌了→可能是点击少了,也可能是曝光暴涨
⭐ 看比率时永远同时看分子和分母

🔗 第 11 章排查第一步就查这条。


🎯 陷阱七:指标被优化后就失效了(古德哈特定律)

「当一个指标成为目标,它就不再是一个好指标。」

关键信息

用「停留时长」当目标
模型学会推容易让人反复刷但没价值的内容
时长涨了,用户满意度和留存反而降了
用「点击率」当目标
标题党

三个对策:

对策 说明
加护栏指标 ⭐ 主指标涨的同时,这些不能掉(留存、投诉率、多样性)
多目标 同时优化几个互相制衡的目标
定期换/校准指标 指标用久了会被"学会",要定期回头验证它还代表价值吗

🔗 强化学习第 1 章的奖励黑客是同一个现象的 RL 版本: 模型会忠实地优化你写下的那个东西,而不是你想要的那个东西。

💀 一个不涉及模型、但更能说明问题的案例

对照

指标:客服「一次解决率」(FCR)—— 一通电话内解决问题的比例

动作:把它定成团队 KPI,要求 ≥ 85%

人(和模型一样)很快学会了怎么优化它:

· 没解决的问题【不建工单】,让用户过会儿再打一次

· 第二通电话是一张全新的单,第一通就"解决"了 💀

结果:

· FCR 从 71% 涨到 89% ✅ KPI 达成

· 同期投诉量涨了 34% 💀

· 三个月后才有人发现 ——

因为【没有任何一张图把 FCR 和投诉量放在一起】⭐

⭐ 这个案例给出了古德哈特定律真正的解药: 不是"找一个更好的指标"(不存在),而是—— 把主指标和护栏指标画在同一张图上、同一个看板上、同一个周报里。

💡 判断标准很朴素:如果一个指标涨了,没有任何机制会让你顺便看到代价, 那它迟早会被优化到失效。这和模型无关,是激励结构的问题。


📋 一张自查表

看到任何一个「结论」时,问这七句:

逐项核对

  • 分人群看还成立吗? (辛普森)⭐

  • 样本是怎么来的、谁被筛掉了?(幸存者)

  • 有对照组吗? (均值回归)⭐

  • 这些数据在决策时点存在吗? (前视)

  • 相对值和绝对值都看了吗?

  • 分母变了吗? (比率)⭐

  • 这个指标被优化后还代表价值吗?(古德哈特)⭐

⭐ 三个带星的是最高频的。如果只记三条,记它们。


⚠️ 一张坑表(自查表的「怎么修」版)

坑 后果 怎么修
只看总体,不分人群 ⭐ 辛普森反转:新方案两个人群都赢,总体却输 默认按 3–5 个维度出分组表
分了人群,但各用各的权重 还是不可比,只是错得更隐蔽 分层加权:用同一套人群权重 ⭐
挑极端组做干预,和它自己上期比 ⭐ 均值回归伪装成效果,ρ=0.6 时白送 40% 的"提升" 在极端组内部再随机分对照组
拿「显著」当因果的证据 💀 大样本下伪效应必然显著 p 值只否定随机,不证明因果
只用通过筛选的样本训练/评估 幸存者偏差:离线 0.78 → 全量 0.66 花钱买一小块随机放行样本 ⭐
回测用了当时不存在的数据 回测收益爆表,实盘亏损 每个特征标注「可用时间」,回测按它裁剪
只报相对提升 「提升 50%」实际是 3 个订单 相对 + 绝对 + 置信区间三件套
KPI 只考核单一指标 💀 古德哈特:指标涨、业务跌,还要三个月才发现 主指标和护栏指标画在同一张图上 ⭐
代理指标定下来就不再验证 关系漂移后,你在优化一个不再代表价值的东西 定期重验(第 15 章)

🔗 和站内其他章的关系

相关的地方 和这一章的关系
第 2 章幸存者偏差 陷阱二
第 4 章特征穿越 陷阱四
第 8 章分人群告警 陷阱一的监控形态
第 11 章看分母 陷阱六
第 12 章 SRM SRM 是辛普森的预警信号
强化学习 01奖励黑客 陷阱七的 RL 版

✅ 检查点

  1. 用那个实算例子说明辛普森悖论。为什么会发生?
  2. 辛普森悖论出现时,该信分人群还是总体?技术上怎么修?修完的数字是多少?
  3. 随机分流和 SRM 检查与辛普森悖论是什么关系?
  4. 风控模型为什么必然有幸存者偏差?那个 AUC 的数字是多少?三个对策里哪个最有效、代价是什么?
  5. 均值回归怎么骗人?ρ=0.6 时白送多大的"提升"?为什么 p 值保护不了你?
  6. 比率的两个陷阱是什么?
  7. 古德哈特定律说什么?用那个 FCR 的案例说明。真正的解药是什么?
  8. 自查表里最高频的三条是哪三条?
👀 答案
  1. 新算法在老用户(9.50% vs 9.00%)和新用户(2.20% vs 2.00%)两个人群都更好,总体却是 3.42% vs 7.83%,旧的赢。因为老用户天然转化率高(9%)、新用户低(2%),而新算法 83% 的流量落在新用户上,被拖下来了。
  2. 取决于流量分配不均的原因:如果是随机的、只是碰巧不均 → 信分人群;如果是由某个机制决定的 → 要先问清你到底想回答什么问题。技术解法是分层加权(标准化):用同一套人群权重去加权两个算法。修完是 新 0.0585 vs 旧 0.0550,新算法赢,和分人群结论一致。
  3. 随机分流从源头避免了辛普森悖论(分组变量不再影响分到哪一组);SRM 一旦出现就要警惕这类反转——它说明分流不随机了。
  4. 因为被拒的申请人没有"最后还没还款"这个标签,只能用通过审批的人训练,而上线后要判断的是全部申请人。数字:通过率 30% 的场景,离线 AUC 0.78,换成全部申请人重新评估只有 0.66,掉的 12 个点全在「明显该拒、模型从没见过」的人身上。最有效的对策是每天随机放行 0.5–2% 本该拒的申请,代价是真金白银的坏账——但它是唯一的无偏样本。
  5. 挑"表现最差的 10%"做干预,他们下月自然会回升(偶然低谷),会被误认为干预有效。ρ=0.6 时回升幅度约等于挑选时偏离均值的 40%——什么都不做也能报一个"提升 40%"。识别:必须在这批人里再随机分实验组和对照组。p 值保护不了你,因为均值回归造成的差异是系统性的、一定显著;p 值只否定"这是随机波动",从不证明"这是你的干预造成的",而且样本越大 p 越小。在挽留/召回/唤醒类项目里几乎必然出现。
  6. ①比率的平均不等于平均的比率(要按分母加权)②分母变化伪装成分子变化(CTR 跌可能是曝光暴涨)。
  7. 当一个指标成为目标,它就不再是好指标。案例:把客服「一次解决率 FCR」定成 KPI,客服学会把没解决的问题不建工单、让用户再打一次——第二通是新单,第一通就"解决"了;FCR 从 71% 涨到 89%,同期投诉量涨 34%,三个月后才被发现,因为没有任何一张图把 FCR 和投诉量放在一起。真正的解药不是"找一个更好的指标"(不存在),而是把主指标和护栏指标画在同一张图/看板/周报里——如果一个指标涨了却没有任何机制让你顺便看到代价,它迟早会被优化到失效。
  8. 辛普森(分人群看还成立吗)、均值回归(有对照组吗)、分母变了吗。(外加古德哈特也是高频。)

🛑 可以停在这里

⚡ 走神救援

⭐ 辛普森悖论:新算法在老用户和新用户两个人群都赢,总体却大输——因为老用户天然转化高,而新算法的流量绝大部分落在新用户上。

根因是分组变量同时影响「分到哪组」和「结果」(混杂变量)。该信哪个取决于流量为什么不均;随机分流从源头避免它,SRM 是它的预警信号。技术解法是分层加权:用同一套人群权重加权两边,结论就和分人群一致了。

⭐ 均值回归:挑「最差 10%」做召回,他们下个月自然回升,什么都不做也能报一个成功项目。唯一可靠的识别办法是在这批人里再随机分一个对照组。 而且样本越大 p 值越小——均值回归是系统性的,p 值只否定「随机波动」,从不证明「是你干的」。

古德哈特:当指标成为目标,它就不再是好指标。解药不是找更好的指标(不存在),而是把主指标和护栏指标画在同一张图上。

💀 两个案例各记一句:风控里被拒的人没有标签,只拿通过的人训练,换成全部申请人评估会掉一大截,最有效的解法是每天随机放行一点点;客服把「一次解决率」定成 KPI 后,学会了不建工单让用户再打一次,FCR 涨了、投诉同期也涨了,三个月没人发现。

⭐ 自查表最高频的三条:分人群还成立吗、有对照组吗、分母变了吗。

下一节 👉 15-长期效应与代理指标.md

打卡记录保存在你的浏览器里,首页能看到总进度