时间序列之:多步预测、长序列预测——Informer / ARIMA

多步预测是指根据已知的时间序列数据预测未来多个时间步长的值。在ARIMA模型中,可以使用预测函数进行多步预测。

Informer是一种用于时间序列预测的神经网络模型,旨在解决长序列预测中的挑战,如长期依赖性和变长序列。它结合了自注意力机制、卷积神经网络和传统的循环神经网络,以提高时间序列预测的准确性和效率。

Informer模型的核心思想是将输入序列分成不同的时间段,然后通过编码器-解码器结构进行建模。编码器部分使用自注意力机制和卷积层来捕捉序列内部的长期依赖关系和局部模式。解码器部分使用传统的循环神经网络来生成预测结果。此外,Informer还引入了一种长度编码机制,用于对变长序列进行建模。

用Informer进行时间序列预测(基于PyTorch):

import torch
import torch.nn as nn
from informer.models import Informer

# 创建Informer模型
model = Informer(
    enc_in=1,  # 输入序列的特征数
    dec_in=1,  # 输出序列的特征数
    c_out=1,   # 输出序列的维度
    seq_len=10,  # 输入序列的长度
    label_len=5,  # 输出序列的长度
    pred_len=1,  # 预测的时间步长
    factor=5,  # 编码器和解码器的缩放因子
    d_model=256,  # 模型的隐藏维度
    n_heads=8,  # 注意力头的数量
    e_layers=2,  # 编码器的层数
    d_layers=1,  # 解码器的层数
    d_ff=512,  # 前馈神经网络的隐藏层维度
    dropout=0.1,  # Dropout概率
    activation='gelu',  # 激活函数类型
    output_attention=False,  # 是否输出注意力权重
    distil=True,  # 是否使用蒸馏机制
    device=torch.device('cuda' if torch.cuda.is_available() else 'cpu')  # 使用GPU或CPU进行训练
)

# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 准备输入数据
x_train = torch.randn(100, 10, 1)  # 输入训练数据,大小为(样本数, 输入序列长度, 特征数)
y_train = torch.randn(100, 5, 1)   # 输出训练数据,大小为(样本数, 输出序列长度, 特征数)

# 将数据传入模型进行训练
model.train()
optimizer.zero_grad()
outputs = model(x_train, y_train[:, :-1, :])  # 预测输出,大小为(样本数, 预测序列长度, 特征数)
loss = criterion(outputs, y_train[:, 1:, :])  # 计算损失
loss.backward()
optimizer.step()

# 使用训练好的模型进行预测
model.eval()
x_test = torch.randn(10, 10, 1)  # 输入测试数据,大小为(样本数, 输入序列长度, 特征数)
preds = model.predict(x_test)  # 预测输出,大小为(样本数, 预测序列长度, 特征数)

上述代码中,通过调用Informer类创建了Informer模型,并定义了损失函数和优化器。然后,使用训练数据进行模型训练,通过调用model.train()、optimizer.zero_grad()、model()和loss.backward()实现反向传播和参数更新。最后,使用训练好的模型对测试数据进行预测,通过调用model.eval()和model.predict()获取预测结果。

请注意,上述代码仅为示例,实际应用中需要根据数据和任务的特点进行适当的调整和修改。

用ARIMA模型进行多步预测:

import numpy as np
import statsmodels.api as sm

# 创建时间序列数据
# 注意:ARIMA模型要求数据是平稳的,这里仅作示例,并没有对数据进行平稳性处理
data = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100])

# 创建ARIMA模型并拟合数据
model = sm.tsa.arima.ARIMA(data, order=(1, 0, 0))  # ARIMA(1, 0, 0)模型
model_fit = model.fit()

