Autoformer 时序分解预测:用序列分解+自相关机制
Informer 还在点积注意力里挑活跃查询,Autoformer(NeurIPS 2021)直接换了两个零件:一是把「分解」从预处理搬进模型内部——移动平均逐层剥趋势,季节项与趋势项分开建模;二是把点积注意力换成「自相关机制」——用 FFT 以 O(L·logL) 算出自相关谱 R(τ),取 top-k 滞后当候选周期,按 softmax(R(τ)) 权重做时延聚合:预测 = Σ w(τ)·x(t−τ),从「点对点找相似」升级为「整段周期对齐」。纯 numpy 从零实现因果分解 + FFT 自相关 + 时延聚合递推预测,在三重周期(24/96/168)+慢趋势+AR(1)噪声合成序列上做 50 窗口滚动 H=24 多步预测:分解+自相关 MSE=0.257 优于无分解消融 0.263 与季节 naive 0.367,自相关机制自动找到 τ∈{24,96} 真周期;但诚实披露 OLS-96滞后递推 MSE=0.193 仍是全场最优——机制的优雅不等于精度的碾压。附「分解泄漏未来」的一次真实翻车修复(居中移动平均让 AF 版 MSE 虚好 42%),拆穿分解万能/自相关=注意力上位/多步递推免费/top-k 自动对/金融强周期五类陷阱(中阶)。
上一篇我们拆了 Informer:注意力长尾 → 只算活跃查询 → O(L·lnL)。它仍然在点积注意力的框架里做减法。Autoformer(Wu et al., NeurIPS 2021)走得更远——它认为对时序预测来说,点积注意力这个零件本身就不对,于是换掉了两个核心部件:
- 分解不是预处理,是模型内置模块。传统做法先 STL 分解再喂模型;Autoformer 把移动平均块嵌在每层里,前向过程中逐层把趋势剥出来,季节项走注意力路径、趋势项走累加路径,各自建模。
- 点积注意力 → 自相关机制(Auto-Correlation)。点积注意力做的是”点对点找相似”;自相关机制做的是”整段周期对齐”——用 FFT 算自相关谱,找出最强的 k 个周期滞后 τ,把 τ 步前的整段序列按权重聚合过来。

一、先分解:趋势和季节是两种病,别用一副药#
我们的合成序列 = 三重周期(24/96/168 步)× 幅度调制 + 慢趋势 + AR(1) 噪声,共 3600 步。上图是分解结果:移动平均(窗口 25)把慢趋势剥出来,剩下的季节项呈现干净的多周期振荡。
为什么要分开?因为两者的可预测结构完全不同:趋势是低频积分过程,最优预测接近”当前水平 + 斜率外推”;季节是周期过程,最优预测是”抄 τ 步前的自己”。一个模型同时伺候两者,注意力权重会在”追踪水平”和”对齐相位”之间打架。
一个必须强调的工程细节:预测场景下分解必须是因果的。趋势项在位置 i 只能用 x[i−k+1..i](trailing 移动平均),不能用居中移动平均——后者的窗口右半边是未来。我第一版就犯了这个错(细节在陷阱一)。
def moving_avg_causal(x, k):
"""因果移动平均:位置 i 只用 x[i-k+1..i]。"""
cs = np.cumsum(np.insert(x, 0, 0.0))
out = np.empty(len(x))
for i in range(len(x)):
lo = max(0, i - k + 1)
out[i] = (cs[i + 1] - cs[lo]) / (i + 1 - lo)
return out
def decompose(x, k=25):
tr = moving_avg_causal(x, k)
return x - tr, tr # 季节项, 趋势项python二、自相关机制:把注意力从「点」升级到「段」#
点积注意力问”位置 i 和位置 j 的内容像不像”;自相关机制问”整条序列平移 τ 步后和自己像不像”。度量就是自相关函数:
直接算所有 τ 是 O(L²),但 Wiener–Khinchin 定理说自相关是功率谱的逆傅里叶变换,FFT 一来一回 O(L·logL) 搞定:
def autocorr_fft(x):
xc = x - x.mean()
n = len(xc)
f = np.fft.rfft(xc, n=2 * n) # 补零防循环卷积
acf = np.fft.irfft(f * np.conj(f))[:n]
return acf / acf[0]
def autocorrelation_forecast(seasonal, H, topk=5):
acf = autocorr_fft(seasonal[-1024:])
lags = np.arange(8, 400)
top_lags = lags[np.argsort(acf[lags])[-topk:]] # top-k 周期滞后
w = softmax(np.array([acf[l] for l in top_lags]) * 10)
fc, buf = np.zeros(H), seasonal.copy()
for h in range(H): # 时延聚合递推
fc[h] = sum(wi * buf[-li] for wi, li in zip(w, top_lags))
buf = np.append(buf, fc[h])
return fc, top_lags, wpython选出 top-k 个滞后后,做时延聚合:预测值 = Σ w(τ)·x(t−τ),权重是自相关值的 softmax。这就是”周期对齐”——把 τ 步前的相位直接搬过来加权平均。

