365 天 PM2.5 序列:持续法 MAE 10.09、七日移动平均 9.62、AR(1) 9.51。 但三次重污染过程里,AR(1) 的误差 27/26/48,全都比持续法的 17/8/38 大。
上一节做视觉,这一节处理时间序列。它的特点和前面都不同:样本之间不独立,今天和昨天强相关。
一、时间序列的规矩:只能往前看
图像和文本的样本是独立的,打乱顺序不影响。时间序列不行——用第 300 天的数据预测第 200 天,那是作弊。 所以所有验证都必须按时间切:用前面的数据训练,用后面的数据测试。 随机切分是时间序列里最常见的错误,它会让结果好得离谱。 Demo 里三个方法都只用「当前时刻之前」的数据,没有一处用到未来。 这一条不是洁癖,是生死线。做出来的模型要上线,上线那天你拿不到明天数据。
二、三个朴素基线
别小看基线。任何复杂模型都要先跟这三条线比: - 持续法:明天等于今天。MAE 10.09、RMSE 13.17。 - 七日移动平均:取前七天的均值。MAE 9.62、RMSE 14.96。 - AR(1):用最小二乘拟合「今天 = a×昨天 + b」。MAE 9.51、RMSE 12.43。 AR(1) 学到的系数是 a = 0.7836、b = 9.5024。 a 小于 1,说明序列有回归均值的倾向——今天是高值,明天大概率往中间掉一点。 三个数的差距很小:MAE 从 10.09 到 9.51,只好了 6%。 这说明这份数据的「可预测性」本来就不高,换个花哨模型也难大幅改善。
三、关键的那几天,最好的模型最差
Demo 单独看了三次重污染过程的第三天: - 第 63 天,真实 109:持续法错 17,AR(1) 错 27。 - 第 153 天,真实 133:持续法错 8,AR(1) 错 26。 - 第 263 天,真实 126:持续法错 38,AR(1) 错 48。 三次都是 AR(1) 更差。为什么?因为它学到的是「平常日子怎么变」——a = 0.78 意味着向均值回归。 而重污染那几天恰恰是不回归的,一路往上冲。 持续法反而占便宜:它直接复制昨天的值,昨天已经很高,今天更高,误差就小。 这就是极端事件预测的悖论:平均指标最好的模型,恰恰在关键时刻最不可靠。 空气质量预警要的偏偏是那几天。
四、指标选错,结论就反
再仔细看三个基线:七日移动平均的 MAE(9.62)比持续法(10.09)小, 但 RMSE(14.96)比持续法(13.17)大。 也就是说,按 MAE 它更好,按 RMSE 它更差。两句话都对,看你用哪个指标。 MAE 对每个误差一视同仁;RMSE 会放大大的误差。 所以:关心「平时误差多大」用 MAE,关心「会不会爆一个大错」用 RMSE。 空气质量预警关心的是后者——宁可平均差一点,也不能漏掉重污染。 所以这个场景应该盯 RMSE,甚至盯「重污染日召回率」。 指标选错,整份评估就白做。这在模型评估那一章还会再展开一次。
五、动手 Demo:PM2.5 预测:三种朴素办法
造一条 365 天的 PM2.5 序列(季节正弦 + 缓慢趋势 + 噪声 + 三次重污染冲击); 分别用持续法、七日移动平均、AR(1) 最小二乘做一步预测;比较 MAE 与 RMSE; 再单独看三次重污染第三天的误差。
base = 45 + 18 * np.sin(2 * np.pi * (t - 100) / 365)
pm = base - 0.02 * t + rg.normal(0, 8, days)
for c in (60, 150, 260):
pm[c:c + 6] += np.array([30, 60, 85, 70, 40, 20])
p1 = pm[:-1] # 持续法
p2 = np.array([pm[i - 7:i].mean() for i in range(7, days)])
A = np.column_stack([pm[:-1], np.ones(days - 1)])
coef, *_ = np.linalg.lstsq(A, pm[1:], rcond=None)
p3 = A @ coef # AR(1)
实跑输出:
--------------------------------------------------------------------
PM2.5 预测:三种朴素办法,谁的错误更小
--------------------------------------------------------------------
方法 MAE RMSE
-----------------------------------
持续法(昨天=今天) 10.09 13.17
七日移动平均 9.62 14.96
AR(1) 最小二乘 9.51 12.43
AR(1) 学到的系数 a = 0.7836,b = 9.5024
均值 43.76 微克/立方米
标准差 20.10
最高一天 132.8(第 153 天)
重污染那几天,三种方法各错多少(单位同上):
第几天 真实值 持续法误差 AR(1) 误差
----------------------------------------
63 109 17 27
153 133 8 26
263 126 38 48
AR(1) 的 RMSE 比持续法小,但重污染那几天的误差反而更大——
因为它学的是「平常日子怎么变」,学不到「突然冲高」。
这就是极端事件预测的难点:平均值好看,关键的那几天不行。
数据是我按「季节 + 趋势 + 噪声 + 三次冲击」造出来的,
不是真实监测站数据。真实 PM2.5 还有风向、湿度、周边排放的影响。
三条基线的 MAE:10.09 / 9.62 / 9.51。差距只有 6%,说明这份数据的可预测性本来就有限。 但 RMSE 的排序换了:13.17 / 14.96 / 12.43。 七日移动平均在 MAE 上赢,在 RMSE 上输——两个指标给出相反的结论。 AR(1) 系数 a = 0.7836、b = 9.5024。 a 小于 1 表示「向均值回归」,这正好解释了它在重污染日的失败。 重污染三行:AR(1) 的误差 27 / 26 / 48,持续法 17 / 8 / 38,三次都更差。 第 153 天差得最多:8 对 26。
30 秒实验
- 把三次冲击去掉重跑,看 AR(1) 和持续法谁更好。
- 加一个「前三日均值」的基线,看它在这三次冲击上的表现。
- 想一想:为什么时间序列不能随机划分训练集和测试集?
常见误区
- 「随机切分就行」——会用到未来数据,结果虚高。
- 「MAE 小就是好」——本例七日移动平均 MAE 最小、RMSE 最大。
- 「平均指标好就能上线」——重污染那几天它最差,而那几天才是重点。
自测三问(点开对答案)
1. 为什么时间序列必须按时间切分? —— 随机切分会让模型用到未来数据,等于作弊。 2. AR(1) 的系数 0.78 意味着什么? —— 今天有向均值回归的倾向,不适合预测持续冲高的过程。 3. MAE 和 RMSE 的区别在哪儿? —— RMSE 会放大大的误差,关心「会不会爆大错」时看它。第四章的应用场景到此结束,下一章进深度学习——从「为什么要更深的网络」开始。
- ☐ (本章完,下一节 5.1.1 概念解读:认识深度学习算法)