# -*- coding: utf-8 -*-
"""SarcasamDetector.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1jYnc6HA2z25x_ISe83hLjwODrjy_oAdV

Created By: YaminiKalyani Gandrothu(100780823) for Machine Learning - Final Project Part 1.

I have taken the Sarcasm Headlines dataset which consists of 26,709 news headlines. Of these headlines, 43.9% are satire, and 56.1% are real. Each record consists of three attributes. The first was a Boolean variable indicating whether the headline is sarcastic or not. The second was the news headline itself. The third was the URL of the article.
"""

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

# Read DataSet from Git Hub
sar_acc = pd.read_json("https://raw.githubusercontent.com/YaminiKalyani/ML/master/Sarcasm_Headlines_Dataset_v2.json", lines=True)
#sar_acc.shape
import re
sar_acc['source'] = sar_acc['article_link'].apply(lambda x: re.findall(r'\w+', x)[2])
sar_acc.head()

# advance ploting
import seaborn as sns
sns.countplot(sar_acc["is_sarcastic"])

# to plot wordcloud
# =================
from wordcloud import WordCloud
from wordcloud import STOPWORDS
def plot_wordcloud(headlines, cmap):
    fig, ax = plt.subplots(figsize=(8, 6))
    wc = WordCloud(max_words = 1000, background_color ='white', stopwords = STOPWORDS, 
                   min_font_size = 10, colormap=cmap)
    wc = wc.generate(headlines)
    plt.axis('off')
    plt.imshow(wc)

# As a basic exploration, following two figures visualize the word clouds through which we can see the types of words that occur frequently in each category.
# word cloud of saracastic headlines
sarcastic = ' '.join(sar_acc[sar_acc['is_sarcastic']==1]['headline'].to_list())
plot_wordcloud(sarcastic, 'Reds')

# word cloud of non-saracastic headlines
non_sarcastic = ' '.join(sar_acc[sar_acc['is_sarcastic']==0]['headline'].to_list())
plot_wordcloud(non_sarcastic, 'Blues')

"""Adding new columns to the data for better visuals and expose the underlying data patterns to machine learning algorithms."""

import string
## Number of words in the text ##
sar_acc["num_words"] = sar_acc["headline"].apply(lambda x: len(str(x).split()))

## Number of unique words in the text ##
sar_acc["num_unique_words"] = sar_acc["headline"].apply(lambda x: len(set(str(x).split())))

## Number of characters in the text ##
sar_acc["num_chars"] = sar_acc["headline"].apply(lambda x: len(str(x)))

## Number of stopwords in the text ##
sar_acc["num_stopwords"] = sar_acc["headline"].apply(lambda x: len([w for w in str(x).lower().split() if w in STOPWORDS]))

## Number of punctuations in the text ##
sar_acc["num_punctuations"] =sar_acc['headline'].apply(lambda x: len([c for c in str(x) if c in string.punctuation]) )

## Number of title case words in the text ##
sar_acc["num_words_upper"] = sar_acc["headline"].apply(lambda x: len([w for w in str(x).split() if w.isupper()]))

## Number of title case words in the text ##
sar_acc["num_words_title"] = sar_acc["headline"].apply(lambda x: len([w for w in str(x).split() if w.istitle()]))

## Average length of the words in the text ##
sar_acc["mean_word_len"] = sar_acc["headline"].apply(lambda x: np.mean([len(w) for w in str(x).split()]))

"""Plot graph which shows how the words are distributed in Sarcastic and Non  Sarcastic headlines."""

plt.figure(figsize=(15,8))

plt.subplot(1,2,1)
plt.xlim(0, 20)
sns.distplot(sar_acc[sar_acc.is_sarcastic==1]["num_words"], kde=False)
plt.title("Words distribution in Sarcastic headlines")
plt.grid(False)

plt.subplot(1,2,2)
plt.xlim(0, 15)
sns.distplot(sar_acc[sar_acc.is_sarcastic==0]["num_words"], kde=False)
plt.title("Words distribution in Non Sarcastic headlines")

plt.grid(False)
plt.show()

# Create the input(X) and output(Y) vectors and then preprocess the lables.
from sklearn.preprocessing import LabelEncoder
X = sar_acc.headline
Y = sar_acc.is_sarcastic
le = LabelEncoder()
Y = le.fit_transform(Y)
Y = Y.reshape(-1,1)

# Split into Training and Test data
from sklearn.model_selection import train_test_split
X_train,X_test,Y_train,Y_test = train_test_split(X,Y,test_size=0.2)

"""Processing the data for the model

- Tokenize the data and convert the text to sequences.

- Add padding to ensure that all the sequences have the same shape.

- There are many ways of taking the max_len and here an arbitrary length of 150 is chosen
"""

from keras.preprocessing.text import Tokenizer
from keras.preprocessing import sequence
max_words = 1000
max_len = 150
tok = Tokenizer(num_words=max_words)
tok.fit_on_texts(X_train)
sequences = tok.texts_to_sequences(X_train)
sequences_matrix = sequence.pad_sequences(sequences,maxlen=max_len)

test_sequences = tok.texts_to_sequences(X_test)
test_sequences_matrix = sequence.pad_sequences(test_sequences,maxlen=max_len)

"""Model#1 : Linear SVC """

from sklearn.svm import LinearSVC,SVC
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from sklearn.metrics import confusion_matrix, classification_report, roc_curve, auc

model = LinearSVC(loss="hinge",fit_intercept=False, max_iter=1500)
model = model.fit(sequences_matrix, Y_train) 
predictions = model.predict(test_sequences_matrix)

svc_train_acc = accuracy_score(Y_train, model.predict(sequences_matrix))
svc_test_acc = accuracy_score(Y_test, predictions)
svc_f1_score = f1_score(predictions, Y_test)
print("Accuracy score: \n a) Train : {} \n b) Test : {}".format(svc_train_acc, svc_test_acc))
print("Precision score: ", precision_score(Y_test, predictions))
print("Recall score: ", recall_score(Y_test, predictions))
print("F1 score : ", svc_f1_score)

confusion_matrix(Y_test, predictions)

"""Model#2: Random Forest Classifier"""

from sklearn.ensemble import RandomForestClassifier

model_rf = RandomForestClassifier(n_estimators = 200)
model_rf = model_rf.fit(sequences_matrix, Y_train) 
predictions = model_rf.predict(test_sequences_matrix)

rf_train_acc = accuracy_score(Y_train, model_rf.predict(sequences_matrix))

