<jupyter_start><jupyter_text>The problem I would like to solve using an RNN is predicting the price of a stock(Apple stock for my use but this can be extended to any stock) using the previous days stock prices. From the S&P 500 stock dataset I will be using the Apple stock the data from years 2013-2018. https://www.kaggle.com/camnugent/sandp500 I will use the tensorflow keras library to solve this problem.<jupyter_code>import numpy as np
import pandas as pd
import tensorflow as tf
import keras.layers
from sklearn import metrics
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
from keras.layers import SimpleRNN
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from gensim.models.word2vec import Word2Vec
import gensim.downloader as api
%matplotlib inline
dataset = pd.read_csv('AAPL_data.csv',parse_dates = ['date'])
dataset.head()
plt.rcParams['figure.constrained_layout.use'] = True
fig, (ax1,ax2,ax3,ax4) = plt.subplots(4,1, figsize = (20,6))

ax1.set_xlabel('Year')
ax1.set_ylabel('Close')
ax1.set_title('AAPL Close')
ax1.plot(dataset.date, dataset.close)
ax2.set_xlabel('Year')
ax2.set_ylabel('Open')
ax2.set_title('AAPL Open')
ax2.plot(dataset.date, dataset.open)
ax3.set_xlabel('Year')
ax3.set_ylabel('High')
ax3.set_title('AAPL High')
ax3.plot(dataset.date, dataset.high)
ax4.set_xlabel('Year')
ax4.set_ylabel('Low')
ax4.set_title('AAPL Low')
ax4.plot(dataset.date, dataset.low)
plt.show()
#Split train and test data
close = dataset.close.values.astype('float32')
close = close.reshape(len(close), 1)
train_size = int(len(close) * 0.70)
train_set = close[0:train_size, :]
test_set = close[train_size:, :]


#Need to normalize data
scaler = MinMaxScaler(feature_range=(0,1))
scaled_data = scaler.fit_transform(dataset['close'].values.reshape(-1,1))
prediction_days = 30

x_train = []
y_train = []

for x in range(prediction_days, len(scaled_data)):
    x_train.append(scaled_data[x - prediction_days:x, 0])
    y_train.append(scaled_data[x, 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))
rnn = keras.models.Sequential()
#We use the default activation function of tanh for each layer 
#The first layer of the RNN, takes the shape of an input and a unit of 50
rnn.add((keras.layers.SimpleRNN(units = 50, return_sequences = True, input_shape = (x_train.shape[1], 1))))
# Dropout layer that will get rid of 20% of the network to readjust the weights
rnn.add(keras.layers.Dropout(0.2))

rnn.add(keras.layers.SimpleRNN(units = 50, return_sequences = True))
#Another dropout layer before the last input layer
rnn.add(keras.layers.Dropout(0.2))
#Last input layer, this time it does not return the alst sequence
rnn.add(keras.layers.SimpleRNN(units = 50))
#Finally the output layer
rnn.add(keras.layers.Dense(units = 1))
#Overall the simple RNN has 3 input layers and 2 layers to refresh the network throughout
#Accuracy metric used here is MeanSquaredError because this is a regression problem
rnn.compile(optimizer = 'adam',  loss = 'mean_squared_error', metrics=[tf.keras.metrics.MeanSquaredError()])
model = rnn.fit(x_train, y_train, batch_size = 32, epochs = 100)
test_set = pd.DataFrame(test_set)
total_dataset = pd.concat((dataset['close'], test_set), axis=0)
model_inputs = total_dataset[len(total_dataset) - len(test_set) - 30:].values
model_inputs = model_inputs.reshape(-1,1)
model_inputs = scaler.transform(model_inputs)

x_test = []
for x in range(30, len(model_inputs)):
    x_test.append(model_inputs[x-30:x, 0])
x_test = np.array(x_test)
x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1] ,1))

predicted_prices = rnn.predict(x_test)
predicted_prices = scaler.inverse_transform(predicted_prices)

actual_prices = test_set.values
#Skip 30 steps to avoid funky model error at the start of the array
plt.plot(predicted_prices[30:], color = 'red')
plt.plot(actual_prices[30:])
plt.xlabel('Time')
plt.ylabel('Price')
plt.title('AAPL Stock Close Price v. RNN Prediction')
plt.legend(['Predicted','Actual'])
plt.show()
plt.plot((model.history['loss']))
plt.xlabel('Epochs')
plt.ylabel('Mean Squared Error')
plt.show()
#Now implement the LSTM version

rnn_LSTM = keras.models.Sequential()

#Update the same simple RNN cell structure to LSTM 
rnn_LSTM.add((keras.layers.LSTM(units = 50, return_sequences = True, input_shape = (x_train.shape[1], 1))))
rnn_LSTM.add(keras.layers.Dropout(0.2))
rnn_LSTM.add(keras.layers.LSTM(units = 50, return_sequences = True))
rnn_LSTM.add(keras.layers.Dropout(0.2))
rnn_LSTM.add(keras.layers.SimpleRNN(units = 50))
rnn_LSTM.add(keras.layers.Dense(units = 1))
rnn_LSTM.compile(optimizer = 'adam',  loss = 'mean_squared_error')
model_LSTM = rnn_LSTM.fit(x_train, y_train, batch_size = 32, epochs = 100)
predicted_prices_LSTM = rnn_LSTM.predict(x_test)
predicted_prices_LSTM = scaler.inverse_transform(predicted_prices_LSTM)
actual_prices = test_set.values
plt.plot(predicted_prices_LSTM[30:], color = 'red')
plt.plot(actual_prices[30:])
plt.xlabel('Time')
plt.ylabel('Price')
plt.title('AAPL Stock Close Price v. LSTM Prediction')
plt.legend(['Predicted','Actual'])
plt.show()
plt.plot((model_LSTM.history['loss']))
plt.xlabel('Epochs')
plt.ylabel('Mean Squared Error')
plt.show()<jupyter_output><empty_output><jupyter_text>From the two prediction v. actual graphs we can see that they both did a good job of predicting the stock price over days, with LSTM clearly having the better predictions. To understand the performance better, we can look at the second graphs on each RNN, the mean squared error. Here the clear winner is also the LSTM model, which had a very close score to 0 after about the 20th epoch, while the SimpleRNN had issues halfway through epochs and overall had a higher mean squared error.<jupyter_code>#Part 2
corpus = api.load('text8')  #http://mattmahoney.net/dc/textdata.html (first 100,000 words in wikipedia)
model = Word2Vec(corpus)  

input1 = input()
input2 = input()

print(f'Cosine similarity between {input1} and {input2} is {model.wv.similarity(input1, input2)}')
#implementing jaccard dissimilarity for part 2
def jaccard(str1, str2):
    intersection = len(list(set(str1).intersection(str2)))
    union = (len(str1) + len(str2)) - intersection
    return 1 - (float(intersection) / union)
print(f'Jaccard dissimarity(aka distance) between {input1} and {input2} is: {jaccard(input1, input2)}')<jupyter_output>Jaccard dissimarity(aka distance) between cat and dog is: 1.0
{'fraction_non_alphanumeric': 0.12195863746958638, 'fraction_numerical': 0.023722627737226276, 'mean_word_length': 6.079655543595264, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '67720', 'license': 'MIT', 'n_tokens_mistral': 2452, 'n_tokens_neox': 2307, 'n_words': 615, 'path': 'RNN(HW4)/RNN.ipynb', 'repo_name': 'enisaras/Projects-in-Machine-Learning-and-AI-HWs', 'size': '6576'}