🧠 第九章 模型评估和优化
📄 一句话概括

8 个样本加 1 个异常点(真实 100、预测 40),四个误差指标的涨幅是:MSE 743.3 倍、 RMSE 27.3 倍、MAE 10.2 倍、MAPE 2.0 倍。同一个异常值,四个指标给出四种反应。

📝 本节和前面几节的关系

上一节讲分类的指标。这一节换到回归——预测的是连续数值,没有「对错」只有「差多少」。 差多少怎么量,就是这一节的事。

一、四个误差指标

MAE(平均绝对误差):把每条的误差取绝对值,再平均。单位与原数据一致。 MSE(均方误差):把误差平方,再平均。单位是原数据的平方,不好解释。 RMSE(均方根误差):MSE 开根号。单位回到原数据,所以最常用。 MAPE(平均绝对百分比误差):每条误差除以真实值,取绝对值,再平均成百分比。 四个指标测的是同一件事,但「怎么算误差」这一步不一样,结果就分道扬镳了。

二、异常值一来,四个指标分家

Demo 用 8 个样本,误差在 0.2 到 0.9 之间,很干净。 这时 MAE 0.7125、RMSE 0.7340,两者几乎一样。 加一个异常点(真实 100、预测 40,误差 60)之后:MAE 7.3、RMSE 20.01、MSE 400.48、 MAPE 12.19。 换算成倍数:MSE 涨 743.3 倍、RMSE 涨 27.3 倍、MAE 涨 10.2 倍、MAPE 只涨 2.0 倍。 一条线就分开了:平方类指标(MSE、RMSE)被异常值主导,绝对值类(MAE)温和,相对类(MAPE)最钝。

三、为什么 MSE 涨这么夸张

误差 60 平方之后是 3600。原来 8 个点的平方误差加起来才 4.31。 一个点就让总和变成 3604,平均值从 0.54 跳到 400。 这就是平方的作用:它对大误差的惩罚是二次的。误差翻十倍,平方项翻一百倍。 RMSE 是 MSE 开根号,所以涨幅被压了一半(743 变成 27)。 但它仍然被那一个点主导——20.01 这个数已经完全不反映另外 8 个点的表现。 MAE 只涨 10.2 倍,因为 60 摊到 9 个样本上,每条平均多 6.67。线性增长,符合直觉。 MAPE 涨得最少,因为那个异常点的真实值是 100,相对误差只有 60%; 而原来那 8 个点的真实值只有 9 到 14,误差 0.6 就是 5% 到 7% 的相对误差。 它在相对尺度上反而不算离谱。

四、怎么选:看你怕什么

怕大错就用 RMSE。 它在优化时会强烈惩罚大偏差,适合「错一次代价很大」的场景,比如金融预测、库存预估。 数据脏、有离群点就用 MAE。它对异常值稳健,反映的是「典型表现」。 代价是它对大误差不够敏感,可能放任几次严重偏差。 量纲跨度大(房价有几十万也有几十万,销量有个位数也有上百万)用 MAPE。 但它有两个坑:真实值接近 0 时会爆炸,而且对低估和高估不对称。 绝对不要只报一个。 三个一起报,读者才能判断你的模型是「普遍差一点」还是「大部分很好但偶尔很糟」。 这两种情况对业务的影响完全不同。

五、动手 Demo:一个异常值:MSE 涨 743 倍,MAE 只涨 10 倍

用 8 个真实值和对应预测值(误差都在 1 以内),算 MAE、MSE、RMSE、MAPE; 再加一个异常点(真实 100、预测 40),重算四个指标,看各自涨了多少倍。

e = yt - yp
mae = float(np.abs(e).mean())
mse = float((e * e).mean())
rmse = float(np.sqrt(mse))
mape = float((np.abs(e) / yt).mean() * 100)

实跑输出:

