<jupyter_start><jupyter_text>Predicting Microsoft Stock Price with Keras 
> Using a Neural Network architecture (LSTM) to predict Microsoft Stock Price
- toc: true
- badges: true
- comments: true
- categories: [Keras,LSTM,MicroSoft,NeuralNetwork]
- image: images/LSTM.jpg  Importing dependecies<jupyter_code>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<jupyter_output><empty_output><jupyter_text>Importing the Stock Price Dataset<jupyter_code>df = pd.read_csv("MSFT-1Y-Hourly.csv", sep=",")<jupyter_output><empty_output><jupyter_text>Data Exploration<jupyter_code>df.isna().any()
df.set_index("date", drop=True, inplace=True)
df.info()
df
df = df[["close"]]
df.describe()<jupyter_output><empty_output><jupyter_text>Visualizing Microsoft close price<jupyter_code>plt.figure(1, figsize=(16, 8))
plt.plot(df.close)<jupyter_output><empty_output><jupyter_text>Adding some Features<jupyter_code>df["returns"] = df.close.pct_change()
df.head()<jupyter_output><empty_output><jupyter_text>Setting the Log returns as a Feature<jupyter_code>df["log_returns"] = np.log(1 + df["returns"])
df.head()<jupyter_output><empty_output><jupyter_text>Plotting the Log returns<jupyter_code>plt.figure(figsize=(16, 8))
plt.plot(df.log_returns)
df.dropna(inplace=True)
X = df[["close", "log_returns"]].values
X[:10]<jupyter_output><empty_output><jupyter_text>Model Building<jupyter_code>from sklearn.preprocessing import MinMaxScaler<jupyter_output><empty_output><jupyter_text>Scaling the Features<jupyter_code>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]<jupyter_output><empty_output><jupyter_text>Splitting the data into training & test data<jupyter_code>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)<jupyter_output><empty_output><jupyter_text>Labeling:
we want to predict the stock price at a future time. We'll predict the stock price at time t+1 relative to stock price at time t 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<jupyter_code>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)<jupyter_output><empty_output><jupyter_text>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)<jupyter_code>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)<jupyter_output>(1398, 3, 2)
(1398,)
-------
(348, 3, 2)
(348,)<jupyter_text>LSTM Model<jupyter_code>from keras.models import Sequential
from keras.layers import LSTM, Dense
#collapse-output
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()<jupyter_output>Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
lstm (LSTM)                  (None, 4)                 112       
_________________________________________________________________
dense (Dense)                (None, 1)                 5         
=================================================================
Total params: 117
Trainable params: 117
Non-trainable params: 0
_________________________________________________________________<jupyter_text>Model Prediction<jupyter_code>trainPredict = model.predict(Xtrain)
testPredict = model.predict(Xtest)
trainPredict = np.c_[trainPredict, np.zeros(trainPredict.shape)]
testPredict = np.c_[testPredict, np.zeros(testPredict.shape)]
#invert prediction
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
#calculate the root 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))<jupyter_output>Train Score : 156.33 RMSE
Train Score : 195.62 RMSE
{'fraction_non_alphanumeric': 0.14119824974755973, 'fraction_numerical': 0.015987882867721306, 'mean_word_length': 6.0, 'pattern_counts': {'":': 0, '<': 54, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '93701', 'license': 'Apache-2.0', 'n_tokens_mistral': 2121, 'n_tokens_neox': 2030, 'n_words': 473, 'path': '_notebooks/2021-09-30-MSFT_LSTM.ipynb', 'repo_name': 'datasiastic/Projects_Portfolio', 'size': '5942'}