📈 第11章 误差
📄 一句话概括

那位员工点数 108,比模型见过的最高分 95 还高。计算器照样吐了一个数:10.40%。 这个数不是预测,是把直线往右画长了一点。它的名字叫外插,它没有任何数据支撑。 外插有三种样子:超上限、低于下限、关系本身变了。第三种最难发现,因为分数还在范围内。

📝 本章和前面几章的关系

上一篇停在「先查那个 108 分」。这一篇把它查清楚,并给出对待这类客户的三句话。 第 10 章 10.4 已经提过一次外插。这里要讲的是它在现实里怎么伤人。

一、25% 从哪来

那位员工的 108 分不是绩效分,是公司把外部获奖、专利、跨部门支援折算成点数之后的总和。 这个折算规则是去年新加的,模型训练用的 60 条记录里一条都没有这种折算。 他按计算器一算:108 分对应 10.40%。他觉得自己该拿 25%,于是按 25% 去谈。

谈崩了。他拿 10.40% 当「公司自己算出来的数」来质问,公司拿不出反驳。 麻烦的根源不是他要 25%,是那个 10.40% 看上去像公司官方口径。

二、他不在模型范围内

这 60 条记录里,分数最低 40、最高 95。108 落在外面。 落在外面意味着:这个区间里没有任何一个数据点约束过这条线。 方程照样给数,因为直线是无限长的。但那个数只反映「直线的延长方向」,不反映「现实」。

点数 方程给的值 这是哪种用法
40 4.29% 内插
95 9.23% 内插
100 9.68% 外插
108 10.40% 外插
130 12.37% 外插

外插不是算错,是问错了问题:模型只在它见过的地方有发言权。

三、外插的三种样子

样子 表现 危险在哪
超出上限 108 分给出 10.40% 数看着合理,没人会拦
低于下限 20 分给出 2.50% 同上,越合理越危险
关系变了 升到管理层后斜率整个换掉 范围以内也可能失效

前两种是坐标越界,一眼能查出来:拿 x 跟数据的最大最小值比一下就知道。 第三种是关系越界。分数还在 40 到 95 里面,但这个人已经不属于这批人了——比如他升成了主管。 第三种最难发现,因为所有自查都能通过。它靠的不是范围检查,是对业务的了解。

四、怎么对待这种客户

第一句:这个数不能用来谈,因为它落在模型没见过的地方。 第二句:能谈的是这个——108 分的人,公司历史上是怎么定的?通常有特批流程。 第三句:如果希望模型覆盖这一段,得补数据,不是调参数。

三句话的顺序有讲究:先否掉错答案,再给替代路径,最后说清成本。 只说「不能算」,客户会自己去找别的算法,然后拿着更离谱的数回来。

五、只解决了部分问题

外插这条路堵住了,可「我该拿多少」这个问题还在。 堵住一个错答案,不等于给出一个对答案。这是咨询工作里最容易被忽略的一半。 而且客户会很自然地问:那你们这个模型,到底能信几分?

要回答这句,得先把这个模型的误差量出来。下一篇开始。

六、动手 Demo:外插法惹的祸:25% 是怎么来的

把 40、95 与 100、108、130 放在一起,逐个标出是内插还是外插。 顺便算一下:外插给出的 10.40% 和员工要求的 25%,差了多少倍。

S = [20261102]

def rnd():
    S[0] = (S[0] * 1103515245 + 12345) % 2147483648
    return S[0] / 2147483648.0

DATA = []
for i in range(60):
    x = 40 + int(round(i * 55 / 59.0))
    y = 1.2 + 0.085 * x + (rnd() - 0.5) * 3.2
    DATA.append((x, round(y, 1)))

XS = [d[0] for d in DATA]
YS = [d[1] for d in DATA]
n = len(XS)
mx = sum(XS) / float(n)
my = sum(YS) / float(n)
m = sum((x - mx) * (y - my) for x, y in zip(XS, YS)) / sum((x - mx) ** 2 for x in XS)
b = my - m * mx
lo, hi = min(XS), max(XS)

for q in (20, 40, 95, 100, 108, 130):
    tag = "内插" if lo <= q <= hi else "外插"
    print("%3d 分  预测 %5.2f%%  %s" % (q, b + m * q, tag))

