找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

676

积分

0

好友

88

主题
发表于 7 小时前 | 查看: 1| 回复: 0

当面对包含数十个特征、数千个序列的业务数据时,传统复杂模型如ARIMA往往力不从心。此时,一种名为TiDE的时间序列预测新方法进入了视野。它不像Transformer那样结构复杂,反而像一个“加强版MLP”,但其预测效果出色且部署简易,非常适合实际业务预测场景。

你可以这样理解:传统时序模型如LSTM、Transformer,其核心是“按时间步逐步推进”,依赖隐藏状态传递历史信息。优点是能“记忆”,但缺点也很明显:面对长序列时,训练缓慢、显存消耗大、部署复杂。

TiDE的设计思路则颇为反直觉:它摒弃了RNN循环和自注意力机制,直接将一整段历史时间窗口的数据“拉平”成一个长向量,再结合节假日、价格等外部特征,全部送入一个多层感知机(MLP)编码器中,从而得到一个代表整个序列的“隐藏表示”。随后,再用一个解码器MLP,将这个表示“展开”为未来多个时间步的预测值。

模型还设计了一条“线性残差支路”,专门捕捉数据中简单的线性趋势。这样一来,复杂的非线性模式由MLP主干学习,而简单的趋势则由线性层处理,两者协同工作,提升了模型的整体表现。

这种设计带来了几个非常实用的优点:

  • 结构简单:核心就是全连接层,工程上易于调整,推理速度快。
  • 多步预测一步到位:例如需要预测未来24小时,TiDE直接输出一个24维的向量,而非进行耗时的逐步滚动预测。
  • 强大的特征容纳能力:在同一个输入窗口内,无论是历史特征、静态特征还是未来已知特征(如未来的节假日安排),都可以拼接在一起进行学习。

下面是一个用PyTorch实现的极简版TiDE,结构遵循论文思想但简化了细节,方便快速理解和使用。

import torch
import torch.nn as nn
import torch.nn.functional as F

class SimpleTiDE(nn.Module):
    def __init__(self, input_len: int,     # 历史窗口长度,比如 48 个时间步
                 d_in: int,           # 每个时间步的特征维度
                 output_len: int,     # 预测步数,比如未来 24 步
                 d_hidden: int = 256  # 隐藏维度
                 ):
        super().__init__()
        self.input_len = input_len
        self.d_in = d_in
        self.output_len = output_len

        # 编码器:把 [B, T, D] 拉平成 [B, T*D] 再过 MLP
        self.encoder = nn.Sequential(
            nn.Linear(input_len * d_in, d_hidden),
            nn.ReLU(),
            nn.Linear(d_hidden, d_hidden),
            nn.ReLU(),
        )

        # 解码器:把序列级表示变成未来多步预测
        self.decoder = nn.Sequential(
            nn.Linear(d_hidden, d_hidden),
            nn.ReLU(),
            nn.Linear(d_hidden, output_len)  # 这里先假设只预测 1 维目标
        )

        # 线性残差:直接对历史做线性投影,学“趋势”
        self.linear_residual = nn.Linear(input_len, output_len)

    def forward(self, x_hist, y_hist):
        """
        x_hist: [B, T, D]   历史特征(价格、节假日、业务特征等)
        y_hist: [B, T]      历史目标(比如历史销量)
        return: [B, H]      未来 H 步预测
        """
        B, T, D = x_hist.shape
        assert T == self.input_len and D == self.d_in

        # 1. 编码器:序列 -> 一个向量
        x_flat = x_hist.reshape(B, T * D)     # [B, T*D]
        h = self.encoder(x_flat)              # [B, d_hidden]

        # 2. 解码器:向量 -> 未来多步
        dec_out = self.decoder(h)             # [B, output_len]

        # 3. 线性残差:用历史目标直接线性外推
        trend = self.linear_residual(y_hist)  # [B, output_len]

        # 4. 两条路相加
        return dec_out + trend

这个版本的功能很明确:输入一段历史特征 x_hist 和历史目标值 y_hist,模型直接输出未来 output_len 步的预测值。

一个最简单的训练循环示意如下:

model = SimpleTiDE(input_len=48, d_in=10, output_len=24)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
loss_fn = nn.MSELoss()

for epoch in range(50):
    for x_hist, y_hist, y_future in dataloader:
        # x_hist: [B, 48, 10]
        # y_hist: [B, 48]
        # y_future: [B, 24]
        pred = model(x_hist, y_hist)
        loss = loss_fn(pred, y_future)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

在实际项目中,你可以灵活调整:

  • input_len 可以设为 96、168 等更长的历史窗口。
  • d_in 中可以塞入更多特征,如价格、营销活动标志、星期几、节假日、大促标识等。
  • 若需要同时预测多个目标(如GMV、订单量、访客数),可将解码器最后一层输出改为 output_len * num_targets,再进行reshape。

通过这个极简的实现,我们可以看到TiDE如何利用简单的深度学习组件解决复杂的时序预测问题。其思想对于希望快速搭建高效预测模型的Python开发者而言,具有很高的参考价值。如果你想进一步探索,例如加入未来已知协变量、用PyTorch Lightning构建完整训练流程等,欢迎在云栈社区交流讨论。




上一篇:Linux面试争议:28K候选人写不出统计Nginx日志Top10 IP命令
下一篇:ChatGPT辅助论文写作:脑电研究揭示认知债务风险与大脑连接性减弱
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-26 18:44 , Processed in 0.431667 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表