from __future__ import print_function  # Python 2/3 compatibility
import numpy as np
import pandas as pd

from IPython.display import Image

"""
Explanation: Objective
Build a Sentiment Classifier using Logistic Regression:

Load Data
Vectorize using Scikit-Learn
Build a Logisitc Regression Model
Evaluate the Model
Update our Kaggle Submission
End of explanation
"""


train_df = pd.read_csv("data/train.tsv", sep="\t")

train_df.sample(10)

"""
Explanation: Load Data
End of explanation
"""


from sklearn.model_selection import train_test_split

X_train, X_valid, y_train, y_valid = train_test_split(train_df["review"], train_df["sentiment"], test_size=0.2)

print("Training Data: {}, Validation: {}".format(len(X_train), len(X_valid)))

"""
Explanation: Training process

Split the Overall Training examples into Training and Validation
Build the Models on Training Data
Score on Validation data
Choose the best model and submit to Kaggle

Caution:  If you do this enough times, you will be overfitting to the Validation data.  To avoid that it might be advisable to split into three ways like Train-Validation-Test and generate the final score on Test Data.
End of explanation
"""


from sklearn.feature_extraction.text import CountVectorizer

# The API is very similar to model building process.
# Step 1: Instantiate the Vectorizer or more generally called Transformer

vect = CountVectorizer(max_features=5000, binary=True, stop_words="english")

# Fit your Training Data
vect.fit(X_train)

# Transform your training and validation data
X_train_vect = vect.transform(X_train)
X_valid_vect = vect.transform(X_valid)

X_train.head()

# Creates a Sparse Matrix
X_train_vect

# Understand the Vectorizer
vect

# Does similar things to what we did manually in our bag of words model

# vect.vocabulary_

# Does similar things to what we did manually in our bag of words model
from itertools import islice

list(islice(vect.vocabulary_.items(), 10))

pd.DataFrame(X_train_vect.todense(), columns=vect.vocabulary_.keys()).head()

"""
Explanation: Vectorize Data (a.k.a. covert text to numbers)
Computers don't understand Texts, so we need to convert texts to numbers before we could do any math on it and see if we can build a system to classify a review as Positive or Negative.
Ways to vectorize data:

Bag of Words
TF-IDF
Word Embeddings (Word2Vec) 

Scikit-Learn has nice APIs for preprocessing and feature extraction modules.  In fact, these can be used even if you build your own models or use another libriary for model building process.
End of explanation
"""


from sklearn.linear_model import LogisticRegression

model = LogisticRegression()

model.fit(X_train_vect, y_train)

# Training Accuracy
print("Training Accuracy: {:.3f}".format(model.score(X_train_vect, y_train)))

## Validation Accuracy
print("Validation Accuracy: {:.3f}".format(model.score(X_valid_vect, y_valid)))

"""
Explanation: Model - Logistic Regression
End of explanation
"""


model = LogisticRegression(C=0.1)
model.fit(X_train_vect, y_train)

# Training Accuracy
print("Training Accuracy: {:.3f}".format(model.score(X_train_vect, y_train)))
print("Validation Accuracy: {:.3f}".format(model.score(X_valid_vect, y_valid)))

"""
Explanation: Model Tuning
Model seems to be Overfitting.  Try, Regularization to bring Training Accuracy closer to Validation Accuracy

What options are available in Logisitc Regression
End of explanation
"""


# Read in the Test Dataset
# Note that it's missing the Sentiment Column.  That's what we need to Predict
#
test_df = pd.read_csv("data/test.tsv", sep="\t")
test_df.head()

# Vectorize the Review Text

X_test = test_df.review
X_test_vect = vect.transform(X_test)

y_test_pred = model.predict(X_test_vect)

df = pd.DataFrame({
    "document_id": test_df.document_id,
    "sentiment": y_test_pred
})

df.to_csv("data/logistic_reg_submission1.csv", index=False)

!head data/logistic_reg_submission1.csv

"""
Explanation: Feeling Good? - Let's Update Kaggle Submission
Steps:

Load Test Dataset
Vectorize the Features (Review)
Predict the sentiment
Create the CSV file and update the submission
End of explanation
"""