print()
print("数据范围 %d ~ %d,108 在外面的距离是 %d 分" % (lo, hi, 108 - hi))
print("外插给的 %.2f%%,他要的 25%%,差了 %.2f 倍" % (b + m * 108, 25.0 / (b + m * 108)))

实跑输出:

--------------------------------------------------------------------
外插法惹的祸:25% 是怎么来的
--------------------------------------------------------------------

  ① 25% 从哪来
  --------------------------------------------------------------------
  那位员工的 108 分不是绩效分,是公司把外部获奖、专利、跨部门支援折算成点数之后的总和。
  他按计算器一算:108 分对应 10.40%。
  他觉得自己该拿 25%,于是按 25% 去谈。谈崩了,然后来找我们。

  ② 他不在模型范围内
  --------------------------------------------------------------------
  这 60 条记录里,分数最低 40、最高 95。108 落在外面。

| 点数 | 方程给的值 | 这是哪种用法 |
|:---:|---:|---|
| 40 | 4.29% | 内插 |
| 95 | 9.23% | 内插 |
| 100 | 9.68% | 外插 |
| 108 | 10.40% | 外插 |
| 130 | 12.37% | 外插 |

  三行外插都是「把直线往两头画长」画出来的,一个数据点都没有支撑它们。
  ! 外插不是算错,是问错了问题:模型只在它见过的地方有发言权。

  ③ 外插的三种样子
  --------------------------------------------------------------------

| 样子 | 表现 | 危险在哪 |
|---|---|---|
| 超出上限 | 108 分算出一个偏高的数 | 数看着合理,没人会拦 |
| 低于下限 | 20 分算出 2.50% | 同上,越合理越危险 |
| 关系变了 | 升到管理层后斜率整个换掉 | 范围以内也可能失效 |

  前两种是坐标越界,第三种是关系本身越界。第三种最难发现,因为分数还在范围内。

  ④ 怎么对待这种客户
  --------------------------------------------------------------------
  第一句:这个数不能用来谈,因为它落在模型没见过的地方。
  第二句:能谈的是这个——108 分的人,公司历史上怎么定的?(通常有特批流程)
  第三句:如果要模型覆盖这一段,得补数据,不是补参数。
  ! 拒绝一个外插值,必须同时给一条替代路径。只说「不能算」,客户会自己找别的算法。

  ⑤ 只解决了部分问题
  --------------------------------------------------------------------
  外插这条堵住了,可「我该拿多少」这个问题还在。
  堵住一个错答案,不等于给出一个对答案。这是咨询里最容易被忽略的一半。
  要给出对答案,得先知道这个模型本身有多准。下一节开始量误差。

108 只超出上限 13 分,看着不远;但 13 分对应 1.17 个百分点,正好够吵一架。 「不远」不等于「有依据」。 外插给的 10.40% 和 25% 差了 2.4 倍——这个差不是模型算错,是两边说的根本不是同一件事。

30 秒实验

  1. 如果数据里补上 20 条 100 到 130 分的记录,那条线的斜率还会是 0.0898 吗?为什么?
  2. 「升成主管的人斜率变了」这种情况,光靠范围检查能发现吗?要靠什么发现?
  3. 想一想:为什么外插给出一个「合理」的数,比给出一个荒唐的数更危险?

常见误区

  1. 只看 x 是否为正数就放心用:范围检查比的是数据的最小最大值,不是零。
  2. 相信「直线是无限的」:直线的数学定义是无限的,模型的可信范围不是。
  3. 只堵不给路:拒绝一个外插值却不给替代方案,客户会去找更差的算法。
  4. 以为范围以内就一定安全:关系本身可能已经变了,这种越界查不出来。
自测三问(点开对答案) 1. 108 分算出的 10.40% 为什么不能拿去谈? —— 因为 108 落在数据范围 40~95 之外,这个区间没有任何数据点约束过那条线。 它只是直线延长,不是预测。 2. 外插的三种样子里,哪一种最难发现? —— 关系本身变了的那种。分数还在范围内,所有位置检查都通过,只能靠对业务的理解发现。 3. 拒绝一个外插值时要同时给什么? —— 一条替代路径:查历史特批、补数据重建模型。只说「不能算」,客户会自己找别的算法。

外插只是把错答案挡住。要给出对答案,得先把模型的误差量出来——那就是机会误差。

相关笔记