rf_test_acc = accuracy_score(Y_test, predictions)
rf_f1_score = f1_score(predictions, Y_test)
print("Accuracy score: \n a) Train : {} \n b) Test : {}".format(rf_train_acc, rf_test_acc))
print("Precision score: ", precision_score(Y_test, predictions))
print("Recall score: ", recall_score(Y_test, predictions))
print("F1 score : ", rf_f1_score)

confusion_matrix(Y_test, predictions)

"""Model#3: Ada Boost Classifier"""

from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import AdaBoostClassifier
tree = DecisionTreeClassifier(random_state = 11, max_features = "auto", class_weight = "balanced",max_depth = None)

model_ada = AdaBoostClassifier(base_estimator=tree)
model_ada = model_ada.fit(sequences_matrix, Y_train)
predictions = model_ada.predict(test_sequences_matrix)

ada_train_acc = accuracy_score(Y_train, model_ada.predict(sequences_matrix))
ada_test_acc = accuracy_score(Y_test, predictions)
ada_f1_score = f1_score(predictions, Y_test)
print("Accuracy score: \n a) Train : {}\n b) Test : {}".format(ada_train_acc, ada_test_acc))
print("Precision score: ", precision_score(Y_test, predictions))
print("Recall score: ", recall_score(Y_test, predictions))
print("F1 score : ",  ada_f1_score)

confusion_matrix(Y_test, predictions)

"""Model#4: Recurrent Neural Networks"""

# Defining the RNN structure for the model
from keras.layers import LSTM, Activation, Dense, Dropout, Input, Embedding
from keras.optimizers import RMSprop
from keras.models import Model
def RNN():
    inputs = Input(name='inputs',shape=[max_len])
    layer = Embedding(max_words,50,input_length=max_len)(inputs)
    layer = LSTM(64)(layer)
    layer = Dense(256,name='FC1')(layer)
    layer = Activation('relu')(layer)
    layer = Dropout(0.2)(layer)
    layer = Dense(1,name='out_layer')(layer)
    layer = Activation('sigmoid')(layer)
    model = Model(inputs=inputs,outputs=layer)
    return model

model = RNN()
model.summary()
model.compile(loss='binary_crossentropy',optimizer=RMSprop(),metrics=['accuracy'])
from keras.callbacks import EarlyStopping
better_history=model.fit(sequences_matrix,Y_train,batch_size=100,epochs=3,
          validation_split=0.1,callbacks=[EarlyStopping(monitor='val_loss',min_delta=0.0001)])

#plot RNN model
import tensorflow as tf
from tensorflow import keras
keras.utils.plot_model(model, to_file="RNN.png", show_shapes=True, rankdir="LR")

#history
import matplotlib.pyplot as plt
pd.DataFrame(better_history.history).plot(figsize=(8, 5))
plt.grid(True)
plt.gca().set_ylim(0, 5)
plt.show()

# to plot model accuracy and loss on change of Epochs

def plot_history(history):
    
    plt.figure(figsize=(18, 6))

    plt.subplot(1, 2, 1)
    plt.plot(history.history['accuracy'], label='Training Accuracy', c='dodgerblue', lw='2')
    plt.plot(history.history['val_accuracy'], label='Test Accuracy', c='orange', lw='2')
    plt.title('Accuracy', loc='left', fontsize=16)
    plt.xlabel("Epochs")
    plt.ylabel('Accuracy')
    plt.legend()
    plt.subplot(1, 2, 2)
    plt.plot(history.history['loss'], label='Training Loss', c='dodgerblue', lw='2')
    plt.plot(history.history['val_loss'], label='Test Loss', c='orange', lw='2')
    plt.title('Loss', loc='left', fontsize=16)
    plt.xlabel("Epochs")
    plt.ylabel('Loss')
    plt.legend()

    plt.show()

plot_history(better_history)

# Calculating accuracy on train and test data
accr = model.evaluate(test_sequences_matrix,Y_test)
print('Test set\n  Loss: {:0.3f}\n  Accuracy: {:0.3f}'.format(accr[0],accr[1]))
rnn_test_acc = accr[1]
rnn_train_acc = accuracy_score(Y_train, model.predict(sequences_matrix).round())
# predict values
pred = model.predict(test_sequences_matrix)

rnn_f1_score = f1_score(pred.round(), Y_test)
print("Accuracy score: \n a) Train : {}\n b) Test : {}".format(rnn_train_acc, rnn_test_acc))
print("Precision score: ", precision_score(Y_test, pred.round()))
print("Recall score: ", recall_score(Y_test, pred.round()))
print("F1 score : ", rnn_f1_score)

# to plot confusion matrix for RNN model

def plot_cm(pred):
    
    pred = pred.ravel()
    pred = np.round(pred)
    
    fig, ax = plt.subplots(1, 1, figsize=(5, 5))

    cm = confusion_matrix(Y_test, pred)
    sns.heatmap(cm, annot=True, cbar=False, fmt='1d', cmap='Blues', ax=ax)

    ax.set_xlabel('Predicted')
    ax.set_ylabel('Actual')
    ax.set_yticklabels(['Non-Sarcastic', 'Sarcastic', ])
    ax.set_xticklabels(['Non-Sarcastic', 'Sarcastic'])

    plt.show()

# Confusion Matrix for RNN model
plot_cm(pred)

"""Finally showing the models performance in a table. 
RNN model performance is eally great when compared with other model results.
"""

models = [('Linear SVC', svc_train_acc, svc_test_acc, svc_f1_score),
          ('Random Forest', rf_train_acc, rf_test_acc, rf_f1_score),
          ('Ada boost', ada_train_acc, ada_test_acc, ada_f1_score),
          ('RNN', rnn_train_acc, rnn_test_acc, rnn_f1_score)
         ]
         
predict = pd.DataFrame(data = models, columns=['Model', 'Train accuracy', 'Test accuracy', 'F1 score'])
predict
c111879bd0793ac8c3ccc257888b6b078c02c123
<mask token>


def plot_wordcloud(headlines, cmap):
    fig, ax = plt.subplots(figsize=(8, 6))
    wc = WordCloud(max_words=1000, background_color='white', stopwords=
        STOPWORDS, min_font_size=10, colormap=cmap)
    wc = wc.generate(headlines)
    plt.axis('off')
    plt.imshow(wc)


<mask token>


