<jupyter_start><jupyter_text>LSTM Recurrent Neural Network for Predicting the price of a Stock<jupyter_code>#1-Import basic libraries 
import pandas as pd
import yfinance as yf
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import warnings
warnings.filterwarnings("ignore")
#2-Download stock data
data=yf.download('AAPL')[['Adj Close']]
data.reset_index(inplace=True)
data.drop('Date', axis=1, inplace=True)
#3-Data pre-processing 

#Split into train and test set
split_percentage=0.97
split_point=round(len(data)*split_percentage)
train_data=data.iloc[:split_point]
test_data=data.iloc[split_point:]

#Scale the data
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(train_data)
scaled_train = scaler.transform(train_data)
scaled_test = scaler.transform(test_data)

#4-Transform the data to use it like a time series, Xs will have a shape of (#Samples, #Lags) and Ys of (#Samples,)
def timeseries_preprocessing(scaled_train, scaled_test, lags):
    X,Y = [],[]
    for t in range(len(scaled_train)-lags-1):
        X.append(scaled_train[t:(t+lags),0])
        Y.append(scaled_train[(t+lags),0])
    
    Z,W = [],[]
    for t in range(len(scaled_test)-lags-1):
        Z.append(scaled_test[t:(t+lags),0])
        W.append(scaled_test[(t+lags),0])
        
    X_train, Y_train, X_test, Y_test=np.array(X), np.array(Y), np.array(Z),np.array(W)
    
    #Reshape Xs as (Sample,Timestep,Features), reshape is necessary for keras to understand
    X_train = X_train.reshape((X_train.shape[0],X_train.shape[1],1))
    X_test = X_test.reshape((X_test.shape[0],X_test.shape[1],1))
    
    return X_train, Y_train, X_test, Y_test

X_train, Y_train, X_test, Y_test=timeseries_preprocessing(scaled_train, scaled_test, 10)
#5-Create the model
from tensorflow.keras.models import Sequential 
from tensorflow.keras.layers import Dense, LSTM

model = Sequential()
model.add(LSTM(256,input_shape=(X_train.shape[1],1)))
model.add(Dense(1))
model.compile(optimizer='adam',loss='mse')

#6-Fit model with a validation set to check for overfitting
history = model.fit(x=X_train,y=Y_train,epochs=300,validation_data=(X_test,Y_test),shuffle=False)
#7-Evaluate the model
Y_predicted=scaler.inverse_transform(model.predict(X_test))
Y_true=scaler.inverse_transform(Y_test.reshape(Y_test.shape[0],1))

fig,axes=plt.subplots(1,2,figsize=(20,8))
axes[0].plot(pd.DataFrame(model.history.history)['loss'], label='Loss')
axes[0].plot(pd.DataFrame(model.history.history)['val_loss'], label='Validation Loss')
axes[0].legend(loc=0)
axes[0].set_title('Model fitting performance')

axes[1].plot(Y_true, label='True Y')
axes[1].plot(Y_predicted, label='Predicted Y')
axes[1].legend(loc=0)
axes[1].set_title('Prediction adjustment')

from sklearn import metrics
print('Model accuracy (%)')
Y_p=scaler.inverse_transform(model.predict(X_train))
Y_t=scaler.inverse_transform(Y_train.reshape(Y_train.shape[0],1))
print((1-(metrics.mean_absolute_error(Y_t, Y_p)/Y_t.mean()))*100)
print('')
print('Prediction performance')
print('MAE in %', (metrics.mean_absolute_error(Y_true, Y_predicted)/Y_true.mean())*100)
print('MSE', metrics.mean_squared_error(Y_true, Y_predicted))
print('RMSE',np.sqrt(metrics.mean_squared_error(Y_true, Y_predicted)))
print('R2', metrics.r2_score(Y_true, Y_predicted))
#Precise accuracy 
lista=[]
for t in range(1,Y_predicted.shape[0]):
    if Y_predicted[t]>Y_predicted[t-1] and Y_true[t]>Y_true[t-1]:
        lista.append(1)
    
    if Y_predicted[t]<Y_predicted[t-1] and Y_true[t]<Y_true[t-1]:
        lista.append(1)
    
    else:
        lista.append(0)
print('Precise Accuracy:', sum(lista)/Y_predicted.shape[0])
#Make forecast
def predictions(lags, df, days_ahead):
    batch=scaler.transform(data[-lags:])
    current_batch=np.array(batch[:lags]).reshape(1, batch.shape[0],batch.shape[1])
    
    forecast=[]
    for t in range(0, days_ahead):
        current_pred=model.predict(current_batch)[0]
        forecast.append(list(scaler.inverse_transform(current_pred.reshape(1,1)).reshape(1))[0])
        current_batch=np.append(current_batch[:,1:,:],[[current_pred]],axis=1)
    return forecast
plt.plot(predictions(10, data, 1000))
#Save or load model
from tensorflow.keras.models import load_model
model.save('LSTM_stock_prices')
my_model = load_model('LSTM_stock_prices')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1500114863312658, 'fraction_numerical': 0.020445669653112796, 'mean_word_length': 6.280936454849498, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '606046', 'license': 'Apache-2.0', 'n_tokens_mistral': 1697, 'n_tokens_neox': 1635, 'n_words': 275, 'path': 'Code/LSTM NNs for Stock Price Prediction.ipynb', 'repo_name': 'fedeglan/my-projects', 'size': '4353'}