from k2datascience import classification
from k2datascience import plotting

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
%matplotlib inline

"""
Explanation: Classifiers Exercises
Timothy Helton
Labeled Faces in the Wild
These exercises use pictures of famous people collected over the internet.
Scikit-Learn Reference

<br>
<font color="red">
    NOTE:
    <br>
    This notebook uses code found in the
    <a href="https://github.com/TimothyHelton/k2datascience/blob/master/k2datascience/classification.py">
    <strong>k2datascience.classification</strong></a> module.
    To execute all the cells do one of the following items:
    <ul>
        <li>Install the k2datascience package to the active Python interpreter.</li>
        <li>Add k2datascience/k2datascience to the PYTHON_PATH system variable.</li>
        <li>Create a link to the classification.py file in the same directory as this notebook.</li>
</font>

Imports
End of explanation
"""


wf = classification.WildFaces(n_faces=70)
wf.data.shape

"""
Explanation: Load Data

Exercise 1: Explore Data
1.1: Open dataset and only select those faces for which we have 70 or more images.
End of explanation
"""


wf.faces_plot()

"""
Explanation: 1.2: Print a few of the faces to familiarized yourself with the data.
End of explanation
"""


wf.targets_barplot()

"""
Explanation: 1.3: Graph the count vs different labels.
End of explanation
"""


wf.calc_pca()
wf.var_pct[wf.var_pct.cumsum() < .99].tail(1).index[0]

"""
Explanation: 1.4: Notice that the number of features in our dataset is fairly large. This is a good moment to apply PCA to reduce the dimensionality of our dataset. Lets choose 150 components.
End of explanation
"""


wf.avg_face_plot()

"""
Explanation: 1.5: A really cool thing about PCA is that it lets you compute the mean of each entry which we can then use to obtain the 'average' face in our dataset.
End of explanation
"""


wf.components_plot()

"""
Explanation: 1.6: Plot the components of the PCA. Notice that these are always ordered by importance.
End of explanation
"""


wf.classify_data(model='LR')
print(wf.score)
print(wf.log_loss)
wf.confusion
print(wf.classification)

"""
Explanation: Exercise 2: Models
2.1a. Logistic Regression
End of explanation
"""


wf.accuracy_vs_k()

wf.classify_data(model='KNN', n=9)
print(wf.score)
print(wf.log_loss)
wf.confusion
print(wf.classification)

"""
Explanation: 2.1b: K-Neighbors Classifier
End of explanation
"""


wf.classify_data(model='LDA')
print(wf.score)
print(wf.log_loss)
wf.confusion
print(wf.classification)

"""
Explanation: 2.1c: Linear Discriminant
End of explanation
"""


wf.classify_data(model='NB')
print(wf.score)
print(wf.log_loss)
wf.confusion
print(wf.classification)

"""
Explanation: 2.1d: Naive Bayes
End of explanation
"""


wf.classify_data(model='QDA')
print(wf.score)
print(wf.log_loss)
wf.confusion
print(wf.classification)

"""
Explanation: 2.1d: Quadratic Discriminat Analysis
End of explanation
"""


plotting.confusion_heatmap_plot(wf.confusion, wf.target_names,
                                title='Labeled Faces in the Wild')

"""
Explanation: 2.2: Which one had the best performance? Which one had the worst performance?
FINDINGS

Logistic Regression had the best score of 0.820.
Naive Bayes had the worst score of 0.453.

2.3: Any idea why the score on the top two differs so drastically from the last two?
The linear models more accurately describe this dataset.
2.4: Find the log_loss, precision, recall, f_score of the best model.
2.5: Plot the Confusion Matrix of the best model.
End of explanation
"""