def RNN():
    inputs = Input(name='inputs', shape=[max_len])
    layer = Embedding(max_words, 50, input_length=max_len)(inputs)
    layer = LSTM(64)(layer)
    layer = Dense(256, name='FC1')(layer)
    layer = Activation('relu')(layer)
    layer = Dropout(0.2)(layer)
    layer = Dense(1, name='out_layer')(layer)
    layer = Activation('sigmoid')(layer)
    model = Model(inputs=inputs, outputs=layer)
    return model


<mask token>


def plot_history(history):
    plt.figure(figsize=(18, 6))
    plt.subplot(1, 2, 1)
    plt.plot(history.history['accuracy'], label='Training Accuracy', c=
        'dodgerblue', lw='2')
    plt.plot(history.history['val_accuracy'], label='Test Accuracy', c=
        'orange', lw='2')
    plt.title('Accuracy', loc='left', fontsize=16)
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.legend()
    plt.subplot(1, 2, 2)
    plt.plot(history.history['loss'], label='Training Loss', c='dodgerblue',
        lw='2')
    plt.plot(history.history['val_loss'], label='Test Loss', c='orange', lw='2'
        )
    plt.title('Loss', loc='left', fontsize=16)
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.legend()
    plt.show()


<mask token>


def plot_cm(pred):
    pred = pred.ravel()
    pred = np.round(pred)
    fig, ax = plt.subplots(1, 1, figsize=(5, 5))
    cm = confusion_matrix(Y_test, pred)
    sns.heatmap(cm, annot=True, cbar=False, fmt='1d', cmap='Blues', ax=ax)
    ax.set_xlabel('Predicted')
    ax.set_ylabel('Actual')
    ax.set_yticklabels(['Non-Sarcastic', 'Sarcastic'])
    ax.set_xticklabels(['Non-Sarcastic', 'Sarcastic'])
    plt.show()


<mask token>

<mask token>
sar_acc.head()
<mask token>
sns.countplot(sar_acc['is_sarcastic'])
<mask token>


def plot_wordcloud(headlines, cmap):
    fig, ax = plt.subplots(figsize=(8, 6))
    wc = WordCloud(max_words=1000, background_color='white', stopwords=
        STOPWORDS, min_font_size=10, colormap=cmap)
    wc = wc.generate(headlines)
    plt.axis('off')
    plt.imshow(wc)


<mask token>
plot_wordcloud(sarcastic, 'Reds')
<mask token>
plot_wordcloud(non_sarcastic, 'Blues')
<mask token>
plt.figure(figsize=(15, 8))
plt.subplot(1, 2, 1)
plt.xlim(0, 20)
sns.distplot(sar_acc[sar_acc.is_sarcastic == 1]['num_words'], kde=False)
plt.title('Words distribution in Sarcastic headlines')
plt.grid(False)
plt.subplot(1, 2, 2)
plt.xlim(0, 15)
sns.distplot(sar_acc[sar_acc.is_sarcastic == 0]['num_words'], kde=False)
plt.title('Words distribution in Non Sarcastic headlines')
plt.grid(False)
plt.show()
<mask token>
tok.fit_on_texts(X_train)
<mask token>
print("""Accuracy score: 
 a) Train : {} 
 b) Test : {}""".format(
    svc_train_acc, svc_test_acc))
print('Precision score: ', precision_score(Y_test, predictions))
print('Recall score: ', recall_score(Y_test, predictions))
print('F1 score : ', svc_f1_score)
confusion_matrix(Y_test, predictions)
<mask token>
print("""Accuracy score: 
 a) Train : {} 
 b) Test : {}""".format(
    rf_train_acc, rf_test_acc))
print('Precision score: ', precision_score(Y_test, predictions))
print('Recall score: ', recall_score(Y_test, predictions))
print('F1 score : ', rf_f1_score)
confusion_matrix(Y_test, predictions)
<mask token>
print("""Accuracy score: 
 a) Train : {}
 b) Test : {}""".format(
    ada_train_acc, ada_test_acc))
print('Precision score: ', precision_score(Y_test, predictions))
print('Recall score: ', recall_score(Y_test, predictions))
print('F1 score : ', ada_f1_score)
confusion_matrix(Y_test, predictions)
<mask token>


def RNN():
    inputs = Input(name='inputs', shape=[max_len])
    layer = Embedding(max_words, 50, input_length=max_len)(inputs)
    layer = LSTM(64)(layer)
    layer = Dense(256, name='FC1')(layer)
    layer = Activation('relu')(layer)
    layer = Dropout(0.2)(layer)
    layer = Dense(1, name='out_layer')(layer)
    layer = Activation('sigmoid')(layer)
    model = Model(inputs=inputs, outputs=layer)
    return model


<mask token>
model.summary()
model.compile(loss='binary_crossentropy', optimizer=RMSprop(), metrics=[
    'accuracy'])
<mask token>
keras.utils.plot_model(model, to_file='RNN.png', show_shapes=True, rankdir='LR'
    )
<mask token>
pd.DataFrame(better_history.history).plot(figsize=(8, 5))
plt.grid(True)
plt.gca().set_ylim(0, 5)
plt.show()


def plot_history(history):
    plt.figure(figsize=(18, 6))
    plt.subplot(1, 2, 1)
    plt.plot(history.history['accuracy'], label='Training Accuracy', c=
        'dodgerblue', lw='2')
    plt.plot(history.history['val_accuracy'], label='Test Accuracy', c=
        'orange', lw='2')
    plt.title('Accuracy', loc='left', fontsize=16)
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.legend()
    plt.subplot(1, 2, 2)
    plt.plot(history.history['loss'], label='Training Loss', c='dodgerblue',
        lw='2')
    plt.plot(history.history['val_loss'], label='Test Loss', c='orange', lw='2'
        )
    plt.title('Loss', loc='left', fontsize=16)
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.legend()
    plt.show()


plot_history(better_history)
<mask token>
print("""Test set
  Loss: {:0.3f}
  Accuracy: {:0.3f}""".format(accr[0],
    accr[1]))
<mask token>
print("""Accuracy score: 
 a) Train : {}
 b) Test : {}""".format(
    rnn_train_acc, rnn_test_acc))
print('Precision score: ', precision_score(Y_test, pred.round()))
print('Recall score: ', recall_score(Y_test, pred.round()))
print('F1 score : ', rnn_f1_score)


def plot_cm(pred):
    pred = pred.ravel()
    pred = np.round(pred)
    fig, ax = plt.subplots(1, 1, figsize=(5, 5))
    cm = confusion_matrix(Y_test, pred)
    sns.heatmap(cm, annot=True, cbar=False, fmt='1d', cmap='Blues', ax=ax)
    ax.set_xlabel('Predicted')
    ax.set_ylabel('Actual')
    ax.set_yticklabels(['Non-Sarcastic', 'Sarcastic'])
    ax.set_xticklabels(['Non-Sarcastic', 'Sarcastic'])
    plt.show()