--------------------------------------------------------------------
误差指标:一个异常值能把 RMSE 抬多高
--------------------------------------------------------------------
  样本数                   8 个,真实值在 9 到 14 之间
  指标                     MAE、MSE、RMSE、MAPE 四个

  指标        8 个样本   加一个异常点   涨了几倍
  ---------------------------------------------
  MAE           0.7125         7.3000    10.2 倍
  MSE           0.5388       400.4789   743.3 倍
  RMSE          0.7340        20.0120    27.3 倍
  MAPE(%)     6.2130        12.1893     2.0 倍

  加进去的那个点           真实 100,预测 40,误差 60
  原来最大的误差           0.9

  这一组数把四个指标的脾气分得很清楚,按涨幅从大到小排:
  **MSE**(743.3 倍)涨得最凶,因为它把误差平方了——60 的平方是 3600,一个点就能把整批的平均值拉到天上。
  **RMSE**(27.3 倍)是 MSE 开根号,涨幅介于中间,但量纲和原数据一致,所以最常用。
  **MAE**(10.2 倍)只涨了一档。它对所有误差一视同仁,一个 60 摊到 9 个样本里,每个样本平均多 6.7。
  **MAPE**(2.0 倍)涨得最少,因为它是相对误差——那个异常点的真实值是 100,相对误差只有 60%,而原来那 8 个点的相对误差也有 3% 到 10%。
  注意「涨得最少」不等于「更好」。MAPE 对异常值钝,代价是它对大误差也不敏感,优化时模型不会特别怕犯大错。

  选哪个指标,取决于你想让模型「在意什么」:
  在意大误差被惩罚 → RMSE。它在优化时会把模型往「别犯大错」的方向推。
  在意典型误差、不想被个别点带偏 → MAE。它对异常值稳健。
  在意相对偏差、量纲跨度大 → MAPE。但真实值接近 0 时它会炸,而且它对「低估」和「高估」不对称。
  没有哪个更好。报指标时最好三个一起报,只报一个容易被挑刺。

八个点的 MAE 0.7125 和 RMSE 0.7340 几乎相等。这说明误差分布很均匀,没有大的偏差。 加异常值之前,选哪个指标都差不多。 加了那个点之后 RMSE 是 20.01,MAE 是 7.3。 差 2.7 倍——这个差距就是「有没有被异常值带偏」的量化。 MSE 400.48 这个数已经没法解释(单位是原数据的平方),所以它只用来做优化目标,不用来汇报。 汇报一律用 RMSE。 MAPE 是最反直觉的:它涨得最少(2.0 倍)。因为那个异常点在相对尺度上不算大。 这也提醒一件事——「异常」是相对的,换个指标可能就不异常了。

30 秒实验

  1. 把异常点改成真实 100、预测 100.5(小误差),看四个指标还涨不涨。
  2. 把异常点改成真实 1、预测 3,看 MAPE 会变成多少——想想为什么会爆。
  3. 想一想:你的业务里,「偶尔错得很离谱」和「普遍错一点」,哪个更不能接受?

常见误区

  1. 「RMSE 一定比 MAE 好」——它被异常值主导,数据脏的时候会给出误导性的结论。
  2. 「MSE 可以直接汇报」——单位是平方,没人看得懂,只适合当优化目标。
  3. 「MAPE 最公平」——真实值接近 0 时会爆炸,且对高估低估不对称。
自测三问(点开对答案) 1. MAE 和 RMSE 的公式差别是什么? —— MAE 对误差取绝对值再平均,RMSE 对误差平方再平均再开根号。 2. 为什么异常值对 MSE 的影响远大于 MAE? —— 平方放大了大误差:误差翻十倍,平方项翻一百倍,平均值被一个点主导。 3. MAPE 在什么情况下会出问题? —— 真实值接近 0 时相对误差会爆炸,而且它对低估和高估的惩罚不对称。

误差是回归的指标。下一节回到分类,讲一个能同时看所有阈值的工具:ROC 曲线。

相关笔记