Please help, unable to use LSTM correctly

can someone please help me figure out whats wrong here with my simple LSTM forecasting model?

Thanks Deepti, Just checking if anyone was here. I’m using using LSTM model to predict bitcoin price as an example. The results are totally off when I use this model. See Code below:

##LSTM Time Series Forecasting Tutorial in Python
##https://www.youtube.com/watch?v=c0k-YLQGKjY&t=38s

import requests
import zipfile
import io
import pandas as pd
from datetime import datetime, timedelta
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout, InputLayer
from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.losses import MeanSquaredError
from tensorflow.keras.metrics import RootMeanSquaredError
from tensorflow.keras.optimizers import Adam
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import load_model

def download_and_save_binance_data(symbol, interval, start_date, end_date, filename):
base_url = “https://data.binance.vision/data/spot/monthly/klines/
current_date = start_date

all_data =

while current_date <= end_date:
year_month = current_date.strftime(‘%Y-%m’)
url = f"{base_url}{symbol}/{interval}/{symbol}-{interval}-{year_month}.zip"
print(f"Downloading: {url}")

response = requests.get(url)
if response.status_code == 200:
with zipfile.ZipFile(io.BytesIO(response.content)) as z:
file_name = z.namelist()[0]
with z.open(file_name) as f:
df = pd.read_csv(f, header=None)
all_data.append(df)
else:
print(f"Failed to download: {url}")

Move to the next month

current_date += timedelta(days=32)
current_date = current_date.replace(day=1)

Concatenate all dataframes

full_data = pd.concat(all_data, ignore_index=True)

Assign column names as per Binance kline format

full_data.columns = [‘timestamp’, ‘open’, ‘high’, ‘low’, ‘close’, ‘volume’, ‘close_time’, ‘quote_asset_volume’, ‘number_of_trades’, ‘taker_buy_base_asset_volume’, ‘taker_buy_quote_asset_volume’, ‘ignore’]
full_data[‘timestamp’] = pd.to_datetime(full_data[‘timestamp’], unit=‘ms’)
full_data.set_index(‘timestamp’, inplace=True)

Save to CSV

full_data.to_csv(filename)
print(f"Data saved to {filename}")

Define the parameters

symbol = ‘BTCUSDT’
interval = ‘1d’
start_date = datetime(2021, 1, 1)
end_date = datetime(2024, 6, 14)
filename = ‘BTCUSDT_1d_20210101_20240614.csv’

Download and save the data

download_and_save_binance_data(symbol, interval, start_date, end_date, filename)

df = pd.read_csv(‘BTCUSDT_1d_20210101_20240614.csv’)
df.head()

#changing index to the time
df.index = pd.to_datetime(df[‘timestamp’], format = ‘%Y-%m-%d’)
df[:10]

temp = df[‘close’]
temp.plot()

Function to create sequences

def df_to_X_y(data, window_size):
X =
y =
for i in range(len(data) - window_size):
X.append(data[i:i+window_size])
y.append(data[i+window_size])
return np.array(X), np.array(y)

Create sequences

WINDOW_SIZE = 21
X, y = df_to_X_y(temp, WINDOW_SIZE)
X.shape, y.shape

X_train, y_train = X[:800], y[:800]
X_val, y_val = X[800:1000], y[800:1000]
X_test, y_test = X[1000:], y[1000:]
X_train.shape, y_train.shape, X_val.shape, y_val.shape, X_test.shape, y_test.shape

Reshape the data for LSTM

Define the improved model

model = Sequential()
model.add(InputLayer((WINDOW_SIZE, 1))) #
model.add(LSTM(64, return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(64))
model.add(Dropout(0.2))
model.add(Dense(32, activation=‘relu’))
model.add(Dense(1, activation=‘linear’))

model.summary()

Compile the model

cp = ModelCheckpoint(‘model/’, save_best_only=True)
model.compile(loss=MeanSquaredError(), optimizer=Adam(learning_rate=0.001), metrics=[RootMeanSquaredError()])

cp1 = ModelCheckpoint(‘model1/’, save_best_only=True)
model.compile(loss=MeanSquaredError(), optimizer=Adam(learning_rate=0.001), metrics=[RootMeanSquaredError()])

model.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=10, batch_size = 32, callbacks=[cp1])

