做时间序列预测,建模只是上半场,下半场是:

这个模型到底靠不靠谱?预测得准不准?

要回答这个问题,离不开一套清晰的“准确性评价指标”。下面结合几个最常用的误差指标,一步步把它们讲清楚:它们怎么算、代表什么、各自适合什么场景。


预测误差(Forecast Error)

预测误差最原始的出发点是关于这一件事:预测值和真实值之间的差

常见约定有两种:

  • 预测误差 = 预测值 - 实际值
  • 或者 预测误差 = 实际值 - 预测值

只要在整个项目里保持一致即可。 下面我们延续示例代码里的写法:

expected = [0.0, 0.5, 0.0, 0.5, 0.0]      # 实际值
predictions = [0.2, 0.4, 0.1, 0.6, 0.2]  # 预测值

forecast_errors = [expected[i] - predictions[i] 
                   for i in range(len(expected))]

print('Forecast Errors:', forecast_errors)

这里的 forecast_errors 就是一条条时间上的“残差序列”。 后面所有的指标,本质上都在问:这堆误差整体上长什么样?


平均预测误差(Mean Forecast Error / Bias)

问题:模型是不是老“偏高”或者老“偏低”?

平均预测误差,也叫 Bias(偏差),就是把所有误差求个平均:

Mean Forecast Error = mean(预测错误)

示例代码:

expected = [0.0, 0.5, 0.0, 0.5, 0.0]
predictions = [0.2, 0.4, 0.1, 0.6, 0.2]

forecast_errors = [expected[i] - predictions[i] 
                   for i in range(len(expected))]

bias = sum(forecast_errors) * 1.0 / len(expected)
print('Bias:', bias)
  • Bias ≈ 0:整体上“不偏不倚”,有高有低,大体抵消。
  • Bias > 0:实际值普遍比预测值高,模型偏低估
  • Bias < 0:实际值普遍比预测值低,模型偏高估

小结:Bias 不关注“误差有多大”,只关注“有没有系统性偏差”。 在长期运营类的预测(如电量、负荷、销量)里,这个信息非常重要。


MAE:平均绝对误差(Mean Absolute Error)

问题:平均来说,预测差多少?

MAE 的公式是:

MAE = mean( |预测错误| )

也就是先取绝对值,再求平均。

它有两个很实用的特点:

  • 单位和原数据一样,容易向业务解释(比如“平均每天差 2MW”)。
  • 倾向于“靠近中位数”: 如果你只想让整体误差尽量均匀小,而不过度在意极端异常点,MAE 是一个很舒服的选择。

代码示例(sklearn 已经实现好了):

from sklearn.metrics import mean_absolute_error

expected = [0.0, 0.5, 0.0, 0.5, 0.0]
predictions = [0.2, 0.4, 0.1, 0.6, 0.2]

mae = mean_absolute_error(expected, predictions)
print('MAE:', mae)

直觉理解:把所有“偏差的幅度”拉直摊开,算一个平均水平。


MSE 与 RMSE

有时候,我们不满足于“平均差多少”,而是更在意:

那些偏得特别离谱的点,会不会被严重惩罚?

这时就轮到 MSERMSE 出场了。

MSE:均方误差(Mean Squared Error)

公式:

MSE = mean( 预测错误^2 )

也就是先平方,再求平均。平方这一步,会让大误差的影响被成倍放大

示例代码:

from sklearn.metrics import mean_squared_error

expected = [0.0, 0.5, 0.0, 0.5, 0.0]
predictions = [0.2, 0.4, 0.1, 0.6, 0.2]

mse = mean_squared_error(expected, predictions)
print('MSE:', mse)

MSE 的单位是“原单位的平方”,解释起来略微别扭一些,所以实务中更多用下面这个指标。

RMSE:均方根误差(Root Mean Squared Error)

为了解决“单位不好懂”的问题,我们再开个平方根:

RMSE = sqrt(MSE)

代码:

from sklearn.metrics import mean_squared_error
from math import sqrt

expected = [0.0, 0.5, 0.0, 0.5, 0.0]
predictions = [0.2, 0.4, 0.1, 0.6, 0.2]

