import os

!mkdir -p ~/.kaggle
!mv kaggle.json ~/.kaggle/
!chmod 600 ~/.kaggle/kaggle.json
!pip install -q kaggle
!kaggle datasets download -d fullmetal26/glovetwitter27b100dtxt
!unzip -q glovetwitter27b100dtxt.zip
!wget -q https://raw.githubusercontent.com/haochen23/nlp-rnn-lstm-sentiment/master/training.1600000.processed.noemoticon.csv

import tensorflow.keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import InputLayer, Dense, SimpleRNN, Activation, Dropout, Conv1D
from tensorflow.keras.layers import Embedding, Flatten, LSTM, GRU
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.callbacks import EarlyStopping
import pandas as pd
import numpy as np
import spacy
from sklearn.metrics import classification_report

data = pd.read_csv("training.1600000.processed.noemoticon.csv", header=None, encoding='latin-1')
print("The shape of the original dataset is {}".format(data.shape))
data.head()

data.isnull().any()

!python -m spacy download en_core_web_sm
nlp = spacy.load("en_core_web_sm")

def remove_stopwords(sentence):
    new = []
    sentence = nlp(sentence)
    for tk in sentence:
        if (tk.is_stop == False) & (tk.pos_ != "PUNCT"):
            new.append(tk.string.strip())
    c = " ".join(str(x) for x in new)
    return c

def lemmatize(sentence):
    sentence = nlp(sentence)
    s = ""
    for w in sentence:
        s += " " + w.lemma_
    return nlp(s)

def sent_vectorizer(sent, model):
    sent_vector = np.zeros(200)
    num_w = 0
    for w in sent.split():
        try:
            sent_vector = np.add(sent_vector, model[str(w)])
            num_w += 1
        except:
            pass
    return sent_vector

data_X = data[data.columns[5]].to_numpy()
data_y = data[data.columns[0]]
data_y = pd.get_dummies(data_y).to_numpy()

glove_model = load_glove_model("glove.twitter.27B.200d.txt")
max_vocab = 18000
max_len = 15

tokenizer = Tokenizer(num_words=max_vocab)
tokenizer.fit_on_texts(data_X)
sequences = tokenizer.texts_to_sequences(data_X)
word_index = tokenizer.word_index
print('Found %s unique tokens.' % len(word_index))
data_keras = pad_sequences(sequences, maxlen=max_len, padding="post")

from sklearn.model_selection import train_test_split
train_X, valid_X, train_y, valid_y = train_test_split(data_keras, data_y, test_size=0.3, random_state=42)

nb_words = len(tokenizer.word_index) + 1

embedding_matrix = np.zeros((nb_words, 200))
for word, i in word_index.items():
    embedding_vector = glove_model.get(word)
    if embedding_vector is not None:
        embedding_matrix[i] = embedding_vector
print('Null word embeddings: %d' % np.sum(np.sum(embedding_matrix, axis=1) == 0))

def build_model(nb_words, rnn_model="SimpleRNN", embedding_matrix=None):
    model = Sequential()
    if embedding_matrix is not None:
        model.add(Embedding(nb_words, 200, weights=[embedding_matrix], input_length=max_len, trainable=False))
    else:
        model.add(Embedding(nb_words, 200, input_length=max_len, trainable=False))

    if rnn_model == "SimpleRNN":
        model.add(SimpleRNN(200))
    elif rnn_model == "LSTM":
        model.add(LSTM(200))
    else:
        model.add(GRU(200))
    model.add(Dense(2, activation='softmax'))

    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model

model_rnn = build_model(nb_words, "SimpleRNN", embedding_matrix)
model_rnn.fit(train_X, train_y, epochs=20, batch_size=120, validation_data=(valid_X, valid_y), callbacks=EarlyStopping(monitor='val_accuracy', mode='max', patience=3))
predictions = model_rnn.predict(valid_X)
predictions = predictions.argmax(axis=1)

print(classification_report(valid_y.argmax(axis=1), predictions))

model_lstm = build_model(nb_words, "LSTM", embedding_matrix)
model_lstm.fit(train_X, train_y, epochs=20, batch_size=120, validation_data=(valid_X, valid_y), callbacks=EarlyStopping(monitor='val_accuracy', mode='max', patience=3))
predictions = model_lstm.predict(valid_X)
predictions = predictions.argmax(axis=1)
print(classification_report(valid_y.argmax(axis=1), predictions))

model_gru = build_model(nb_words, "GRU", embedding_matrix)
model_gru.fit(train_X, train_y, epochs=20, batch_size=120, validation_data=(valid_X, valid_y), callbacks=EarlyStopping(monitor='val_accuracy', mode='max', patience=3))
predictions = model_gru.predict(valid_X)
predictions = predictions.argmax(axis=1)
print(classification_report(valid_y.argmax(axis=1), predictions))