TP 6 – scikit

Transcription

TP 6 – scikit
Master 2 IS – IN
Classification, Apprentissage, Décision
2015-2016
TP 6 – scikit-learn 2
Ce TP est à rendre avant mercredi prochain 23h59 sous la forme d'une archive à votre nom
(exemple : remi_eyraud.zip). Les différentes questions de ce sujet doivent correspondre chacune à
une fonction.
Le tout est à envoyer par mail à l'adresse [email protected] avec comme sujet ''CAD
TP6''.
Les données utilisées dans ce TP consistent en un ensemble d'images de visages de personnes
'célèbres' et le but est d'implémenter un classifieur qui assigne le bon nom à chaque image.
Voici la plupart des importations de modules dont nous allons avoir besoin :
from __future__ import print_function
from time import time
import logging
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cross_validation import train_test_split
from sklearn.datasets import fetch_lfw_people
from sklearn.grid_search import GridSearchCV
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.svm import SVC
from numpy import linalg
import numpy as np
Il y a des modules et des fonctions que nous n'avons pas encore utilisé : utiliser la documentation
pour savoir leur usage et rôle.
Les données que l'on va utilisé font partie de la distribution de Scikit-Learn, mais il vous faut quand
même une connexion internet pour les récupérer. Voici le code pour les avoir en local :
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s')
lfw_people = fetch_lfw_people(min_faces_per_person=70, resize=0.4)
n_samples, h, w = lfw_people.images.shape
X = lfw_people.data
n_features = X.shape[1]
y = lfw_people.target
target_names = lfw_people.target_names
n_classes = target_names.shape[0]
print("Total dataset size:")
print("n_samples: %d" % n_samples)
print("n_features: %d" % n_features)
print("n_classes: %d" % n_classes)
De nouveau, assurez-vous que vous comprenez ce code.
Question 1
Découper les données en 2 ensembles : un ensemble d'apprentisage X_train, y_train
comprenant 75 % des données et un ensemble de test X_test, y_test (avec donc 25 % des
données).
Question 2
Construisez un classifieur clf à partir des données en utilisant GridSearchCV pour
trouver les meilleurs paramètres (lisez la doc!). Un SVM peut être une idée, mais choisissez le
classifieur qui vous plait le plus.
Question 3
Pour améliorer les résultats, il est possible d'implémenter une ACP. Ecrivez une fonction
PCAtrain sur X_train qui retourne 4 valeurs : vecteurs et valeurs singuliers, moyenne et
variance. L'ACP doit être réalisée sur des attributs normalisés : la moyenne de chaque attribut
d'entrée doit être 0 et l'écart-type de 1. Pour y arriver il suffit de de soustraire la moyenne et de
diviser par l'écart-type pour chaque attribut. Assurez-vous d'utiliser la même moyenne et les même
écart type pour les données d'apprentissage et les données de test…
Question 4
En utilisant la fonction précédente, déterminer combien de composantes principales il faut
utiliser pour couvrir 95 % de la variabilité des données.
Question 5
Reprendre le processus de classification de la question 2 mais en utilisant les données
transformées par l'ACP.
Question 6
Si vous avez tout fait comme il faut, il est maintenant possible d'avoir un rapport de
classification, une matrice de confusion, etc. A noter qu'il est possible d'obtenir un taux de bonne
classification supérieur à 80 %…
print("Prédiction des noms des personnes sur l'ensemble de test")
t0 = time()
y_pred = clf.predict(X_test_pca)
print("Réalisé en %0.3fs" % (time() - t0))
print(classification_report(y_test, y_pred, target_names=target_names))
print(confusion_matrix(y_test, y_pred, labels=range(n_classes)))
def plot_gallery(images, titles, h, w, n_row=3, n_col=4):
"""Fonction auxiliaire pour afficher les données"""
plt.figure(figsize=(1.8 * n_col, 2.4 * n_row))
plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35)
for i in range(n_row * n_col):
plt.subplot(n_row, n_col, i + 1)
plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray)
plt.title(titles[i], size=12)
plt.xticks(())
plt.yticks(())
# Affiche le résultat de prédiction pour une partie de l'ensemble de test
def title(y_pred, y_test, target_names, i):
pred_name = target_names[y_pred[i]].rsplit(' ', 1)[-1]
true_name = target_names[y_test[i]].rsplit(' ', 1)[-1]
return 'predicted: %s\ntrue: %s' % (pred_name, true_name)
prediction_titles = [title(y_pred, y_test, target_names, i)
for i in range(y_pred.shape[0])]
plot_gallery(X_test, prediction_titles, h, w)
#Affiche la galerie des visages propres les plus significatifs
eigenface_titles = ["eigenface %d" % i for i in range(eigenfaces.shape[0])]
plot_gallery(eigenfaces, eigenface_titles, h, w)