Here’s some output:
Epoch 1/10 25/25 [==============================] - 10s 284ms/step - loss: 1459104256.0000 - root_mean_squared_error: 38198.2227 - val_loss: 750331584.0000 - val_root_mean_squared_error: 27392.1816 Epoch 2/10 25/25 [==============================] - 6s 246ms/step - loss: 1455859456.0000 - root_mean_squared_error: 38155.7266 - val_loss: 747881664.0000 - val_root_mean_squared_error: 27347.4238 Epoch 3/10 25/25 [==============================] - 6s 263ms/step - loss: 1452826624.0000 - root_mean_squared_error: 38115.9609 - val_loss: 745344064.0000 - val_root_mean_squared_error: 27300.9902 Epoch 4/10 25/25 [==============================] - 6s 250ms/step - loss: 1449219072.0000 - root_mean_squared_error: 38068.6094 - val_loss: 742698816.0000 - val_root_mean_squared_error: 27252.5000 Epoch 5/10 25/25 [==============================] - 7s 282ms/step - loss: 1445720192.0000 - root_mean_squared_error: 38022.6250 - val_loss: 739911040.0000 - val_root_mean_squared_error: 27201.3047 Epoch 6/10 25/25 [==============================] - 5s 226ms/step - loss: 1442188160.0000 - root_mean_squared_error: 37976.1523 - val_loss: 737020800.0000 - val_root_mean_squared_error: 27148.1270 Epoch 7/10 25/25 [==============================] - 7s 287ms/step - loss: 1438715520.0000 - root_mean_squared_error: 37930.4023 - val_loss: 734045888.0000 - val_root_mean_squared_error: 27093.2812 Epoch 8/10 25/25 [==============================] - 5s 226ms/step - loss: 1434402176.0000 - root_mean_squared_error: 37873.5000 - val_loss: 730951424.0000 - val_root_mean_squared_error: 27036.1133 Epoch 9/10 25/25 [==============================] - 8s 341ms/step - loss: 1430457216.0000 - root_mean_squared_error: 37821.3867 - val_loss: 727728896.0000 - val_root_mean_squared_error: 26976.4512 Epoch 10/10 25/25 [==============================] - 5s 222ms/step - loss: 1426157952.0000 - root_mean_squared_error: 37764.5039 - val_loss: 724388672.0000 - val_root_mean_squared_error: 26914.4688

model1 = load_model(‘model1/’)
train_predictions = model1.predict(X_train).flatten()
train_results = pd.DataFrame(data={‘Train Predictions’:train_predictions, ‘Actuals’:y_train})
train_results

25/25 [==============================] - 1s 3ms/step

Train Predictions Actuals

0 1147.007568 32945.17
1 1147.007568 32078.00
2 1147.007568 32259.90
3 1147.007568 32254.20
4 1147.007568 32467.77
… … …
795 1147.007568 27261.07
796 1147.007568 28348.60
797 1147.007568 28028.53
798 1147.007568 28465.36
799 1147.007568 28452.73

can I know reason behind your choice of metric?

Mean squared error? It’s a standard loss mode I thought

Sorry to interrupt but the metric is not equal to loss:

1 Like

What do you mean by metric? The dependent parameter I’m using is the last 21 days of price data.

yes balaji it is not same, but I meant why metric choice was root mean square error precisely?

1 Like

Hi @Amit_Misra1

can you share the link where you have run the codes?

Window_size of 21 you used as you mentioned the above reason is understandable.

I want to see your output of create sequence.

Regards
DP