This is an another attempt to predict the future stocks of a certain company. In this project, an artificial recurrent neural network called Long Short Term Memory (LSTM) will be now use to predict the closing stock price of a corporation (Apple Inc.).
The project goes through following steps: Data generation, Data pre-processing and feature selection, Baseline prediction, LSTM training and demonstration of results.
Problem:
Dataset:
Source: Yahoo Finance
# Import libraries
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# For calculation and web scrape
import math
import pandas_datareader as web
# For preprocessing and model building
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense, LSTM
# Style settings
sns.set()
plt.style.use('fivethirtyeight')
# Get stack quote
df = web.DataReader('AAPL', data_source = 'yahoo', start = '2012-01-01', end = '2020-07-13')
# Show the data
df.head()
# Check data dimension
df.shape
# Visualize the closing price
plt.figure(figsize = (16, 8))
plt.title('Close Price History')
plt.plot(df['Close'])
plt.xlabel('Date', fontsize = 18)
plt.ylabel('Close Price USD', fontsize = 18)
plt.show()
# Create new dataframe with the 'Close' column
data = df.filter(['Close'])
# Convert dataframe into a numpy array
dataset = data.values
# Get the number of rows to train the model on # math.ceil -> Round up
training_data_len = math.ceil(len(dataset)* 0.8)
# Check the data length
training_data_len
# Scale the data
scaler = MinMaxScaler(feature_range = (0,1))
# Fit and transform the data
scaled_data = scaler.fit_transform(dataset)
# Check the data
scaled_data;
# Create the training dataset
# Create the scaled training dataset
train_data = scaled_data[0: training_data_len, :] # Get all the data from 0 to training_data_len, all column
# Split the data
X_train = []
y_train = []
for i in range (60, len(train_data)):
X_train.append(train_data[i - 60:i, 0])
y_train.append(train_data[i, 0])
if i <=61:
print(X_train) # Past 60 days
print(y_train) # target label
print()
# Convert the X_train and y_train to numpy arrays
X_train, y_train = np.array(X_train), np.array(y_train)
# Reshape the data # LSTM needs 3 dimensional data
X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
X_train.shape
# Build the LSTM model # X_train.shape[1] = 60
model = Sequential()
# First layer
model.add(LSTM(50, return_sequences = True, input_shape = (X_train.shape[1], 1)))
# Second layer
model.add(LSTM(50, return_sequences = False))
# Third layer
model.add(Dense(25))
# Last layer
model.add(Dense(1))
# Compile the model
model.compile(optimizer = 'adam', loss = 'mean_squared_error')
# Train the model
model.fit(X_train, y_train, batch_size = 1, epochs = 1)
# Create the testing dataset
# Create a new array containing scaled values from index 1656 to 2145
test_data = scaled_data[training_data_len - 60:, :]
# Create the datasets X_test and y_test
X_test = []
y_test = dataset[training_data_len:, :] # 60 first actual values, not scaled
for i in range(60, len(test_data)):
X_test.append(test_data[i - 60:i, 0]) # Past 60 values
# Convert the data to a numpy array to be able to use in LSTM model
X_test = np.array(X_test)
# Check the shape
X_test;
# Reshape the data for LSTM model. It needs 3 dimensional data
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
# Get the models predicted price values
predictions = model.predict(X_test)
# Get the inverse shape of the data
predictions = scaler.inverse_transform(predictions)
# Evaluate the model
# Get the root mean squared error (RMSE)
rmse = np.sqrt(np.mean(predictions - y_test)**2)
# Show the rmse
print('rmse:', rmse)
# Plot the data
train = data[:training_data_len]
valid = data[training_data_len:]
valid['Predictions'] = predictions
# Visualize the data
plt.figure(figsize = (18, 8))
plt.title('Model')
plt.xlabel('Date')
plt.ylabel('Close Price USD', fontsize = 18)
plt.plot(train['Close'])
plt.plot(valid[['Close', 'Predictions']])
plt.legend(['Train', 'Val', 'Predictions'], loc = 'lower right')
plt.show()
# Show the valid (Actual price) and predicted prices
valid
# Get stack quote
apple_quote = web.DataReader('AAPL', data_source = 'yahoo', start = '2012-01-01', end = '2020-07-13')
# Create a new dataframe
new_df = apple_quote.filter(['Close'])
# Get the last 60 days closing price values and convert the dataframe to an array
last_60_days = new_df[-60:].values
# Scale the data to be values between 0 and 1
last_60_days_scaled = scaler.transform(last_60_days)
# Create an empty list
X_test = []
# Append the past 60 days
X_test.append(last_60_days_scaled)
# Convert the X_test dataset 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 predicted scaled price
pred_price = model.predict(X_test)
# Undo the scaling
pred_price = scaler.inverse_transform(pred_price)
print('Predicted price at July 14, 2020 is', np.round(pred_price))
# Get stack quote
apple_quote_2 = web.DataReader('AAPL', data_source = 'yahoo', start = '2020-07-14', end = '2020-07-14')
# Show the actual price
print('Actual price at July 14, 2020 is', np.round(apple_quote_2['Close'][1]))
The project concludes that LSTM neural network can be good alternative for stock market time series prediction among other machine learning methods.Further testing of different parameter and architecture settings are needed to improve the accuracy.