halo 的技术博客

返回

上一篇我们拆了 Informer:注意力长尾 → 只算活跃查询 → O(L·lnL)。它仍然在点积注意力的框架里做减法。Autoformer(Wu et al., NeurIPS 2021)走得更远——它认为对时序预测来说,点积注意力这个零件本身就不对,于是换掉了两个核心部件:

  1. 分解不是预处理,是模型内置模块。传统做法先 STL 分解再喂模型;Autoformer 把移动平均块嵌在每层里,前向过程中逐层把趋势剥出来,季节项走注意力路径、趋势项走累加路径,各自建模。
  2. 点积注意力 → 自相关机制(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 的内容像不像”;自相关机制问”整条序列平移 τ 步后和自己像不像”。度量就是自相关函数:

R(τ)=1LtxtxtτR(\tau) = \frac{1}{L}\sum_t x_t \cdot x_{t-\tau}

直接算所有 τ 是 O(L²),但 Wiener–Khinchin 定理说自相关是功率谱的逆傅里叶变换,FFT 一来一回 O(L·logL) 搞定:

选出 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.2570.522
无分解消融(原序列直接自相关聚合)0.2630.512
季节 naive(照抄 t−24)0.3670.318
OLS 96 滞后递推0.1930.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 表格

Autoformer 时序分解预测:用序列分解+自相关机制
https://blog.halo26812.eu.org/blog/autoformer-financial
Author halo
Published at 2026年7月24日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