from sklearn.datasets import fetch_mldata
mnist = fetch_mldata('MNIST original')
mnist
# mnist référence un objet (jeu de données) de type dictionnaire
# La première clé décrit le jeu de données sous la forme d'une chaîne de caractères
print(type(mnist["DESCR"]))
L'ensemble des images contenue dans le jeu de données MNIST sont référencées par la clé : data du dictionnaire de type numpy.ndarray, c'est à dire tableau numpy
dataset = mnist["data"]
print(type(dataset))
print(dataset.shape)
import matplotlib
import matplotlib.pyplot as plt
digit = dataset[64600]
img_digit = digit.reshape(28,28)
plt.imshow(img_digit)
plt.show()
Chaque image est accompagnée de son étiquette qui référence le chiffre réprésenté sur l'image. L'ensemble des etiquettes est contenu dans un tableau numpy de type numpy.ndarray
etiquettes = mnist["target"]
print(type(etiquettes))
print(etiquettes[21300])
Q1 : Écrire une fonction $showDigits$ dont vous déterminerez les parèmetres permettant d'afficher sous la forme d'un tableau $[10, n]$ (avec $n\in\mathbb{N}$) l'ensemble des chiffres du jeu de données, compris entre 0 et 9, avec pour chaque chiffre n images différentes. Dans la limite bien sûr du nombre d'images disponibles pour chaque chiffre
Exemple d'un tableau $[10,10]$
Pour commencer nous allons entraîner un séparateur linéaire encore appelé classificateur binaire.
Objectif : un détecteur de 8
from sklearn.linear_model import SGDClassifier
img_digit_train = dataset[:60000] #les images pour l'entraînement
img_digit_test = dataset[60000:] #les images pour les tests
digit_train = etiquettes[:60000] #les valeurs numériques associées au images
digit_test = etiquettes[60000:] #idem
#import numpy as np
#shuffle_index = np.random.permutation(60000)
#img_digit_train = img_digit_train[shuffle_index]
#digit_train = digit_train[shuffle_index]
digit_train_8 = (digit_train == 8) #entraînement supervisé
digit_test_8 = (digit_test == 8)
sgd_clf = SGDClassifier(random_state=42)
sgd_clf.fit(img_digit_train, digit_train_8)
any_digit = dataset[21300] # un 3
any_another_digit = dataset[50000] # un 8
print(sgd_clf.predict([any_digit]))
print(sgd_clf.predict([any_another_digit]))
Q2 : Écrire une fonction $identifyDigit(x\_train, y\_train, y\_test, digit)$ permettant à l'utilisateur de choisir le chiffre à détecter.
Q3 : Écrire une fonction $perform(sgd\_clf, dataset, start, end)$ renvoyant le nombre total des chiffres mal détectés, par exemple l'image du chiffre 4 qui n'aurait pas été détecté comme la valeur numérique 4. Que remarquez-vous ?
Tous les chiffres pour lesquels ont s'attend à une réponse positive lors de la détection ne sont pas forcément validés, il est donc nécessaire d'estimer la performance de notre classificateur.
Q1 :
def showDigits(dataset, rows, columns, start_img, step):
fig=plt.figure(figsize=(8, 8))
pos = 1
for row in range(0, rows):
for col in range(0, columns):
digit = dataset[start_img + row*step + col]
img_digit = digit.reshape(28,28)
fig.add_subplot(rows, columns, pos)
plt.imshow(img_digit)
pos += 1
plt.show()
showDigits(dataset, 10, 10, 3000, 6000)
Q2 :
sgd_clf = SGDClassifier(random_state=42)
def identifyDigit(sgd_clf, x_train, y_train, y_test, digit):
digit_train = (y_train == digit) #entraînement supervisé
digit_test = (y_test == digit)
sgd_clf.fit(x_train, digit_train)
return sgd_clf
sgd_clf = identifyDigit(sgd_clf, img_digit_train, digit_train, digit_test, 4)
any_digit = dataset[64500] # un 4
any_another_digit = dataset[64550] # un autre 4
print(sgd_clf.predict([any_digit]))
print(sgd_clf.predict([any_another_digit]))
Q3 :
def performance(sgd_clf, dataset, start, end):
count = 0
for d in dataset[start:end]:
if sgd_clf.predict([d]) == False:
count += 1
return count
performance(sgd_clf, dataset, 64500, 64600)