VI-ME-BA-BAR sur vos propres données!

Instructions:

  • Vous effacerez les instructions au fur et à mesure que vous les aurez suivies. Commencez par effacer celle-ci!

  • Mettez ici une description de votre jeu de données: où l’avez-vous trouvé, quel est le défi? Intuitivement quels critères pourraient permettre de distinguer les deux classes d’images?

  • Recherchez au fur et à mesure les commandes adéquates dans le TP 2.

%load_ext autoreload
%autoreload 2
from utilities import *

Étape 1: prétraitement et [VI]sualisation

Le jeu de données consiste en les images suivantes:

Instructions:

  • Ajuster la variable dataset_dir.

  • Rajouter au fur et à mesure les utilitaires requis – comme load_images dans utilities.py en les récupérant de la semaine dernière.

# YOUR CODE HERE
raise NotImplementedError()

Instruction: selon vos données, vous choisirez ci-dessous entre png ou jpeg

images = load_images(dataset_dir, "*.jpeg")
image_grid(images, titles=images.index)
assert len(images) == 20

Prétraitement

Extrayons dans un tableau de données les attributs (features) de nos images ainsi que leurs classes (vérité terrain, ground truth).

Instructions:

  • Dans un premier temps ajoutez ci-dessous deux attributs très simples; vous pouvez par exemple reprendre les même attributs que pour les pommes et bananes: rougeur et élongation. Comme d’habitude, vous les mettrez dans le fichier utilities.py.

  • Lors de la deuxième semaine du projet, vous implanterez de nouveaux attributs que vous rajouterez ci-dessous (sans enlever les précédents!)

df = pd.DataFrame({
	# YOUR CODE HERE
	raise NotImplementedError()
	'classe':      images.index.map(lambda name: 1 if name[0] == 'a' else -1),
})
df
assert len(df[df['classe'] ==  1]) == 10
assert len(df[df['classe'] == -1]) == 10

Pour calculer les corrélations entre colonnes, nous aurons besoin de standardiser chacune d’entre elles, à l’exception de la colonne classes!

# YOUR CODE HERE
raise NotImplementedError()
dfstd

Vérifions:

dfstd.describe()

Visualisation

Tout d’abord, extrayons quelques statistiques de base:

# YOUR CODE HERE
raise NotImplementedError()

Visualisons le tableau de données sous forme de carte de chaleur (heat map):

# YOUR CODE HERE
raise NotImplementedError()

la matrice de corrélation:

# YOUR CODE HERE
raise NotImplementedError()

ainsi que le nuage de points (scatter plot):

# YOUR CODE HERE
raise NotImplementedError()

Observations

Instructions: décrire ici vos observations: corrélations apparentes ou pas, interprétation de ces corrélations à partir du nuage de points, etc. Est-ce que les attributs choisis semblent suffisants? Quel attribut semble le plus discriminant? Est-ce qu’un seul d’entre eux suffirait? Vous compléterez visualisations et observations ultérieurement lorsque vous rajouterez de nouveaux attributs.

Étape 2: [ME]sure de performance ([ME]tric)

Pour mesurer les performances de ce problème de classification, nous utiliserons la même métrique par taux d’erreur que dans le TP2 .

Partition (split) du jeu de données en ensemble d’entraînement et ensemble de test

Séparons d’abord les attributs (dans X) de la vérité terrain (dans Y):

X = dfstd[['redness', 'elongation']]
Y = dfstd['classe']

Maintenant partitionnons nos images en ensemble d’entraînement et ensemble de test:

# YOUR CODE HERE
raise NotImplementedError()

Les images suivantes serviront à entraîner notre modèle de prédiction (prédictive model):

# YOUR CODE HERE
raise NotImplementedError()

celles-ci à le tester et à évaluer sa performance:

# YOUR CODE HERE
raise NotImplementedError()

Les voici sous forme de nuage de points en fonction de leurs attributs:

# YOUR CODE HERE
raise NotImplementedError()

Taux d’erreur

Comme la semaine dernière, nous utiliserons le taux d’erreur comme métrique, d’une part sur l’ensemble d’entraînement, d’autre part sur l’ensemble de test:

show_source(error_rate)

Étape 3: Référence ([BA]se line)

Classification

Pour obtenir une référence, nous choisissons le classifieur [VOTRE CLASSIFIEUR ICI] que nous entraînons sur l’ensemble d’entraînement:

# YOUR CODE HERE
raise NotImplementedError()

Calculons les prédictions sur l’ensemble d’entraînement et l’ensemble de test, ainsi que les taux d’erreur dans les deux cas:

# YOUR CODE HERE
raise NotImplementedError()
print("Training error:", e_tr)
print("Test error:", e_te)

Voici les prédictions obtenues:

# The training examples are shown as white circles and the test examples are black squares.
# The predictions made are shown as letters in the black squares.
make_scatter_plot(X, images.apply(transparent_background_filter),
                  train_index, test_index, 
                  predicted_labels=Ytest_predicted, axis='square')

Interprétation

Instructions: donnez ici votre interprétation des résultats. La performance des prédictions paraît elle satisfaisante? Avez vous une première intuition de comment l’améliorer?

Étape 4: [BAR]res d’erreur (error bar)

Barre d’erreur 1-sigma

Comme première estimation de la barre d’erreur, voici la barre d’erreur 1-sigma pour le taux d’erreur e_te:

# YOUR CODE HERE
raise NotImplementedError()
print("TEST SET ERROR RATE: {0:.2f}".format(e_te))
print("TEST SET STANDARD ERROR: {0:.2f}".format(sigma))

Barre d’erreur par validation croisée (Cross-Validation)

Nous calculons maintenant une autre estimation de la barre d’erreur en répétant l’évaluation de performance pour de multiples partitions entre ensemble d’entraînement et ensemble de test:

n_te = 10
SSS = StratifiedShuffleSplit(n_splits=n_te, test_size=0.5, random_state=5)
E = np.zeros([n_te, 1])
k = 0
for train_index, test_index in SSS.split(X, Y):
    print("TRAIN:", train_index, "TEST:", test_index)
    Xtrain, Xtest = X.iloc[train_index], X.iloc[test_index]
    Ytrain, Ytest = Y.iloc[train_index], Y.iloc[test_index]
    neigh.fit(Xtrain, Ytrain.ravel()) 
    Ytrain_predicted = neigh.predict(Xtrain)
    Ytest_predicted = neigh.predict(Xtest)
    e_te = error_rate(Ytest, Ytest_predicted)
    print("TEST ERROR RATE:", e_te)
    E[k] = e_te
    k = k+1
    
e_te_ave = np.mean(E)
# It is bad practice to show too many decimal digits:
print("\n\nCV ERROR RATE: {0:.2f}".format(e_te_ave))
print("CV STANDARD DEVIATION: {0:.2f}".format(np.std(E)))

sigma = np.sqrt(e_te_ave * (1-e_te_ave) / n_te)
print("TEST SET STANDARD ERROR (for comparison): {0:.2f}".format(sigma))

Conclusion

Instructions: Vous résumerez ici les performances obtenues, tout d’abord avec votre référence, puis avec les variantes que vous aurez explorées en changeant d’attributs et de classifieur. Puis vous commenterez sur la difficulté du problème ainsi que les pistes possibles pour soit obtenir de meilleures performances, soit pour généraliser le problème.