我正在使用PyTorch构建LSTM模型来预测时间序列数据。我使用滞后特征将前n步作为输入传递给网络进行训练。我将数据分成三组,即训练-验证-测试集,并使用前两组来训练模型。我的验证函数从验证数据集中获取数据,使用DataLoaders和TensorDataset类将其传递给LSTM模型来计算预测值。最初,我得到了相当不错的结果,R2值在0.85-0.95之间。
然而,我对这个验证函数是否也适用于测试模型性能感到不安。因为该函数现在使用DataLoader中的实际X值(即时间滞后特征)来预测y^值(即预测目标值),而不是使用预测的y^值作为下一个预测的特征。这种情况似乎与现实相去甚远,特别是如果你预测更长时间段(比如3-6个月)的时间序列数据。
我目前对解决这个问题和定义一个函数来预测未来值而不是测试集中的实际值感到有些困惑。我有以下的
然而,我对这个验证函数是否也适用于测试模型性能感到不安。因为该函数现在使用DataLoader中的实际X值(即时间滞后特征)来预测y^值(即预测目标值),而不是使用预测的y^值作为下一个预测的特征。这种情况似乎与现实相去甚远,特别是如果你预测更长时间段(比如3-6个月)的时间序列数据。
我目前对解决这个问题和定义一个函数来预测未来值而不是测试集中的实际值感到有些困惑。我有以下的
predict
函数,它可以进行一步预测,但我还没有真正弄清楚如何使用DataLoader来预测整个测试数据集。 def predict(self, x):
# convert row to data
x = x.to(device)
# make prediction
yhat = self.model(x)
# retrieve numpy array
yhat = yhat.to(device).detach().numpy()
return yhat
以下是我分割和加载数据集的方法、LSTM模型构造函数以及验证函数。如果您需要更多信息,请随时联系我。
数据集的分割和加载
def create_tensor_datasets(X_train_arr, X_val_arr, X_test_arr, y_train_arr, y_val_arr, y_test_arr):
train_features = torch.Tensor(X_train_arr)
train_targets = torch.Tensor(y_train_arr)
val_features = torch.Tensor(X_val_arr)
val_targets = torch.Tensor(y_val_arr)
test_features = torch.Tensor(X_test_arr)
test_targets = torch.Tensor(y_test_arr)
train = TensorDataset(train_features, train_targets)
val = TensorDataset(val_features, val_targets)
test = TensorDataset(test_features, test_targets)
return train, val, test
def load_tensor_datasets(train, val, test, batch_size=64, shuffle=False, drop_last=True):
train_loader = DataLoader(train, batch_size=batch_size, shuffle=shuffle, drop_last=drop_last)
val_loader = DataLoader(val, batch_size=batch_size, shuffle=shuffle, drop_last=drop_last)
test_loader = DataLoader(test, batch_size=batch_size, shuffle=shuffle, drop_last=drop_last)
return train_loader, val_loader, test_loader
Class LSTM
class LSTMModel(nn.Module):
def __init__(self, input_dim, hidden_dim, layer_dim, output_dim, dropout_prob):
super(LSTMModel, self).__init__()
self.hidden_dim = hidden_dim
self.layer_dim = layer_dim
self.lstm = nn.LSTM(
input_dim, hidden_dim, layer_dim, batch_first=True, dropout=dropout_prob
)
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, x, future=False):
h0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_()
c0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_()
out, (hn, cn) = self.lstm(x, (h0.detach(), c0.detach()))
out = out[:, -1, :]
out = self.fc(out)
return out
验证(在训练器类中定义)
def validation(self, val_loader, batch_size, n_features):
with torch.no_grad():
predictions = []
values = []
for x_val, y_val in val_loader:
x_val = x_val.view([batch_size, -1, n_features]).to(device)
y_val = y_val.to(device)
self.model.eval()
yhat = self.model(x_val)
predictions.append(yhat.cpu().detach().numpy())
values.append(y_val.cpu().detach().numpy())
return predictions, values