如何用LSTM模型预测时序数据的后续多步值(t+1至t+n)
实现LSTM模型的多步时序预测
先梳理下你已经完成的准备工作:
1. 数据处理环节
你已经用MinMaxScaler(feature_range=(0, 1))对时序数据做了归一化,并且通过自定义的create_dataset函数(设置look_back=20)完成了训练集、验证集、测试集的划分,还处理成了LSTM需要的输入格式。相关代码如下:
def create_dataset(signal_data, look_back=1): dataX, dataY = [], [] for i in range(len(signal_data) - look_back): dataX.append(signal_data[i:(i + look_back), 0]) dataY.append(signal_data[i + look_back, 0]) return np.array(dataX), np.array(dataY) train_size = int(len(signal_data) * 0.80) test_size = len(signal_data) - train_size - int(len(signal_data) * 0.05) val_size = len(signal_data) - train_size - test_size train = signal_data[0:train_size] val = signal_data[train_size:train_size+val_size] test = signal_data[train_size+val_size:len(signal_data)] x_train, y_train = create_dataset(train, look_back) x_val, y_val = create_dataset(val, look_back) x_test, y_test = create_dataset(test, look_back)
2. LSTM模型结构
你搭建的双层LSTM模型结构如下:
model = Sequential() model.add(LSTM(64, input_shape=(None, 1), return_sequences=True)) model.add(Dropout(l)) model.add(LSTM(64)) model.add(Dropout(l)) model.add(Dense(64)) model.add(Dropout(l)) model.add(Dense(1))
现在你需要基于x_test[-1](对应t时刻的20步序列)预测t+1到t+n的多步值,这里提供两种常用的实现思路:
方法一:递归式多步预测(逐步滚动)
这是最适合你当前已训练模型的方案——不需要修改模型结构或重新训练,用前一步的预测结果作为下一次输入序列的末尾值,滚动更新输入直到完成n步预测。代码示例如下:
import numpy as np n_steps = 10 # 替换成你实际需要预测的步数 predictions = [] # 初始化输入序列,确保形状和模型输入匹配:(batch_size, look_back, features) current_sequence = x_test[-1].reshape(1, 20, 1) for _ in range(n_steps): # 预测当前序列的下一个值 next_pred = model.predict(current_sequence, verbose=0)[0][0] predictions.append(next_pred) # 滚动更新序列:移除最前面的旧值,把新预测值添加到序列末尾 current_sequence = np.roll(current_sequence, shift=-1, axis=1) current_sequence[0, -1, 0] = next_pred # 最终predictions列表就是t+1到t+n的预测值,长度为n_steps
注意:这种方法的误差会随着预测步数增加而累积,步数越多误差可能越大,适合短期多步预测场景。
方法二:直接多步预测(修改模型结构)
如果想要避免递归的误差累积,可以调整模型让它一次性输出n步预测结果,但需要重新构建数据集和训练模型:
- 先修改数据集生成函数,让目标值变成输入序列对应的后续n步值:
def create_multistep_dataset(signal_data, look_back=1, n_steps=1): dataX, dataY = [], [] # 调整循环边界,确保能取到完整的n步目标值 for i in range(len(signal_data) - look_back - n_steps + 1): dataX.append(signal_data[i:(i + look_back), 0]) # 提取后续n步作为目标输出 dataY.append(signal_data[i + look_back : i + look_back + n_steps, 0]) return np.array(dataX), np.array(dataY)
- 修改模型输出层,让输出单元数等于预测步数n_steps:
model = Sequential() model.add(LSTM(64, input_shape=(None, 1), return_sequences=True)) model.add(Dropout(l)) model.add(LSTM(64)) model.add(Dropout(l)) model.add(Dense(64)) model.add(Dropout(l)) model.add(Dense(n_steps)) # 输出单元数设置为预测步数
- 重新训练模型后,直接用
x_test[-1]就能得到全部n步预测值:
multistep_pred = model.predict(x_test[-1].reshape(1, 20, 1), verbose=0)[0] # multistep_pred就是t+1到t+n的预测值,形状为(n_steps,)
这种方法的优点是误差不会累积,但模型只能固定预测设定的n步,灵活性不如递归法。
内容的提问来源于stack exchange,提问作者GoBackess