plot_cm(pred)
<mask token>
predict

<mask token>
sar_acc = pd.read_json(
    'https://raw.githubusercontent.com/YaminiKalyani/ML/master/Sarcasm_Headlines_Dataset_v2.json'
    , lines=True)
<mask token>
sar_acc['source'] = sar_acc['article_link'].apply(lambda x: re.findall(
    '\\w+', x)[2])
sar_acc.head()
<mask token>
sns.countplot(sar_acc['is_sarcastic'])
<mask token>


def plot_wordcloud(headlines, cmap):
    fig, ax = plt.subplots(figsize=(8, 6))
    wc = WordCloud(max_words=1000, background_color='white', stopwords=
        STOPWORDS, min_font_size=10, colormap=cmap)
    wc = wc.generate(headlines)
    plt.axis('off')
    plt.imshow(wc)


sarcastic = ' '.join(sar_acc[sar_acc['is_sarcastic'] == 1]['headline'].
    to_list())
plot_wordcloud(sarcastic, 'Reds')
non_sarcastic = ' '.join(sar_acc[sar_acc['is_sarcastic'] == 0]['headline'].
    to_list())
plot_wordcloud(non_sarcastic, 'Blues')
<mask token>
sar_acc['num_words'] = sar_acc['headline'].apply(lambda x: len(str(x).split()))
sar_acc['num_unique_words'] = sar_acc['headline'].apply(lambda x: len(set(
    str(x).split())))
sar_acc['num_chars'] = sar_acc['headline'].apply(lambda x: len(str(x)))
sar_acc['num_stopwords'] = sar_acc['headline'].apply(lambda x: len([w for w in
    str(x).lower().split() if w in STOPWORDS]))
sar_acc['num_punctuations'] = sar_acc['headline'].apply(lambda x: len([c for
    c in str(x) if c in string.punctuation]))
sar_acc['num_words_upper'] = sar_acc['headline'].apply(lambda x: len([w for
    w in str(x).split() if w.isupper()]))
sar_acc['num_words_title'] = sar_acc['headline'].apply(lambda x: len([w for
    w in str(x).split() if w.istitle()]))
sar_acc['mean_word_len'] = sar_acc['headline'].apply(lambda x: np.mean([len
    (w) for w in str(x).split()]))
<mask token>
plt.figure(figsize=(15, 8))
plt.subplot(1, 2, 1)
plt.xlim(0, 20)
sns.distplot(sar_acc[sar_acc.is_sarcastic == 1]['num_words'], kde=False)
plt.title('Words distribution in Sarcastic headlines')
plt.grid(False)
plt.subplot(1, 2, 2)
plt.xlim(0, 15)
sns.distplot(sar_acc[sar_acc.is_sarcastic == 0]['num_words'], kde=False)
plt.title('Words distribution in Non Sarcastic headlines')
plt.grid(False)
plt.show()
<mask token>
X = sar_acc.headline
Y = sar_acc.is_sarcastic
le = LabelEncoder()
Y = le.fit_transform(Y)
Y = Y.reshape(-1, 1)
<mask token>
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2)
<mask token>
max_words = 1000
max_len = 150
tok = Tokenizer(num_words=max_words)
tok.fit_on_texts(X_train)
sequences = tok.texts_to_sequences(X_train)
sequences_matrix = sequence.pad_sequences(sequences, maxlen=max_len)
test_sequences = tok.texts_to_sequences(X_test)
test_sequences_matrix = sequence.pad_sequences(test_sequences, maxlen=max_len)
<mask token>
model = LinearSVC(loss='hinge', fit_intercept=False, max_iter=1500)
model = model.fit(sequences_matrix, Y_train)
predictions = model.predict(test_sequences_matrix)
svc_train_acc = accuracy_score(Y_train, model.predict(sequences_matrix))
svc_test_acc = accuracy_score(Y_test, predictions)
svc_f1_score = f1_score(predictions, Y_test)
print("""Accuracy score: 
 a) Train : {} 
 b) Test : {}""".format(
    svc_train_acc, svc_test_acc))
print('Precision score: ', precision_score(Y_test, predictions))
print('Recall score: ', recall_score(Y_test, predictions))
print('F1 score : ', svc_f1_score)
confusion_matrix(Y_test, predictions)
<mask token>
model_rf = RandomForestClassifier(n_estimators=200)
model_rf = model_rf.fit(sequences_matrix, Y_train)
predictions = model_rf.predict(test_sequences_matrix)
rf_train_acc = accuracy_score(Y_train, model_rf.predict(sequences_matrix))
rf_test_acc = accuracy_score(Y_test, predictions)
rf_f1_score = f1_score(predictions, Y_test)
print("""Accuracy score: 
 a) Train : {} 
 b) Test : {}""".format(
    rf_train_acc, rf_test_acc))
print('Precision score: ', precision_score(Y_test, predictions))
print('Recall score: ', recall_score(Y_test, predictions))
print('F1 score : ', rf_f1_score)
confusion_matrix(Y_test, predictions)
<mask token>
tree = DecisionTreeClassifier(random_state=11, max_features='auto',
    class_weight='balanced', max_depth=None)
model_ada = AdaBoostClassifier(base_estimator=tree)
model_ada = model_ada.fit(sequences_matrix, Y_train)
predictions = model_ada.predict(test_sequences_matrix)
ada_train_acc = accuracy_score(Y_train, model_ada.predict(sequences_matrix))
ada_test_acc = accuracy_score(Y_test, predictions)
ada_f1_score = f1_score(predictions, Y_test)
print("""Accuracy score: 
 a) Train : {}
 b) Test : {}""".format(
    ada_train_acc, ada_test_acc))
print('Precision score: ', precision_score(Y_test, predictions))
print('Recall score: ', recall_score(Y_test, predictions))
print('F1 score : ', ada_f1_score)
confusion_matrix(Y_test, predictions)
<mask token>


def RNN():
    inputs = Input(name='inputs', shape=[max_len])
    layer = Embedding(max_words, 50, input_length=max_len)(inputs)
    layer = LSTM(64)(layer)
    layer = Dense(256, name='FC1')(layer)
    layer = Activation('relu')(layer)
    layer = Dropout(0.2)(layer)
    layer = Dense(1, name='out_layer')(layer)
    layer = Activation('sigmoid')(layer)
    model = Model(inputs=inputs, outputs=layer)
    return model


