I trained a BI-LSTM model on stock prices. For this model, I did 2 approaches of backtesting :
With the 1) method, results look like pretty good whith a RMSE near of 0.25 which can tell me that the model has good performance on test set, as follows:
The code used:
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)
predictions = model.predict(x_test)
scaler2=dictio_scalers[symbols]
predictions = scaler2.inverse_transform(predictions)
But using the 2) method, the model predicts almost a straight line,
Code used:
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)
As the model performs really well with the whole test data, if I want to make predictions from each day to each day, I was expecting a slight drop in performance but not a straight line!
Did I Make a mistake in my code?
NB: Here is the code I use to build the model (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)
Your two approaches are two different problems. It depends on how long the future you want to predict.
With your training code, it was designed for the model to learn to predict just one step future. You then feed the future ground truth data as input to the model so the values which was fed into model in the validation phase look likely to the data which was trained that's why it gives a good performance.
With the your second approach, that's long-term forecasting problem which you want the model to predict N-step future base on K-step in the past which is clearly harder compare to the first one and this is not what you trained your model to learn. But you still can do it with LSTM, take a look at recursive forecasting.