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:
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?
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