model = RNN()
model.summary()
model.compile(loss='binary_crossentropy', optimizer=RMSprop(), metrics=[
    'accuracy'])
<mask token>
better_history = model.fit(sequences_matrix, Y_train, batch_size=100,
    epochs=3, validation_split=0.1, callbacks=[EarlyStopping(monitor=
    'val_loss', min_delta=0.0001)])
<mask token>
keras.utils.plot_model(model, to_file='RNN.png', show_shapes=True, rankdir='LR'
    )
<mask token>
pd.DataFrame(better_history.history).plot(figsize=(8, 5))
plt.grid(True)
plt.gca().set_ylim(0, 5)
plt.show()


def plot_history(history):
    plt.figure(figsize=(18, 6))
    plt.subplot(1, 2, 1)
    plt.plot(history.history['accuracy'], label='Training Accuracy', c=
        'dodgerblue', lw='2')
    plt.plot(history.history['val_accuracy'], label='Test Accuracy', c=
        'orange', lw='2')
    plt.title('Accuracy', loc='left', fontsize=16)
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.legend()
    plt.subplot(1, 2, 2)
    plt.plot(history.history['loss'], label='Training Loss', c='dodgerblue',
        lw='2')
    plt.plot(history.history['val_loss'], label='Test Loss', c='orange', lw='2'
        )
    plt.title('Loss', loc='left', fontsize=16)
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.legend()
    plt.show()


plot_history(better_history)
accr = model.evaluate(test_sequences_matrix, Y_test)
print("""Test set
  Loss: {:0.3f}
  Accuracy: {:0.3f}""".format(accr[0],
    accr[1]))
rnn_test_acc = accr[1]
rnn_train_acc = accuracy_score(Y_train, model.predict(sequences_matrix).round()
    )
pred = model.predict(test_sequences_matrix)
rnn_f1_score = f1_score(pred.round(), Y_test)
print("""Accuracy score: 
 a) Train : {}
 b) Test : {}""".format(
    rnn_train_acc, rnn_test_acc))
print('Precision score: ', precision_score(Y_test, pred.round()))
print('Recall score: ', recall_score(Y_test, pred.round()))
print('F1 score : ', rnn_f1_score)


def plot_cm(pred):
    pred = pred.ravel()
    pred = np.round(pred)
    fig, ax = plt.subplots(1, 1, figsize=(5, 5))
    cm = confusion_matrix(Y_test, pred)
    sns.heatmap(cm, annot=True, cbar=False, fmt='1d', cmap='Blues', ax=ax)
    ax.set_xlabel('Predicted')
    ax.set_ylabel('Actual')
    ax.set_yticklabels(['Non-Sarcastic', 'Sarcastic'])
    ax.set_xticklabels(['Non-Sarcastic', 'Sarcastic'])
    plt.show()


plot_cm(pred)
<mask token>
models = [('Linear SVC', svc_train_acc, svc_test_acc, svc_f1_score), (
    'Random Forest', rf_train_acc, rf_test_acc, rf_f1_score), ('Ada boost',
    ada_train_acc, ada_test_acc, ada_f1_score), ('RNN', rnn_train_acc,
    rnn_test_acc, rnn_f1_score)]
predict = pd.DataFrame(data=models, columns=['Model', 'Train accuracy',
    'Test accuracy', 'F1 score'])
predict

<mask token>
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
sar_acc = pd.read_json(
    'https://raw.githubusercontent.com/YaminiKalyani/ML/master/Sarcasm_Headlines_Dataset_v2.json'
    , lines=True)
import re
sar_acc['source'] = sar_acc['article_link'].apply(lambda x: re.findall(
    '\\w+', x)[2])
sar_acc.head()
import seaborn as sns
sns.countplot(sar_acc['is_sarcastic'])
from wordcloud import WordCloud
from wordcloud import STOPWORDS


def plot_wordcloud(headlines, cmap):
    fig, ax = plt.subplots(figsize=(8, 6))
    wc = WordCloud(max_words=1000, background_color='white', stopwords=
        STOPWORDS, min_font_size=10, colormap=cmap)
    wc = wc.generate(headlines)
    plt.axis('off')
    plt.imshow(wc)


sarcastic = ' '.join(sar_acc[sar_acc['is_sarcastic'] == 1]['headline'].
    to_list())
plot_wordcloud(sarcastic, 'Reds')
non_sarcastic = ' '.join(sar_acc[sar_acc['is_sarcastic'] == 0]['headline'].
    to_list())
plot_wordcloud(non_sarcastic, 'Blues')
<mask token>
import string
sar_acc['num_words'] = sar_acc['headline'].apply(lambda x: len(str(x).split()))
sar_acc['num_unique_words'] = sar_acc['headline'].apply(lambda x: len(set(
    str(x).split())))
sar_acc['num_chars'] = sar_acc['headline'].apply(lambda x: len(str(x)))
sar_acc['num_stopwords'] = sar_acc['headline'].apply(lambda x: len([w for w in
    str(x).lower().split() if w in STOPWORDS]))
sar_acc['num_punctuations'] = sar_acc['headline'].apply(lambda x: len([c for
    c in str(x) if c in string.punctuation]))
sar_acc['num_words_upper'] = sar_acc['headline'].apply(lambda x: len([w for
    w in str(x).split() if w.isupper()]))
sar_acc['num_words_title'] = sar_acc['headline'].apply(lambda x: len([w for
    w in str(x).split() if w.istitle()]))
sar_acc['mean_word_len'] = sar_acc['headline'].apply(lambda x: np.mean([len
    (w) for w in str(x).split()]))
