In this tutorial, we’ll dive into the exciting world of stock price prediction using Long Short-Term Memory (LSTM) neural networks. LSTM is a powerful deep-learning technique for time series forecasting, making it ideal for predicting stock prices.
Getting the Data
To get started, we need historical stock price data. We can obtain this data from sources like Yahoo Finance or Alpha Vantage. For this tutorial, we’ll use a dataset covering IBM’s stock prices from 2006 to 2018.
import pandas as pd
df = pd.read_csv("IBM_2006–01–01_to_2018–01–01.csv", index_col='Date', parse_dates=["Date"])
Data Visualization
Let’s visualize our dataset to understand the stock price trends. We’ll plot the training set (before 2017) and the test set (2017 and beyond) separately.
import matplotlib.pyplot as plt
# Plot the training set
df["High"][:'2016'].plot(figsize=(16, 4), legend=True)
# Plot the test set
df["High"]['2017':].plot(figsize=(16, 4), legend=True)
plt.legend(['Training set (Before 2017)', 'Test set (2017 and beyond)'])
plt.title('IBM stock price')
plt.show()
Data Preprocessing
Before feeding the data into our LSTM model, we need to preprocess it. We’ll use Min-Max scaling to scale the stock prices to a range between 0 and 1.
from sklearn.preprocessing import MinMaxScaler
sc = MinMaxScaler(feature_range=(0, 1))
training_set_scaled = sc.fit_transform(trainning_set)
Creating the Training Data
We’ll create our training data by creating sequences of stock prices and their corresponding labels. Each sequence will contain the stock prices of the previous 60 days.
# here we are seperating the data
trainning_set = df[:'2016'].iloc[:,1:2].values
test_set = df['2017':].iloc[:,1:2].valuesX_train = []
y_train = []
for i in range(60, len(training_set_scaled)):
X_train.append(training_set_scaled[i - 60:i, 0])
y_train.append(training_set_scaled[i, 0])
X_train, y_train = np.array(X_train), np.array(y_train)
X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
Building the LSTM Model
Now, it’s time to build our LSTM model. We’ll create a sequential model with multiple LSTM layers and dropout for regularization.
from keras.models import Sequential
from keras.layers import LSTM, Dropout, Denseregressor = Sequential()
# First LSTM layer with Dropout regularisation
regressor.add(LSTM(units=100, return_sequences=True, input_shape=(X_train.shape[1],1)))
regressor.add(Dropout(0.3))
regressor.add(LSTM(units=80, return_sequences=True))
regressor.add(Dropout(0.1))
regressor.add(LSTM(units=50, return_sequences=True))
regressor.add(Dropout(0.2))
regressor.add(LSTM(units=30))
regressor.add(Dropout(0.3))
regressor.add(Dense(units=1))
regressor.compile(optimizer='adam',loss='mean_squared_error')
Training the Model
With our model architecture in place, let’s train it on our prepared training data.
regressor.fit(X_train, y_train, epochs=50, batch_size=32)
Making Predictions
Now, we can make predictions on our test data.
# pre-processing the data
dataset_total = pd.concat((df["High"][:'2016'],df["High"]['2017':]),axis=0)
inputs = dataset_total[len(dataset_total)-len(test_set) - 60:].values
inputs = inputs.reshape(-1,1)
inputs = sc.transform(inputs)# making the test data
X_test = []
for i in range(60,len(inputs)):
X_test.append(inputs[i-60:i,0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0],X_test.shape[1],1))
predicted_stock_price = regressor.predict(X_test)
predicted_stock_price = sc.inverse_transform(predicted_stock_price)
Visualizing the Predictions
Let’s visualize our model’s predictions against the actual test data.
def plot_prediction(test,prediction):
plt.plot(test,color='red',label="Real IBM Stock Price")
plt.plot(prediction, color="blue",label="predicted IBM Stock price")
plt.title("IBM Stock Price Prediction")
plt.xlabel("Time")
plt.ylabel("IBM Stock Price")
plt.legend()
plt.show()
# now we'll use this function to visualize our test and predicted dataplot_prediction(test_set,predicted_stock_price)
Our plot is with Time.
Evaluating Model Performance
Finally, let’s evaluate our model’s performance using the Root Mean Squared Error (RMSE).
def return_rmse(test,predicted):
rmse = math.sqrt(mean_squared_error(test,predicted))
print("The root mean sqaured error is {}.".format(rmse))
The root mean sqaured error is 1.3337922543779552.
Now let’s try with GRU
regressorGRU = Sequential()regressorGRU.add(GRU(units=100, return_sequences=True, input_shape=(X_train.shape[1],1), activation='tanh'))
regressorGRU.add(Dropout(0.3))
# Second GRU layer
regressorGRU.add(GRU(units=80, return_sequences=True, input_shape=(X_train.shape[1],1), activation='tanh'))
regressorGRU.add(Dropout(0.2))
# Third GRU layer
regressorGRU.add(GRU(units=50, return_sequences=True, input_shape=(X_train.shape[1],1), activation='tanh'))
regressorGRU.add(Dropout(0.1))
# Fourth GRU layer
regressorGRU.add(GRU(units=30, activation='tanh'))
regressorGRU.add(Dropout(0.2))
# The output layer
regressorGRU.add(Dense(units=1))
# Compiling the RNN
regressorGRU.compile(optimizer='adam',loss='mean_squared_error')
# Fitting to the training set
regressorGRU.fit(X_train,y_train,epochs=50,batch_size=150)
Predict the values
X_test = []
for i in range(60,len(inputs)):
X_test.append(inputs[i-60:i,0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0],X_test.shape[1],1))
predicted_stock_price = regressorGRU.predict(X_test)
predicted_stock_price = sc.inverse_transform(predicted_stock_price)
Visualize the predicted and real data
plot_prediction(test_set,predicted_stock_price)
GRU has comparatively less computation and a very recent model(2014), and is gaining great popularity
NOTE: Making a model great, is a thing which you can do, like trying various hit and trails, optimizing hyperparameter, and pre-processing.
Congratulations! You’ve successfully built an LSTM and GRU model for stock price prediction. This tutorial covered the entire process, from data loading to evaluation.
In practice, you can further fine-tune your model and explore different hyperparameters to improve its performance. Happy forecasting!