"""
================
Confusion matrix
================

Example of confusion matrix usage to evaluate the quality
of the output of a classifier on the iris data set. The
diagonal elements represent the number of points for which
the predicted label is equal to the true label, while
off-diagonal elements are those that are mislabeled by the
classifier. The higher the diagonal values of the confusion
matrix the better, indicating many correct predictions.

The figures show the confusion matrix with and without
normalization by class support size (number of elements
in each class). This kind of normalization can be
interesting in case of class imbalance to have a more
visual interpretation of which class is being misclassified.

Here the results are not as good as they could be as our
choice for the regularization parameter C was not the best.
In real life applications this parameter is usually chosen
using :ref:`grid_search`.

"""

print(__doc__)

import numpy as np
import matplotlib.pyplot as plt

from sklearn import svm, datasets
from sklearn.cross_validation import train_test_split
from sklearn.metrics import confusion_matrix


#To pickle y_test and y_pred
from sklearn.externals import joblib
#To work with paths
import os

#Paths for file saving
module_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')
models_path = os.path.join(module_path, 'dummy_models')
baselline_path = os.path.join(module_path, 'baseline_images')


# import some data to play with
iris = datasets.load_iris()
X = iris.data
y = iris.target

# Split the data into a training set and a test set
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

# Run classifier, using a model that is too regularized (C too low) to see
# the impact on the results
classifier = svm.SVC(kernel='linear', C=0.01)
y_pred = classifier.fit(X_train, y_train).predict(X_test)

#Pickle arrays so tests can use them
joblib.dump(y_test, os.path.join(models_path, 'confusion_matrix_y_test.pkl'))
joblib.dump(y_pred, os.path.join(models_path, 'confusion_matrix_y_pred.pkl'))


def plot_confusion_matrix(cm, title='Confusion matrix', cmap=plt.cm.Blues):
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(iris.target_names))
    plt.xticks(tick_marks, iris.target_names, rotation=45)
    plt.yticks(tick_marks, iris.target_names)
    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')


# Compute confusion matrix
cm = confusion_matrix(y_test, y_pred)
np.set_printoptions(precision=2)
print('Confusion matrix, without normalization')
print(cm)
cf = plt.figure()
plot_confusion_matrix(cm)

#Save confusion matrix
cf.savefig(os.path.join(baselline_path, 'confusion_matrix.png'))

# Normalize the confusion matrix by row (i.e by the number of samples
# in each class)
cm_normalized = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
print('Normalized confusion matrix')
print(cm_normalized)
ncf = plt.figure()
plot_confusion_matrix(cm_normalized, title='Normalized confusion matrix')
#plt.show()

#Save normalized confusion matrix
ncf.savefig(os.path.join(baselline_path, 'normalized_confusion_matrix.png'))