<mask token>
plt.figure(figsize=(15, 8))
plt.subplot(1, 2, 1)
plt.xlim(0, 20)
sns.distplot(sar_acc[sar_acc.is_sarcastic == 1]['num_words'], kde=False)
plt.title('Words distribution in Sarcastic headlines')
plt.grid(False)
plt.subplot(1, 2, 2)
plt.xlim(0, 15)
sns.distplot(sar_acc[sar_acc.is_sarcastic == 0]['num_words'], kde=False)
plt.title('Words distribution in Non Sarcastic headlines')
plt.grid(False)
plt.show()
from sklearn.preprocessing import LabelEncoder
X = sar_acc.headline
Y = sar_acc.is_sarcastic
le = LabelEncoder()
Y = le.fit_transform(Y)
Y = Y.reshape(-1, 1)
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2)
<mask token>
from keras.preprocessing.text import Tokenizer
from keras.preprocessing import sequence
max_words = 1000
max_len = 150
tok = Tokenizer(num_words=max_words)
tok.fit_on_texts(X_train)
sequences = tok.texts_to_sequences(X_train)
sequences_matrix = sequence.pad_sequences(sequences, maxlen=max_len)
test_sequences = tok.texts_to_sequences(X_test)
test_sequences_matrix = sequence.pad_sequences(test_sequences, maxlen=max_len)
<mask token>
from sklearn.svm import LinearSVC, SVC
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from sklearn.metrics import confusion_matrix, classification_report, roc_curve, auc
model = LinearSVC(loss='hinge', fit_intercept=False, max_iter=1500)
model = model.fit(sequences_matrix, Y_train)
predictions = model.predict(test_sequences_matrix)
svc_train_acc = accuracy_score(Y_train, model.predict(sequences_matrix))
svc_test_acc = accuracy_score(Y_test, predictions)
svc_f1_score = f1_score(predictions, Y_test)
print("""Accuracy score: 
 a) Train : {} 
 b) Test : {}""".format(
    svc_train_acc, svc_test_acc))
print('Precision score: ', precision_score(Y_test, predictions))
print('Recall score: ', recall_score(Y_test, predictions))
print('F1 score : ', svc_f1_score)
confusion_matrix(Y_test, predictions)
<mask token>
from sklearn.ensemble import RandomForestClassifier
model_rf = RandomForestClassifier(n_estimators=200)
model_rf = model_rf.fit(sequences_matrix, Y_train)
predictions = model_rf.predict(test_sequences_matrix)
rf_train_acc = accuracy_score(Y_train, model_rf.predict(sequences_matrix))
rf_test_acc = accuracy_score(Y_test, predictions)
rf_f1_score = f1_score(predictions, Y_test)
print("""Accuracy score: 
 a) Train : {} 
 b) Test : {}""".format(
    rf_train_acc, rf_test_acc))
print('Precision score: ', precision_score(Y_test, predictions))
print('Recall score: ', recall_score(Y_test, predictions))
print('F1 score : ', rf_f1_score)
confusion_matrix(Y_test, predictions)
<mask token>
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import AdaBoostClassifier
tree = DecisionTreeClassifier(random_state=11, max_features='auto',
    class_weight='balanced', max_depth=None)
model_ada = AdaBoostClassifier(base_estimator=tree)
model_ada = model_ada.fit(sequences_matrix, Y_train)
predictions = model_ada.predict(test_sequences_matrix)
ada_train_acc = accuracy_score(Y_train, model_ada.predict(sequences_matrix))
ada_test_acc = accuracy_score(Y_test, predictions)
ada_f1_score = f1_score(predictions, Y_test)
print("""Accuracy score: 
 a) Train : {}
 b) Test : {}""".format(
    ada_train_acc, ada_test_acc))
print('Precision score: ', precision_score(Y_test, predictions))
print('Recall score: ', recall_score(Y_test, predictions))
print('F1 score : ', ada_f1_score)
confusion_matrix(Y_test, predictions)
<mask token>
from keras.layers import LSTM, Activation, Dense, Dropout, Input, Embedding
from keras.optimizers import RMSprop
from keras.models import Model


def RNN():
    inputs = Input(name='inputs', shape=[max_len])
    layer = Embedding(max_words, 50, input_length=max_len)(inputs)
    layer = LSTM(64)(layer)
    layer = Dense(256, name='FC1')(layer)
    layer = Activation('relu')(layer)
    layer = Dropout(0.2)(layer)
    layer = Dense(1, name='out_layer')(layer)
    layer = Activation('sigmoid')(layer)
    model = Model(inputs=inputs, outputs=layer)
    return model


model = RNN()
model.summary()
model.compile(loss='binary_crossentropy', optimizer=RMSprop(), metrics=[
    'accuracy'])
from keras.callbacks import EarlyStopping
better_history = model.fit(sequences_matrix, Y_train, batch_size=100,
    epochs=3, validation_split=0.1, callbacks=[EarlyStopping(monitor=
    'val_loss', min_delta=0.0001)])
import tensorflow as tf
from tensorflow import keras
keras.utils.plot_model(model, to_file='RNN.png', show_shapes=True, rankdir='LR'
    )
import matplotlib.pyplot as plt
pd.DataFrame(better_history.history).plot(figsize=(8, 5))
plt.grid(True)
plt.gca().set_ylim(0, 5)
plt.show()


def plot_history(history):
    plt.figure(figsize=(18, 6))
    plt.subplot(1, 2, 1)
    plt.plot(history.history['accuracy'], label='Training Accuracy', c=
        'dodgerblue', lw='2')
    plt.plot(history.history['val_accuracy'], label='Test Accuracy', c=
        'orange', lw='2')
    plt.title('Accuracy', loc='left', fontsize=16)
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.legend()
    plt.subplot(1, 2, 2)
    plt.plot(history.history['loss'], label='Training Loss', c='dodgerblue',
        lw='2')
    plt.plot(history.history['val_loss'], label='Test Loss', c='orange', lw='2'
        )
    plt.title('Loss', loc='left', fontsize=16)
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.legend()
    plt.show()


plot_history(better_history)
accr = model.evaluate(test_sequences_matrix, Y_test)
print("""Test set
  Loss: {:0.3f}
  Accuracy: {:0.3f}""".format(accr[0],
    accr[1]))
rnn_test_acc = accr[1]
rnn_train_acc = accuracy_score(Y_train, model.predict(sequences_matrix).round()
    )
pred = model.predict(test_sequences_matrix)
rnn_f1_score = f1_score(pred.round(), Y_test)
print("""Accuracy score: 
 a) Train : {}
 b) Test : {}""".format(
    rnn_train_acc, rnn_test_acc))
print('Precision score: ', precision_score(Y_test, pred.round()))
print('Recall score: ', recall_score(Y_test, pred.round()))
print('F1 score : ', rnn_f1_score)


def plot_cm(pred):
    pred = pred.ravel()
    pred = np.round(pred)
    fig, ax = plt.subplots(1, 1, figsize=(5, 5))
    cm = confusion_matrix(Y_test, pred)
    sns.heatmap(cm, annot=True, cbar=False, fmt='1d', cmap='Blues', ax=ax)
    ax.set_xlabel('Predicted')
    ax.set_ylabel('Actual')
    ax.set_yticklabels(['Non-Sarcastic', 'Sarcastic'])
    ax.set_xticklabels(['Non-Sarcastic', 'Sarcastic'])
    plt.show()


