为何BI-LSTM模型滚动预测验证集时输出近乎直线?
BI-LSTM股票预测模型滚动回测异常排查
问题背景
我基于股票价格训练了一个BI-LSTM模型,采用两种回测方法验证效果:
- 方法1:直接对整个验证集调用
predict函数,与真实数据对比,模型表现良好,RMSE约为0.25 - 方法2:基于每日预测结果滚动预测次日及后续数据,模型输出近乎直线,远低于预期性能,怀疑代码存在问题
方法1(静态回测)代码
pas = 20 train_len=5586 test_data = df_scaled[train_len - pas: ] print ('len(test_data):', len(test_data)) # Create the data sets x_test and y_test x_test = [] y_test = df[train_len:, :] for i in range(pas, len(test_data)): x_test.append(test_data[i-pas:i, 0]) # Convert the data to a numpy array x_test = np.array(x_test) # Reshape the data x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1], 1 )) # Get the models predicted price values fichier_modele = f"{symbols}.h5" model = load_model(fichier_modele) scaler2=dictio_scalers[symbols] predictions = scaler2.inverse_transform(predictions)
方法2(滚动回测)代码
Pred_Array_Global=df[int(train_len)-pas:int(train_len)] # Get the models predicted price values fichier_modele = f"{symbols}.h5" model = load_model(fichier_modele) scaler2=dictio_scalers[symbols] Pred_Array_Global=scaler2.fit_transform(Pred_Array_Global) for i in range(0,len(test['Close'])): Pred_Array_Global=np.array(Pred_Array_Global) Pred_Array=Pred_Array_Global[i:i+pas] # Convert the data to a numpy array Pred_Array = np.array(Pred_Array) # Reshape the data Pred_Array_Input = np.reshape(Pred_Array,(1,pas, 1 )) predictions = model.predict(Pred_Array_Input,verbose=0) Pred_Array_Global=np.append(Pred_Array_Global,predictions) Pred_Array_Global=Pred_Array_Global.reshape(-1,1) Pred_Array_Global = scaler2.inverse_transform(Pred_Array_Global)
模型构建代码(epochs=2000,batch_size=256)
model = Sequential() model.add(Bidirectional(LSTM(units=128, input_shape=(20, 1)))) model.add(Dense(1)) model.compile(optimizer='adam', loss='mean_squared_error') model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs,verbose=0) fichier_modele = f"{symbols}.h5" model.save(fichier_modele)
问题排查与修正建议
1. 数据缩放错误(核心问题)
方法2中使用scaler2.fit_transform(Pred_Array_Global)是错误的:训练时的scaler是基于训练集数据拟合的,滚动预测时必须复用这个已拟合好的scaler,仅调用transform方法。重新fit会改变缩放规则,导致模型输入与训练时的分布完全不一致,直接引发预测失效。
修正代码:
# 替换原fit_transform为transform Pred_Array_Global=scaler2.transform(Pred_Array_Global)
2. 双向LSTM的适配问题
模型使用了Bidirectional(LSTM),双向LSTM在训练时会利用序列的前后双向信息,但滚动预测是单向递推(只能用历史及已预测数据,无法获取未来信息),这会导致模型的双向设计在滚动场景下无法发挥作用,甚至因为训练/推理的信息不对称导致预测偏差累积。
建议:若要做滚动预测,可将模型改为单向LSTM,或保留双向但明确模型仅利用历史信息(部分框架支持双向LSTM的推理模式调整,但实现较复杂)。
3. 误差累积问题
滚动预测中,随着迭代次数增加,输入序列会逐渐被预测值替代(而非真实历史数据),误差会不断累积。这是滚动预测的固有问题,但合理的模型设计能缓解此问题,比如加入真实特征(如成交量、宏观数据),或使用多步预测策略替代单步滚动。
内容的提问来源于stack exchange,提问作者Rgrvkfer
相关产品推荐
相关产品推荐

