"""
This script is where the preprocessed data is used to train the SVM model to
perform the classification. I am using Stratified K-Fold Cross Validation to 
prevent bias and/or any imbalance that could affect the model's accuracy.

REFERENCE: https://medium.com/@bedigunjit/simple-guide-to-text-classification-nlp-using-svm-and-naive-bayes-with-python-421db3a72d34
"""

import numpy as np
import pandas as pd
from sklearn import model_selection, svm
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import LabelEncoder
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import StratifiedKFold


# Open preproccessed csv
df = pd.read_csv("preprocessed.csv", index_col=0)
print(df.head())

print("SPLITTING TRAIN-TEST")
x = df["Text"]
y = df["PublicationTitle"]

train_x, test_x, train_y, test_y = model_selection.train_test_split(
    df["Text"], df["PublicationTitle"], test_size=0.3)

# Label encode the target variable to transform categorical data of string
# type into numerical values the model can understand

encoder = LabelEncoder()
# train_y = encoder.fit_transform(train_y)
# test_y = encoder.fit_transform(test_y)

# Word vectorization
# turning a collection of text documents into numerical feature vectors
# We are using Term Frequency - Inverse Document
tfidf_vect = TfidfVectorizer(max_features=5000)
tfidf_vect.fit(df["Text"])

# train_x_tfidf = tfidf_vect.transform(train_x)
# test_x_tfidf = tfidf_vect.transform(test_x)

x_tfidf = tfidf_vect.transform(df["Text"])
y = encoder.fit_transform(y)


# print(tfidf_vect.vocabulary_)

# Fit the training dataset to the classifier
print("TRAINING THE MODEL")
SVM = svm.SVC(C=1.0, kernel='linear', degree=3, gamma='auto')

skf = StratifiedKFold(n_splits=10, shuffle=True, random_state=1)
accuracies = []

fold = 1
for train_idx, test_idx in skf.split(x, y):
    print("Working on fold", fold)
    x_train_fold, x_test_fold = x_tfidf[train_idx], x_tfidf[test_idx]
    y_train_fold, y_test_fold = y[train_idx], y[test_idx]

    SVM.fit(x_train_fold, y_train_fold)
    acc = SVM.score(x_test_fold, y_test_fold)
    print("Acc", fold, ":", acc)
    accuracies.append(acc)
    fold += 1


print("ACCURACIES:", accuracies)
print("Max Accuracy:", np.max(accuracies))
print("Min Accuracy:", np.min(accuracies))
print("Mean of Accuracies:", np.mean(accuracies))
print("STD of Accuracies:", np.std(accuracies))

# print("RUNNING TEST PREDICTIONS")
# predictions = SVM.predict(test_x_tfidf)

# # Calculate accuracy score
# accuracy = accuracy_score(test_y, predictions)
# print("Accuracy:", str(accuracy * 100) + "%")

[((686, 730), 'pandas.read_csv', 'pd.read_csv', (['"""preprocessed.csv"""'], {'index_col': '(0)'}), "('preprocessed.csv', index_col=0)\n", (697, 730), True, 'import pandas as pd\n'), ((857, 944), 'sklearn.model_selection.train_test_split', 'model_selection.train_test_split', (["df['Text']", "df['PublicationTitle']"], {'test_size': '(0.3)'}), "(df['Text'], df['PublicationTitle'],\n    test_size=0.3)\n", (889, 944), False, 'from sklearn import model_selection, svm\n'), ((1087, 1101), 'sklearn.preprocessing.LabelEncoder', 'LabelEncoder', ([], {}), '()\n', (1099, 1101), False, 'from sklearn.preprocessing import LabelEncoder\n'), ((1342, 1376), 'sklearn.feature_extraction.text.TfidfVectorizer', 'TfidfVectorizer', ([], {'max_features': '(5000)'}), '(max_features=5000)\n', (1357, 1376), False, 'from sklearn.feature_extraction.text import TfidfVectorizer\n'), ((1686, 1741), 'sklearn.svm.SVC', 'svm.SVC', ([], {'C': '(1.0)', 'kernel': '"""linear"""', 'degree': '(3)', 'gamma': '"""auto"""'}), "(C=1.0, kernel='linear', degree=3, gamma='auto')\n", (1693, 1741), False, 'from sklearn import model_selection, svm\n'), ((1749, 1807), 'sklearn.model_selection.StratifiedKFold', 'StratifiedKFold', ([], {'n_splits': '(10)', 'shuffle': '(True)', 'random_state': '(1)'}), '(n_splits=10, shuffle=True, random_state=1)\n', (1764, 1807), False, 'from sklearn.model_selection import StratifiedKFold\n'), ((2260, 2278), 'numpy.max', 'np.max', (['accuracies'], {}), '(accuracies)\n', (2266, 2278), True, 'import numpy as np\n'), ((2303, 2321), 'numpy.min', 'np.min', (['accuracies'], {}), '(accuracies)\n', (2309, 2321), True, 'import numpy as np\n'), ((2352, 2371), 'numpy.mean', 'np.mean', (['accuracies'], {}), '(accuracies)\n', (2359, 2371), True, 'import numpy as np\n'), ((2401, 2419), 'numpy.std', 'np.std', (['accuracies'], {}), '(accuracies)\n', (2407, 2419), True, 'import numpy as np\n')]