plot_cm(pred)
<mask token>
models = [('Linear SVC', svc_train_acc, svc_test_acc, svc_f1_score), (
    'Random Forest', rf_train_acc, rf_test_acc, rf_f1_score), ('Ada boost',
    ada_train_acc, ada_test_acc, ada_f1_score), ('RNN', rnn_train_acc,
    rnn_test_acc, rnn_f1_score)]
predict = pd.DataFrame(data=models, columns=['Model', 'Train accuracy',
    'Test accuracy', 'F1 score'])
predict

# -*- coding: utf-8 -*-
"""SarcasamDetector.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1jYnc6HA2z25x_ISe83hLjwODrjy_oAdV

Created By: YaminiKalyani Gandrothu(100780823) for Machine Learning - Final Project Part 1.

I have taken the Sarcasm Headlines dataset which consists of 26,709 news headlines. Of these headlines, 43.9% are satire, and 56.1% are real. Each record consists of three attributes. The first was a Boolean variable indicating whether the headline is sarcastic or not. The second was the news headline itself. The third was the URL of the article.
"""

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

# Read DataSet from Git Hub
sar_acc = pd.read_json("https://raw.githubusercontent.com/YaminiKalyani/ML/master/Sarcasm_Headlines_Dataset_v2.json", lines=True)
#sar_acc.shape
import re
sar_acc['source'] = sar_acc['article_link'].apply(lambda x: re.findall(r'\w+', x)[2])
sar_acc.head()

# advance ploting
import seaborn as sns
sns.countplot(sar_acc["is_sarcastic"])

# to plot wordcloud
# =================
from wordcloud import WordCloud
from wordcloud import STOPWORDS
def plot_wordcloud(headlines, cmap):
    fig, ax = plt.subplots(figsize=(8, 6))
    wc = WordCloud(max_words = 1000, background_color ='white', stopwords = STOPWORDS, 
                   min_font_size = 10, colormap=cmap)
    wc = wc.generate(headlines)
    plt.axis('off')
    plt.imshow(wc)

# As a basic exploration, following two figures visualize the word clouds through which we can see the types of words that occur frequently in each category.
# word cloud of saracastic headlines
sarcastic = ' '.join(sar_acc[sar_acc['is_sarcastic']==1]['headline'].to_list())
plot_wordcloud(sarcastic, 'Reds')

# word cloud of non-saracastic headlines
non_sarcastic = ' '.join(sar_acc[sar_acc['is_sarcastic']==0]['headline'].to_list())
plot_wordcloud(non_sarcastic, 'Blues')

"""Adding new columns to the data for better visuals and expose the underlying data patterns to machine learning algorithms."""

import string
## Number of words in the text ##
sar_acc["num_words"] = sar_acc["headline"].apply(lambda x: len(str(x).split()))

## Number of unique words in the text ##
sar_acc["num_unique_words"] = sar_acc["headline"].apply(lambda x: len(set(str(x).split())))

## Number of characters in the text ##
sar_acc["num_chars"] = sar_acc["headline"].apply(lambda x: len(str(x)))

## Number of stopwords in the text ##
sar_acc["num_stopwords"] = sar_acc["headline"].apply(lambda x: len([w for w in str(x).lower().split() if w in STOPWORDS]))

## Number of punctuations in the text ##
sar_acc["num_punctuations"] =sar_acc['headline'].apply(lambda x: len([c for c in str(x) if c in string.punctuation]) )

## Number of title case words in the text ##
sar_acc["num_words_upper"] = sar_acc["headline"].apply(lambda x: len([w for w in str(x).split() if w.isupper()]))

## Number of title case words in the text ##
sar_acc["num_words_title"] = sar_acc["headline"].apply(lambda x: len([w for w in str(x).split() if w.istitle()]))

## Average length of the words in the text ##
sar_acc["mean_word_len"] = sar_acc["headline"].apply(lambda x: np.mean([len(w) for w in str(x).split()]))

"""Plot graph which shows how the words are distributed in Sarcastic and Non  Sarcastic headlines."""

plt.figure(figsize=(15,8))

plt.subplot(1,2,1)
plt.xlim(0, 20)
sns.distplot(sar_acc[sar_acc.is_sarcastic==1]["num_words"], kde=False)
plt.title("Words distribution in Sarcastic headlines")
plt.grid(False)

plt.subplot(1,2,2)
plt.xlim(0, 15)
sns.distplot(sar_acc[sar_acc.is_sarcastic==0]["num_words"], kde=False)
plt.title("Words distribution in Non Sarcastic headlines")

plt.grid(False)
plt.show()

# Create the input(X) and output(Y) vectors and then preprocess the lables.
from sklearn.preprocessing import LabelEncoder
X = sar_acc.headline
Y = sar_acc.is_sarcastic
le = LabelEncoder()
Y = le.fit_transform(Y)
Y = Y.reshape(-1,1)

# Split into Training and Test data
from sklearn.model_selection import train_test_split
X_train,X_test,Y_train,Y_test = train_test_split(X,Y,test_size=0.2)

"""Processing the data for the model

- Tokenize the data and convert the text to sequences.

- Add padding to ensure that all the sequences have the same shape.

- There are many ways of taking the max_len and here an arbitrary length of 150 is chosen
"""

from keras.preprocessing.text import Tokenizer
from keras.preprocessing import sequence
max_words = 1000
max_len = 150
tok = Tokenizer(num_words=max_words)
tok.fit_on_texts(X_train)
sequences = tok.texts_to_sequences(X_train)
sequences_matrix = sequence.pad_sequences(sequences,maxlen=max_len)

test_sequences = tok.texts_to_sequences(X_test)
test_sequences_matrix = sequence.pad_sequences(test_sequences,maxlen=max_len)

"""Model#1 : Linear SVC """

from sklearn.svm import LinearSVC,SVC
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from sklearn.metrics import confusion_matrix, classification_report, roc_curve, auc

model = LinearSVC(loss="hinge",fit_intercept=False, max_iter=1500)
model = model.fit(sequences_matrix, Y_train) 
predictions = model.predict(test_sequences_matrix)

svc_train_acc = accuracy_score(Y_train, model.predict(sequences_matrix))
svc_test_acc = accuracy_score(Y_test, predictions)
svc_f1_score = f1_score(predictions, Y_test)
print("Accuracy score: \n a) Train : {} \n b) Test : {}".format(svc_train_acc, svc_test_acc))
print("Precision score: ", precision_score(Y_test, predictions))
print("Recall score: ", recall_score(Y_test, predictions))
print("F1 score : ", svc_f1_score)

