用机器学习做时间序列
把时间序列摊平成一张表——每一行是"前 k 个值 → 下一个值"——任何回归模型立刻就能上。这个转换很诱人,也确实常常有效,但它把时间序列最关键的三个特点丢掉了:顺序不能打乱、趋势会走出训练范围、多步预测的误差会累积。这一页把这三个坑一个一个摆出来量给你看。
LAB 01
滞后特征
用前 k 个点当特征,k 取多少,模型能看到多远
最好的 k—
对应的 RMSE—
只用前 1 个点时的 RMSE—
噪声决定的下限—
滞后特征是把时间序列变成回归问题的那把钥匙。第 t 行的特征就是 y(t−1), y(t−2), …, y(t−k),标签是 y(t)。这样一来随机森林、梯度提升、神经网络全都能用了。k 该取多大?把滑杆拖一遍,看那条曲线。这个序列的真实周期是 12,噪声标准差是 0.5。k=1 时 RMSE 是 1.05——只看前一个点,完全不知道现在处在周期的哪个位置;k=6 时降到 0.556,已经很接近噪声下限 0.5;再往上基本就平了。注意一件有点反直觉的事:曲线在 k=12 处并没有明显的台阶。很多人以为"必须覆盖一整个周期",但只要看到半个周期(k=6),模型就已经能从形状推断出相位了——正弦曲线上连续六个点,足以确定它在上升段还是下降段。k 太大有代价:每多一个滞后特征,训练样本就少一行(前 k 个点没法用),同时特征维度多一维,两头夹击之下,样本少的时候反而会变差。实用建议:先看自相关图,把 k 取到"最后一个显著滞后"附近,再加上季节周期本身那个滞后(比如 y(t−12))作为单独的特征——这样既不用把 k 拉到 12 以上,又保留了季节信息。实际项目里还会加上日历特征(星期几、是否节假日),那往往比再多几个滞后有用得多。
LAB 02
直接法与递归法
预测 12 步:一次训 12 个模型,还是把预测当输入递归下去
第 1 步的 RMSE:递归 / 直接—
最后一步的 RMSE:递归 / 直接—
要训练几个模型:递归 / 直接—
远期谁更好—
预测下一步很容易,预测未来十二步有两种完全不同的做法。递归法:只训一个"预测下一步"的模型,预测出来的值当作真实值喂回去,再预测下一步,如此反复。直接法:为每个步长单独训一个模型——一个专门预测第 1 步,一个专门预测第 12 步。两条曲线的形状差别很说明问题。第 1 步两者几乎一样(用的是同一份信息);往后走,递归法的误差涨得更快,因为它把自己的预测误差当成真值又喂了回去,误差在每一步被放大一次,层层累积。直接法没有这个问题,它每一步都是从真实的历史出发。但直接法也有代价:要训 H 个模型(读数第三行),而且步长越远,可用的训练样本越少(预测 12 步就得丢掉最后 12 行),所以远期模型本身也更不准。所以没有一个方向总是赢。经验上:序列噪声小、模型偏差小时,递归法更好(信息利用更充分);噪声大、模型有系统偏差时,直接法更稳(不会把偏差滚雪球)。把噪声滑杆拖一拖,你能看到胜负换手。(还有第三种折中做法叫 DirRec:每步单独训模型,但把上一步的预测也作为特征。以及多输出模型:一次性输出全部 H 个值,这在神经网络里最常见。)
LAB 03
树模型外推不了
有趋势的序列上树模型会画出一条水平线——先差分再学
直接在原序列上学的 RMSE—
先差分再学的 RMSE—
训练集里的最大值—
原序列模型预测出来的最大值—
这是树模型用在时间序列上最常见、也最隐蔽的一个错误。把趋势设成 0.08,看那条红线:它在分割线之后就横着走了,完全跟不上继续上升的真实序列。读数里那两个数字说明了原因:训练集的最大值是 24.6,而红色模型预测出来的最大值是 23.9——它永远不会超过训练集见过的范围。这不是调参能解决的,是树模型的结构性限制。一棵回归树的预测值永远是某个叶子里训练样本的平均,所以输出必然落在训练标签的最小值和最大值之间。随机森林、梯度提升、KNN 都有这个性质。(线性模型没有,神经网络理论上没有但实践中外推也很不可靠。)绿线是解法:先差分。学的不再是"下一个值是多少",而是"下一步会变化多少"——差分序列没有趋势,落在训练范围之内,树模型就能处理了。预测完再把增量一步步累加回去,趋势自然被还原。RMSE 从 2.50 降到 1.04,好了 2.4 倍。把趋势拖到 0,两条线会重合——没有趋势时这个问题根本不存在,这也是为什么它容易被忽略:在平稳的测试数据上一切正常,一上线遇到增长就开始系统性低估。(除了差分,另外两种常见做法是:把时间 t 本身作为特征交给线性部分处理(比如用线性树),或者先用回归去掉趋势,再用树学残差。)
LAB 04
和经典方法比一比
同一份数据上,Holt-Winters 与梯度提升谁赢,在什么条件下
Holt-Winters 的 RMSE—
差分 + 随机森林的 RMSE—
季节朴素法的 RMSE—
谁赢了—
这一页的最后一个实验台,结论可能和你预期的相反。在这条只有 240 个点、带趋势和季节的序列上,Holt-Winters 在四种参数组合下全部赢过差分 + 随机森林,而且噪声越大赢得越多(噪声 2.0 时是 2.37 对 8.14)。这不是故意为难机器学习,而是 M 系列预测竞赛反复得到的结论:在短的、单条的、结构清楚的序列上,经典方法很难被超越。原因不难理解。Holt-Winters 只有三个参数,而且它的结构(水平 + 趋势 + 季节)正好就是数据的结构;随机森林要从两百来个样本里把同样的结构学出来,还要同时抵抗噪声——它在用高方差的方式学一件低维的事。那机器学习什么时候赢?三种情况:一是序列很多(成千上万条 SKU 的销量),可以跨序列共享信息,这是全局模型的主场,M5 竞赛的前几名全都是梯度提升;二是有大量外生变量(促销、天气、价格、节假日),经典方法很难塞进去;三是关系明显非线性(阈值效应、饱和、交互)。实践中的正确做法是:永远先跑季节朴素法和 Holt-Winters 当基准(读数第三行就是基准),再决定要不要上更复杂的东西。一个打不过季节朴素法的模型,无论多复杂都没有价值。
这一页想说的
把时间序列变成表格是可行的,但要带着三条纪律:滞后特征取到自相关显著的范围,并单独加上季节滞后;多步预测要在递归和直接之间按噪声水平选择;树模型无法外推,有趋势就必须先差分。最后一条最重要:先跑季节朴素法和指数平滑当基准。在短序列上经典方法常常更好,机器学习的优势要在"很多条序列 + 很多外生变量"的场合才显现出来。