实测自相关谱干净地在 τ≈24 和 τ≈96 处起峰,top-5 滞后选中 {23, 24, 95, 96, 97}——机制自动找到了我们埋进去的两个主周期(168 步周期振幅最弱,未进前五,合理)。相邻滞后(23/24/25)同时入选相当于对相位估计误差做了平滑,是这个机制隐含的鲁棒性来源。
三、滚动多步实测:分解有增益,但 OLS 仍是全场最优#
H=24 步预测,测试段 50 个滚动窗口,四个方案对照:
| 方案 | 多步 MSE | 等价 R² |
|---|---|---|
| 分解 + 自相关(Autoformer 式) | 0.257 | 0.522 |
| 无分解消融(原序列直接自相关聚合) | 0.263 | 0.512 |
| 季节 naive(照抄 t−24) | 0.367 | 0.318 |
| OLS 96 滞后递推 | 0.193 | 0.641 |

三个结论,按重要性排:
结论一:两个机制都真实有效,但幅度诚实。 自相关聚合(无分解版 0.263)大幅优于季节 naive(0.367)——多滞后加权确实比单滞后照抄强 28%。分解再往上叠 2% 的增益(0.257 vs 0.263)——在这个趋势较温和的序列上,分解的边际贡献存在但不戏剧化。趋势越强、越非平稳,分解的收益越大;这也是 Autoformer 论文里长 horizon(H=336、720)下优势更明显的原因:递推越远,未被剥离的趋势漂移积累得越狠。
结论二:OLS 又赢了。 96 滞后线性递推 MSE=0.193,比 Autoformer 式好 25%。原因与前几篇一脉相承:合成序列本质是固定频率的线性叠加 + AR 噪声,而”96 个滞后的线性组合”完全有能力表达”多周期对齐 + AR 外推”的最优解——它其实是自相关聚合的超集(自相关聚合 = 权重被 ACF 锁死的滞后线性组合,OLS 则自由学权重)。自相关机制的真正价值在免训练、可解释、O(L·logL),以及数据不够 OLS 学 96 个参数时的低方差先验。
结论三:机制的优雅≠精度的碾压。 Autoformer 在 benchmark 上的领先来自完整架构(多层分解 + 编解码器 + 端到端训练),我们提取的是它两个核心机制的”最小可运行版本”。机制本身给出的是合理的归纳偏置,不是免费的精度。
四、五个真实陷阱#
陷阱一:分解泄漏未来(我真实踩过)。 第一版用了居中移动平均做分解——位置 i 的趋势用了 i 之后 12 个点。滚动预测时最后 12 个位置的趋势项被”未来”抹平,季节项相应被污染,AF 版 MSE 虚好到 0.18 左右(比修复后好 42%),一度”击败”OLS。改成因果 trailing 均值后回落到 0.257。分解类方法是 look-ahead 的重灾区:STL、HP 滤波、小波去噪默认都是双边的,进回测前必须逐一检查。
陷阱二:「分解总是有益」。 趋势弱、噪声强时,因果移动平均剥出来的”趋势”多半是噪声的低频投影,对它做斜率外推反而引入额外方差。我们序列上分解只带来 2% 增益;把趋势斜率的估计窗口从 96 缩到 48,增益直接变负。分解模块的超参数(窗口 k、外推方式)不是装饰。
陷阱三:「自相关机制全面优于点积注意力」。 它赢在平稳周期场景。若周期时变(如日历效应随 regime 漂移)、或依赖是内容驱动而非相位驱动(“每次暴跌后的反弹”),固定滞后的时延聚合会对不上相位,点积注意力的内容寻址反而对路。Autoformer 论文自己也只在长周期数据集上碾压。
陷阱四:「多步递推是免费的」。 时延聚合递推 H 步,第 h 步开始消费自己前 h−1 步的预测(当 τ<h 时)。好在 top 滞后是 24/96,都大于 H=24 的大部分位置,误差累积温和;若主周期短于 horizon(比如 τ=5、H=24),递推会迅速自我污染,此时应改用直接多步(direct multi-step)训练。
陷阱五:「金融序列有强周期可挖」。 我们的合成序列 ACF 在 τ=24 处高耸;真实日频收益率的 ACF 在所有滞后上都趴在显著性水平附近。金融里自相关机制的合理用法是对波动率(有真实的日内/周内周期)、成交量、期限结构这类有物理周期的量建模,而不是直接对收益率找周期——找到的多半是幻觉。
收尾#
Autoformer 的两个替换都指向同一个洞察:时序预测的主要矛盾是趋势与周期的显式结构,不是任意 token 间的内容相似度。分解把两种结构分开各自击破,自相关机制用 O(L·logL) 的 FFT 把”周期对齐”写成可微模块——在我们的实测里,它们自动找到了真周期 {24, 96},多步 MSE 比季节 naive 好 30%。但同样的实验也把边界画得很清楚:结构温和时分解增益仅 2%,而一个自由学权重的 OLS 递推仍以 25% 的优势领跑。读论文时记住这条:新机制的价值先看归纳偏置对不对路,再看 benchmark 表格。