confusion_matrix(Y_test, predictions)

"""Model#2: Random Forest Classifier"""

from sklearn.ensemble import RandomForestClassifier

model_rf = RandomForestClassifier(n_estimators = 200)
model_rf = model_rf.fit(sequences_matrix, Y_train) 
predictions = model_rf.predict(test_sequences_matrix)

rf_train_acc = accuracy_score(Y_train, model_rf.predict(sequences_matrix))

rf_test_acc = accuracy_score(Y_test, predictions)
rf_f1_score = f1_score(predictions, Y_test)
print("Accuracy score: \n a) Train : {} \n b) Test : {}".format(rf_train_acc, rf_test_acc))
print("Precision score: ", precision_score(Y_test, predictions))
print("Recall score: ", recall_score(Y_test, predictions))
print("F1 score : ", rf_f1_score)

confusion_matrix(Y_test, predictions)

"""Model#3: Ada Boost Classifier"""

from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import AdaBoostClassifier
tree = DecisionTreeClassifier(random_state = 11, max_features = "auto", class_weight = "balanced",max_depth = None)

model_ada = AdaBoostClassifier(base_estimator=tree)
model_ada = model_ada.fit(sequences_matrix, Y_train)
predictions = model_ada.predict(test_sequences_matrix)

ada_train_acc = accuracy_score(Y_train, model_ada.predict(sequences_matrix))
ada_test_acc = accuracy_score(Y_test, predictions)
ada_f1_score = f1_score(predictions, Y_test)
print("Accuracy score: \n a) Train : {}\n b) Test : {}".format(ada_train_acc, ada_test_acc))
print("Precision score: ", precision_score(Y_test, predictions))
print("Recall score: ", recall_score(Y_test, predictions))
print("F1 score : ",  ada_f1_score)

confusion_matrix(Y_test, predictions)

"""Model#4: Recurrent Neural Networks"""

# Defining the RNN structure for the model
from keras.layers import LSTM, Activation, Dense, Dropout, Input, Embedding
from keras.optimizers import RMSprop
from keras.models import Model
def RNN():
    inputs = Input(name='inputs',shape=[max_len])
    layer = Embedding(max_words,50,input_length=max_len)(inputs)
    layer = LSTM(64)(layer)
    layer = Dense(256,name='FC1')(layer)
    layer = Activation('relu')(layer)
    layer = Dropout(0.2)(layer)
    layer = Dense(1,name='out_layer')(layer)
    layer = Activation('sigmoid')(layer)
    model = Model(inputs=inputs,outputs=layer)
    return model

model = RNN()
model.summary()
model.compile(loss='binary_crossentropy',optimizer=RMSprop(),metrics=['accuracy'])
from keras.callbacks import EarlyStopping
better_history=model.fit(sequences_matrix,Y_train,batch_size=100,epochs=3,
          validation_split=0.1,callbacks=[EarlyStopping(monitor='val_loss',min_delta=0.0001)])

#plot RNN model
import tensorflow as tf
from tensorflow import keras
keras.utils.plot_model(model, to_file="RNN.png", show_shapes=True, rankdir="LR")

#history
import matplotlib.pyplot as plt
pd.DataFrame(better_history.history).plot(figsize=(8, 5))
plt.grid(True)
plt.gca().set_ylim(0, 5)
plt.show()

# to plot model accuracy and loss on change of Epochs

def plot_history(history):
    
    plt.figure(figsize=(18, 6))

    plt.subplot(1, 2, 1)
    plt.plot(history.history['accuracy'], label='Training Accuracy', c='dodgerblue', lw='2')
    plt.plot(history.history['val_accuracy'], label='Test Accuracy', c='orange', lw='2')
    plt.title('Accuracy', loc='left', fontsize=16)
    plt.xlabel("Epochs")
    plt.ylabel('Accuracy')
    plt.legend()
    plt.subplot(1, 2, 2)
    plt.plot(history.history['loss'], label='Training Loss', c='dodgerblue', lw='2')
    plt.plot(history.history['val_loss'], label='Test Loss', c='orange', lw='2')
    plt.title('Loss', loc='left', fontsize=16)
    plt.xlabel("Epochs")
    plt.ylabel('Loss')
    plt.legend()

    plt.show()

plot_history(better_history)

# Calculating accuracy on train and test data
accr = model.evaluate(test_sequences_matrix,Y_test)
print('Test set\n  Loss: {:0.3f}\n  Accuracy: {:0.3f}'.format(accr[0],accr[1]))
rnn_test_acc = accr[1]
rnn_train_acc = accuracy_score(Y_train, model.predict(sequences_matrix).round())
# predict values
pred = model.predict(test_sequences_matrix)

rnn_f1_score = f1_score(pred.round(), Y_test)
print("Accuracy score: \n a) Train : {}\n b) Test : {}".format(rnn_train_acc, rnn_test_acc))
print("Precision score: ", precision_score(Y_test, pred.round()))
print("Recall score: ", recall_score(Y_test, pred.round()))
print("F1 score : ", rnn_f1_score)

# to plot confusion matrix for RNN model

def plot_cm(pred):
    
    pred = pred.ravel()
    pred = np.round(pred)
    
    fig, ax = plt.subplots(1, 1, figsize=(5, 5))

    cm = confusion_matrix(Y_test, pred)
    sns.heatmap(cm, annot=True, cbar=False, fmt='1d', cmap='Blues', ax=ax)

    ax.set_xlabel('Predicted')
    ax.set_ylabel('Actual')
    ax.set_yticklabels(['Non-Sarcastic', 'Sarcastic', ])
    ax.set_xticklabels(['Non-Sarcastic', 'Sarcastic'])

    plt.show()

# Confusion Matrix for RNN model
plot_cm(pred)

"""Finally showing the models performance in a table. 
RNN model performance is eally great when compared with other model results.
"""

models = [('Linear SVC', svc_train_acc, svc_test_acc, svc_f1_score),
          ('Random Forest', rf_train_acc, rf_test_acc, rf_f1_score),
          ('Ada boost', ada_train_acc, ada_test_acc, ada_f1_score),
          ('RNN', rnn_train_acc, rnn_test_acc, rnn_f1_score)
         ]
         
predict = pd.DataFrame(data = models, columns=['Model', 'Train accuracy', 'Test accuracy', 'F1 score'])
predict