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

相关推荐
文火冰糖的硅基工坊21 小时前
[人工智能-大模型-19]:GitHub Copilot:程序员的 AI 编程副驾驶
人工智能·github·copilot
shuououo1 天前
YOLOv4 核心内容笔记
人工智能·计算机视觉·目标跟踪
DO_Community1 天前
普通服务器都能跑:深入了解 Qwen3-Next-80B-A3B-Instruct
人工智能·开源·llm·大语言模型·qwen
WWZZ20251 天前
快速上手大模型:机器学习3(多元线性回归及梯度、向量化、正规方程)
人工智能·算法·机器学习·机器人·slam·具身感知
deephub1 天前
深入BERT内核:用数学解密掩码语言模型的工作原理
人工智能·深度学习·语言模型·bert·transformer
PKNLP1 天前
BERT系列模型
人工智能·深度学习·bert
兰亭妙微1 天前
ui设计公司审美积累 | 金融人工智能与用户体验 用户界面仪表盘设计
人工智能·金融·ux
AKAMAI1 天前
安全风暴的绝地反击 :从告警地狱到智能防护
运维·人工智能·云计算
岁月宁静1 天前
深度定制:在 Vue 3.5 应用中集成流式 AI 写作助手的实践
前端·vue.js·人工智能
galaxylove1 天前
Gartner发布数据安全态势管理市场指南:将功能扩展到AI的特定数据安全保护是DSPM发展方向
大数据·人工智能