N-Beats:一种用于时间序列预测的纯前馈神经网络模型

介绍

N-Beats(Neural Basis Expansion Analysis for Interpretable Time Series Forecasting)是一种基于纯前馈神经网络的时间序列预测模型,由Boris Oreshkin等人在2019年提出。与传统的递归神经网络(如LSTM和GRU)不同,N-Beats通过堆叠多个简单的前馈块来生成预测,具有高度的可解释性和灵活性。

工作原理

模型架构

N-Beats的核心思想是使用一系列简单的前馈块(称为"基础块")来逐步生成预测值。每个基础块包含一个全连接层(或多个全连接层),用于学习时间序列的模式,并输出两个部分:

  1. 后向分量(Backcast):用于拟合输入的历史数据。
  2. 前向分量(Forecast):用于生成未来的预测值。

基础块可以分为两种类型:

  • 通用块(Generic Block):直接学习时间序列的复杂模式。
  • 趋势块 (Trend Block)和季节性块(Seasonality Block):分别用于捕捉时间序列的趋势成分和季节性成分。

训练过程

  1. 数据准备

    • 输入数据包括历史观测值。
    • 每个时间序列被分成训练集和测试集。
  2. 模型训练

    • 对于每个基础块,输入为历史观测值的一部分(即"窗口")。
    • 基础块生成后向分量和前向分量。
    • 后向分量用于拟合输入的历史数据,前向分量用于生成未来预测值。
    • 损失函数通常采用均方误差(MSE),以最小化预测值与真实值之间的差异。
  3. 堆叠基础块

    • 多个基础块按顺序堆叠,每个块的后向分量用于校正前一个块的残差。
    • 最终的预测值是所有基础块前向分量的累加结果。

优势

  • 可解释性:通过堆叠不同类型的基础块(如趋势块和季节性块),N-Beats能够明确地分解时间序列的不同成分,提高模型的可解释性。
  • 灵活性:N-Beats可以处理不同长度和频率的时间序列数据,并且支持多种类型的预测任务。
  • 高效性:由于不依赖递归结构,N-Beats在训练和推理过程中具有较高的计算效率。
  • 鲁棒性:N-Beats在处理噪声和异常值方面表现出色,能够在一定程度上抵抗这些因素的影响。

实现步骤

数据准备

  1. 收集数据:获取时间序列数据及其相关的协变量。
  2. 预处理
    • 处理缺失值。
    • 标准化或归一化数据。
    • 提取时间特征(如月份、星期几等)。

模型构建

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset

class GenericBlock(nn.Module):
    def __init__(self, input_size, theta_size, hidden_size, num_layers):
        super(GenericBlock, self).__init__()
        layers = [nn.Linear(input_size, hidden_size), nn.ReLU()]
        for _ in range(num_layers - 1):
            layers.append(nn.Linear(hidden_size, hidden_size))
            layers.append(nn.ReLU())
        layers.append(nn.Linear(hidden_size, theta_size))
        self.layers = nn.Sequential(*layers)

    def forward(self, x):
        return self.layers(x)

class NBeatsBlock(nn.Module):
    def __init__(self, input_size, theta_size, hidden_size, num_layers, basis_function):
        super(NBeatsBlock, self).__init__()
        self.input_size = input_size
        self.theta_size = theta_size
        self.basis_function = basis_function
        self.fc = GenericBlock(input_size, theta_size, hidden_size, num_layers)

    def forward(self, x):
        backcast, forecast = self.basis_function(self.fc(x))
        return backcast, forecast

class NBeatsNet(nn.Module):
    def __init__(self, input_size, output_size, stack_types, nb_blocks_per_stack, thetas_dim, hidden_layer_units, share_weights_in_stack=False):
        super(NBeatsNet, self).__init__()
        self.blocks = []
        for stack_id in range(len(stack_types)):
            for block_id in range(nb_blocks_per_stack[stack_id]):
                if share_weights_in_stack and block_id != 0:
                    self.blocks[-1].requires_grad_(True)
                else:
                    self.blocks.append(NBeatsBlock(input_size, thetas_dim[stack_id], hidden_layer_units[stack_id], 4, stack_types[stack_id]))
        self.blocks = nn.ModuleList(self.blocks)

    def forward(self, x):
        residuals = x
        forecast = 0
        for i, block in enumerate(self.blocks):
            backcast, block_forecast = block(residuals)
            residuals = (residuals - backcast)
            forecast = forecast + block_forecast
        return forecast

# 参数设置
input_size = 10  # 输入窗口大小
output_size = 1  # 输出窗口大小
stack_types = ['generic', 'trend', 'seasonality']
nb_blocks_per_stack = [2, 2, 2]
thetas_dim = [5, 3, 7]
hidden_layer_units = [64, 64, 64]
batch_size = 32
epochs = 100

# 初始化模型
model = NBeatsNet(input_size, output_size, stack_types, nb_blocks_per_stack, thetas_dim, hidden_layer_units)
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 数据加载
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)

# 训练模型
for epoch in range(epochs):
    for i, (inputs, targets) in enumerate(train_loader):
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, targets)
        loss.backward()
        optimizer.step()
    print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')

模型评估

  1. 生成预测

    • 使用训练好的模型对测试集进行预测。
    • 生成未来时间点的预测值。
  2. 评估指标

    • 计算均方误差(MSE)、平均绝对误差(MAE)等点估计指标。
    • 评估预测的准确性。

结果分析

  • 可视化:绘制预测值与真实值的对比图。
  • 成分分解:展示各个基础块的后向分量和前向分量,分析其对最终预测结果的贡献。

总结

N-Beats是一种强大的时间序列预测模型,通过堆叠简单的前馈块来生成预测值,具有高度的可解释性和灵活性。

相关推荐
水如烟12 小时前
孤能子视角:“组织行为学–组织文化“
人工智能
大山同学12 小时前
图片补全-Context Encoder
人工智能·机器学习·计算机视觉
薛定谔的猫198212 小时前
十七、用 GPT2 中文对联模型实现经典上联自动对下联:
人工智能·深度学习·gpt2·大模型 训练 调优
壮Sir不壮12 小时前
2026年奇点:Clawdbot引爆个人AI代理
人工智能·ai·大模型·claude·clawdbot·moltbot·openclaw
PaperRed ai写作降重助手13 小时前
高性价比 AI 论文写作软件推荐:2026 年预算友好型
人工智能·aigc·论文·写作·ai写作·智能降重
玉梅小洋13 小时前
Claude Code 从入门到精通(七):Sub Agent 与 Skill 终极PK
人工智能·ai·大模型·ai编程·claude·ai工具
-嘟囔着拯救世界-13 小时前
【保姆级教程】Win11 下从零部署 Claude Code:本地环境配置 + VSCode 可视化界面全流程指南
人工智能·vscode·ai·编辑器·html5·ai编程·claude code
正见TrueView13 小时前
程一笑的价值选择:AI金玉其外,“收割”老人败絮其中
人工智能
Imm77713 小时前
中国知名的车膜品牌推荐几家
人工智能·python
风静如云13 小时前
Claude Code:进入dash模式
人工智能