# 预测未来的观测值(多步预测)
forecast = model_fit.forecast(steps=3)  # 预测3个时间步长的观测值
print(forecast)

  • 2
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
Informer是一种用于时间序列预测的模型,它可以处理多变量和多步预测问题。下面是使用PyTorch实现Informer模型的步骤: 1. 安装依赖库 ```python !pip install torch !pip install tqdm !pip install numpy !pip install pandas !pip install matplotlib !pip install sklearn ``` 2. 导入必要的库 ```python import torch import torch.nn as nn import torch.nn.functional as F import numpy as np import pandas as pd from tqdm import tqdm import matplotlib.pyplot as plt from sklearn.preprocessing import StandardScaler ``` 3. 定义Informer模型 ```python class Encoder(nn.Module): def __init__(self, input_size, hidden_size, num_heads, seq_len): super(Encoder, self).__init__() self.input_size = input_size self.hidden_size = hidden_size self.num_heads = num_heads self.seq_len = seq_len self.multihead_attn = nn.MultiheadAttention(hidden_size, num_heads) self.layer_norm1 = nn.LayerNorm(hidden_size) self.pos_ffn = nn.Linear(hidden_size, hidden_size * 4) self.layer_norm2 = nn.LayerNorm(hidden_size) def forward(self, x): residual = x x = x.permute(1, 0, 2) attn_output, _ = self.multihead_attn(x, x, x) x = self.layer_norm1(residual + attn_output.permute(1, 0, 2)) residual = x x = self.pos_ffn(x) x = F.gelu(x) x = self.pos_ffn(x) x = self.layer_norm2(residual + x) return x class Decoder(nn.Module): def __init__(self, input_size, hidden_size, num_heads, seq_len): super(Decoder, self).__init__() self.input_size = input_size self.hidden_size = hidden_size self.num_heads = num_heads self.seq_len = seq_len self.masked_multihead_attn = nn.MultiheadAttention(hidden_size, num_heads) self.layer_norm1 = nn.LayerNorm(hidden_size) self.multihead_attn = nn.MultiheadAttention(hidden_size, num_heads) self.layer_norm2 = nn.LayerNorm(hidden_size) self.pos_ffn = nn.Linear(hidden_size, hidden_size * 4) self.layer_norm3 = nn.LayerNorm(hidden_size) def forward(self, x, encoder_output): residual = x x = x.permute(1, 0, 2) attn_output, _ = self.masked_multihead_attn(x, x, x, attn_mask=self._get_mask(x)) x = self.layer_norm1(residual + attn_output.permute(1, 0, 2)) residual = x x = self.multihead_attn(x, encoder_output, encoder_output) x = self.layer_norm2(residual + x) residual = x x = self.pos_ffn(x) x = F.gelu(x) x = self.pos_ffn(x) x = self.layer_norm3(residual + x) return x def _get_mask(self, x): mask = torch.ones(self.seq_len, self.seq_len).to(x.device) mask = torch.tril(mask) return mask class Informer(nn.Module): def __init__(self, input_size, output_size, hidden_size, num_encoder_layers, num_decoder_layers, num_heads, seq_len): super(Informer, self).__init__() self.input_size = input_size self.output_size = output_size self.hidden_size = hidden_size self.num_encoder_layers = num_encoder_layers self.num_decoder_layers = num_decoder_layers self.num_heads = num_heads self.seq_len = seq_len self.encoder_layers = nn.ModuleList() self.decoder_layers = nn.ModuleList() for i in range(num_encoder_layers): self.encoder_layers.append(Encoder(input_size, hidden_size, num_heads, seq_len)) for i in range(num_decoder_layers): self.decoder_layers.append(Decoder(input_size, hidden_size, num_heads, seq_len)) self.linear = nn.Linear(hidden_size, output_size) def forward(self, x): encoder_output = x for encoder_layer in self.encoder_layers: encoder_output = encoder_layer(encoder_output) decoder_output = x[:, -1:, :] for decoder_layer in self.decoder_layers: decoder_output = decoder_layer(decoder_output, encoder_output) output = self.linear(decoder_output[:, -1:, :]) return output ``` 4. 定义数据预处理函数 ```python def prepare_data(data, seq_len, train_ratio): data = data.values scaler = StandardScaler() data = scaler.fit_transform(data) data_x = [] data_y = [] for i in range(len(data) - seq_len): data_x.append(data[i:i+seq_len]) data_y.append(data[i+seq_len]) data_x = np.array(data_x) data_y = np.array(data_y) train_size = int(len(data_x) * train_ratio) train_x = data_x[:train_size, :, :] train_y = data_y[:train_size, :] test_x = data_x[train_size:, :, :] test_y = data_y[train_size:, :] return train_x, train_y, test_x, test_y, scaler ``` 5. 定义训练函数 ```python def train(model, train_x, train_y, test_x, test_y, epochs, lr): optimizer = torch.optim.Adam(model.parameters(), lr=lr) loss_func = nn.MSELoss() train_loss_list = [] test_loss_list = [] for epoch in tqdm(range(epochs)): model.train() train_loss = 0 for i in range(train_x.shape[0]): optimizer.zero_grad() x = torch.Tensor(train_x[i]).unsqueeze(0) y = torch.Tensor(train_y[i]).unsqueeze(0) output = model(x) loss = loss_func(output, y) loss.backward() optimizer.step() train_loss += loss.item() train_loss /= train_x.shape[0] train_loss_list.append(train_loss) model.eval() test_loss = 0 with torch.no_grad(): for i in range(test_x.shape[0]): x = torch.Tensor(test_x[i]).unsqueeze(0) y = torch.Tensor(test_y[i]).unsqueeze(0) output = model(x) loss = loss_func(output, y) test_loss += loss.item() test_loss /= test_x.shape[0] test_loss_list.append(test_loss) print('Epoch [{}/{}], train loss: {:.4f}, test loss: {:.4f}'.format(epoch+1, epochs, train_loss, test_loss)) return train_loss_list, test_loss_list ``` 6. 载入数据集并调用训练函数 ```python data = pd.read_csv('data.csv', index_col=0) train_x, train_y, test_x, test_y, scaler = prepare_data(data, seq_len=96, train_ratio=0.8) model = Informer(input_size=train_x.shape[-1], output_size=train_y.shape[-1], hidden_size=256, num_encoder_layers=2, num_decoder_layers=2, num_heads=8, seq_len=96) train_loss_list, test_loss_list = train(model, train_x, train_y, test_x, test_y, epochs=50, lr=0.001) ``` 7. 绘制损失曲线 ```python plt.plot(train_loss_list, label='train loss') plt.plot(test_loss_list, label='test loss') plt.legend() plt.show() ``` 这样就可以使用PyTorch实现Informer模型了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值