mse = mean_squared_error(expected, predictions)
rmse = sqrt(mse)
print('RMSE:', rmse)

RMSE 有两个关键点:

  • 单位回到了原来的量纲(比如 MW、kWh),易于理解
  • 对异常值更敏感

    • RMSE 倾向于让整体预测结果的分布靠近平均值
    • 一两个非常大的误差,会把 RMSE 拉得很高。

小结:

  • 如果你特别讨厌“大错一次把系统搞崩”的情况,可以重点看 RMSE。
  • 如果你更在意整体稳定、对异常值不那么敏感,可以多看 MAE。

MAPE:平均绝对百分比误差(Mean Absolute Percentage Error)

问题:误差占真实值的百分比是多少?

很多业务方最关心的是:“相对误差是多少”。这时候,MAPE 就登场了。

典型公式:

MAPE = mean( |预测错误 / 实际值| ) * 100%

对应的 sklearn 示例:

from sklearn.metrics import mean_absolute_percentage_error

expected = [0.0, 0.5, 0.0, 0.5, 0.0]
predictions = [0.2, 0.4, 0.1, 0.6, 0.2]

mape = mean_absolute_percentage_error(expected, predictions)
print('MAPE:', mape)

MAPE 看起来很直观:“平均相对误差 8%”。 但它有几个天然坑点

  1. 实际值为 0 或接近 0 时会炸

    • 分母接近 0,相对误差会变得极大甚至无意义。
  2. 对小数值序列非常不友好

    • 例如实际值 0.01,预测 0.02,看似差不多,但百分比误差就是 100%。

因此,在很多严肃的时间序列场景中,MAPE 通常会被谨慎使用甚至明确规避,尤其是:

  • 实际值可能为 0(或非常接近 0)时;
  • 序列跨越多个数量级时。

在时间序列场景下,怎么选指标?

时间序列预测的评价,比“回归问题”多几分讲究,原因是:

  • 通常有 时间依赖:你可能使用滚动预测、多步预测等评估方式;
  • 业务含义更强:有的是功率/负荷,有的是价格/销量,每一类看重的东西有点不一样。

一个相对稳妥的组合是:

  1. Bias(平均误差)

    • 检查模型是不是“长期偏高”或“长期偏低”。
    • 尤其适用于电力负荷、电量、库存、销量等长期规划。
  2. MAE

    • 关注“平均差多少”,解释给业务方最自然。
    • 对极端异常不那么敏感,更能反映“日常表现”。
  3. RMSE

    • 捕捉“偶尔翻车”的程度。
    • 如果 RMSE 明显大于 MAE,往往意味着有一些特别大的误差点需要排查。
  4. MAPE(可选)

    • 如果业务特别喜欢“百分比误差”,可以在确保没有 0 或近 0 实际值的前提下使用。
    • 一旦存在大量小值或者为 0,建议慎重使用或改用其他相对误差指标(如 sMAPE 等)。

此外,真正落地到时间序列时,还建议:

  • 用滚动/滑动窗口或回测(backtesting)来评估,避免只在一个固定的验证集上“侥幸表现好”。
  • 对不同时间段分别算指标(工作日 vs 周末、旺季 vs 淡季),看模型在哪些场景更容易翻车。

总结

如何实现一套“看得懂”的评价体系?

可以用一张“口袋清单”来记时间序列预测的常用评价指标:

  • Forecast Error(残差):最原始的误差序列。
  • Bias(平均预测误差):模型整体是偏高还是偏低?
  • MAE:平均差多少,稳健、好解释,对异常值不过分敏感。
  • MSE / RMSE:对大误差更敏感,适合你“极度讨厌大错”的场景;RMSE单位可读性更好。
  • MAPE:百分比误差直观,但要提防“实际值为 0 或过小”的坑。

最后一句“说人话”的版本作为总结:

选指标,就像选视角。 Bias 告诉你方向偏没偏,MAE 告诉你一般差多少,RMSE 告诉你翻车有多严重,MAPE 则把误差换算成年轻人最爱听的“百分比”。 真正稳定的时间序列模型,通常是这几项指标看上去都顺眼的那个。