"""
# Imports
"""
import numpy as np
import pandas as pd
from textblob import TextBlob
from wordcloud import WordCloud
import re
import matplotlib.pyplot as plt
plt.style.use('seaborn')
plt.rcParams['figure.figsize'] = 20, 15
from sklearn.metrics import classification_report,confusion_matrix,accuracy_score
from sklearn.preprocessing import MinMaxScaler, LabelEncoder
from sklearn.ensemble import RandomForestClassifier
from keras.models import Sequential
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.optimizers import Adam
from keras.layers import Dense, Embedding, LSTM, SpatialDropout1D, Dropout
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
from tensorflow.keras.preprocessing.text import one_hot
from sklearn.model_selection import train_test_split
import nltk
from nltk.corpus import stopwords
from nltk.stem.porter import PorterStemmer
"""
# Preprocessing
"""
df = pd.read_csv('../input/twitter-and-reddit-sentimental-analysis-dataset/Reddit_Data.csv')
df.dropna(inplace=True)
df.category.value_counts(normalize=True)
df = df.sample(n=10000).reset_index(drop=True)
df.category.value_counts(normalize=True)
df.columns = ['Comment', 'Category']
df
X, y = df.iloc[:,:-1],df.iloc[:,-1]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print(f'X_train, X_test, y_train, y_test shapes are {X_train.shape, X_test.shape, y_train.shape, y_test.shape}')
allwords = " ".join([com for com in df.Comment])
wc = WordCloud().generate(allwords)
plt.imshow(wc,interpolation='bilinear')
plt.axis('off')
new = df.Comment.apply(lambda x:len(x))
plt.hist(new)
# Vocab size
vocab_size = 5000

def preprocess(messages, sentence_length=60):
    # Stemming
    ps = PorterStemmer()
    corpus = []
    for i in range(len(messages)):
        review = re.sub('^a-zA-Z', ' ', messages[i])
        review = review.lower()
        review = review.split()
        review = [ps.stem(word) for word in review if word not in stopwords.words('english')]
        review = ' '.join(review)
        corpus.append(review) 
    # Oen hot coding
    oh_repr = [one_hot(sent, vocab_size) for sent in corpus]

    padded_seq = pad_sequences(oh_repr, maxlen=sentence_length)
    return padded_seq
padded_seq = preprocess(X_train.Comment.reset_index(drop=True))
padded_seq.shape
"""
# Model
"""
no_of_features = 200
sent_len=60
model = Sequential()
model.add(Embedding(vocab_size, no_of_features, input_length=sent_len))
model.add(LSTM(100, return_sequences=True))
model.add(Dropout(.2))
model.add(LSTM(100))
model.add(Dropout(.2))
model.add(Dense(3,activation='softmax'))
model.compile(optimizer=Adam(.0001), loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.summary()

# Add callbacks
filepath = './Sentiment.h5'
checkpoint = ModelCheckpoint(filepath, save_best_only=True, verbose=1)
earlystop = EarlyStopping(patience=5, verbose=1)
#csvlg = CSVLogger('mylogs.csv', separator=',', append=False)

callback_list = [earlystop, checkpoint]

enc = LabelEncoder()
y = enc.fit_transform(y_train)

X, y = np.array(padded_seq), np.array(y)
history = model.fit(X, y, validation_split=.2, epochs=30, batch_size=32, callbacks=callback_list)
def plot_history(history):
    plt.plot(history['loss'], label='Original loss')
    plt.plot(history['val_loss'], label='Validation loss')
    plt.plot(history['accuracy'], label='Original accuracy')
    plt.plot(history['val_accuracy'], label='Validation accuracy')
    plt.legend()
plot_history(history.history)
model.evaluate(preprocess(X_test.Comment.reset_index(drop=True)), enc.transform(y_test))
"""
# TextBlob
"""
def polarity(text):
    return TextBlob(text).sentiment.polarity
def subjectivity(text):
    return TextBlob(text).sentiment.subjectivity
    

df['polarity'] = df.Comment.apply(polarity)
df['subjectivity'] = df.Comment.apply(subjectivity)
df
X, y = df.iloc[:,-2:],df.iloc[:,-3]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print(f'X_train, X_test, y_train, y_test shapes are {X_train.shape, X_test.shape, y_train.shape, y_test.shape}')
X[:5], y[:5]
classifier = RandomForestClassifier()
classifier.fit(X_train, y_train)

preds = classifier.predict(X_test)
preds
accuracy_score(y_test,preds)