Predicting Microsoft Stock Price with Keras
Using a Neural Network architecture (LSTM) to predict Microsoft Stock Price
- Importing dependecies
- Importing the Stock Price Dataset
- Data Exploration
- Adding some Features
- Model Building
- Labeling:
- LSTM Model
- Model Prediction
from IPython.core.debugger import set_trace
import pandas as pd
import numpy as np
import os
import matplotlib.pyplot as plt
import datetime
plt.style.use(style="seaborn")
%matplotlib inline
df = pd.read_csv("MSFT-1Y-Hourly.csv", sep=",")
df.isna().any()
df.set_index("date", drop=True, inplace=True)
df.info()
df
df = df[["close"]]
df.describe()
plt.figure(1, figsize=(16, 8))
plt.plot(df.close)
df["returns"] = df.close.pct_change()
df.head()
df["log_returns"] = np.log(1 + df["returns"])
df.head()
plt.figure(figsize=(16, 8))
plt.plot(df.log_returns)
df.dropna(inplace=True)
X = df[["close", "log_returns"]].values
X[:10]
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1)).fit(X)
X_scaled = scaler.transform(X)
X_scaled[:10]
y = [x[0] for x in X_scaled]
y[:10]
split = int(len(X_scaled) * 0.8)
print(split)
X_train = X_scaled[:split]
X_test = X_scaled[split : len(X_scaled)]
y_train = y[:split]
y_test = y[split : len(y)]
assert len(X_train) == len(y_train)
assert len(X_test) == len(y_test)
As we're going to use an LSTM architecture, we know that it has memory and that it is maintined by setting a time step basiclly how many steps in the past we want the LSTM to use.
The time step refers to how many steps in the time we want the backpropagation algorithm to use when calculating the gradients for weights updates during training.
So we can use a method to create both the timestep and the ouput variable, t+1
n = 3
Xtrain = []
Xtest = []
ytrain = []
ytest = []
for i in range(n, len(X_train)):
Xtrain.append(X_train[i - n : i, : X_train.shape[1]])
ytrain.append(y_train[i])
for i in range(n, len(X_test)):
Xtest.append(X_test[i - n : i, : X_test.shape[1]])
ytest.append(y_test[i])
df.head()
Xtrain[0]
ytrain[0]
val = np.array(ytrain[0])
val = np.c_[val, np.zeros(val.shape)]
scaler.inverse_transform(val)
In an LSTM network the input for each LSTM layer needs to contain the following network:
The number of observations
The time steps
The features
Therefore we need to add a temporel dimension compared to a classical network (number of observation, number of steps, number of feature per step)
Xtrain, ytrain = (np.array(Xtrain), np.array(ytrain))
Xtrain = np.reshape(Xtrain, (Xtrain.shape[0],Xtrain.shape[1],Xtrain.shape[2]))
Xtest, ytest = (np.array(Xtest), np.array(ytest))
Xtest = np.reshape(Xtest, (Xtest.shape[0],Xtest.shape[1],Xtest.shape[2]))
print(Xtrain.shape)
print(ytrain.shape)
print('-------')
print(Xtest.shape)
print(ytest.shape)
from keras.models import Sequential
from keras.layers import LSTM, Dense
model =Sequential()
model.add(LSTM(4, input_shape=(Xtrain.shape[1],Xtrain.shape[2])))
model.add(Dense(1))
model.compile(loss="mean_squared_error", optimizer="adam")
model.fit(Xtrain, ytrain, epochs=100, validation_data=(Xtest,ytest), batch_size=16, verbose=1)
model.summary()
trainPredict = model.predict(Xtrain)
testPredict = model.predict(Xtest)
trainPredict = np.c_[trainPredict, np.zeros(trainPredict.shape)]
testPredict = np.c_[testPredict, np.zeros(testPredict.shape)]
trainPredict = scaler.inverse_transform(trainPredict)
trainPredict = [x[0] for x in trainPredict]
testPredict = scaler.inverse_transform(testPredict)
testPredict = [x[0] for x in testPredict]
print(trainPredict[:5])
print(testPredict[:5])
#Plot the train & test Predict Features
from sklearn.metrics import mean_squared_error
trainScore = mean_squared_error([x[0][0] for x in Xtrain],trainPredict, squared= False )
print("Train Score : %.2f RMSE" % (trainScore))
testScore = mean_squared_error([x[0][0] for x in Xtest],testPredict, squared= False )
print("Train Score : %.2f RMSE" % (testScore))