Certificat Big Data Apprentissage TP2: Séparateurs linéaires et perceptron Correction détaillée



Documents pareils
Cours 7 : Utilisation de modules sous python

Optimisation, traitement d image et éclipse de Soleil

Introduction à MATLAB R

Python - introduction à la programmation et calcul scientifique

STAGE IREM 0- Premiers pas en Python

Exercices types Algorithmique et simulation numérique Oral Mathématiques et algorithmique Banque PT

MATLAB : COMMANDES DE BASE. Note : lorsqu applicable, l équivalent en langage C est indiqué entre les délimiteurs /* */.

Initiation à l algorithmique

Représentation d un entier en base b

Programmation linéaire

TP : Gestion d une image au format PGM

Master IMA - UMPC Paris 6 RDMM - Année Fiche de TP

Baccalauréat ES Pondichéry 7 avril 2014 Corrigé

Calcul Formel et Numérique, Partie I

Optimisation non linéaire Irène Charon, Olivier Hudry École nationale supérieure des télécommunications

Les structures de données. Rajae El Ouazzani

Coup de Projecteur sur les Réseaux de Neurones

Découverte du logiciel ordinateur TI-n spire / TI-n spire CAS

Application 1- VBA : Test de comportements d'investissements

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

IMAGES NUMÉRIQUES MATRICIELLES EN SCILAB

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Examen Médian - 1 heure 30

Licence Sciences et Technologies Examen janvier 2010


Projet Matlab/Octave : segmentation d'un ballon de couleur dans une image couleur et insertion d'un logo

1 Recherche en table par balayage

Projet Matlab : un logiciel de cryptage

Correction du baccalauréat ES/L Métropole 20 juin 2014

1 Définition et Appel d une fonction. V. Phan Luong. Cours 4 : Fonctions

La fonction exponentielle

Projet de Semestre. Page Web Didactique de Visualisation d Algorithme. Université de Genève - semestre de printemps 2012

Reconstruction de bâtiments en 3D à partir de nuages de points LIDAR

Baccalauréat ES Polynésie (spécialité) 10 septembre 2014 Corrigé

de calibration Master 2: Calibration de modèles: présentation et simulation d

TD3: tableaux avancées, première classe et chaînes

Découverte de Python

Séance 0 : Linux + Octave : le compromis idéal

Projet L1, S2, 2015: Simulation de fourmis, Soutenance la semaine du 4 mai.

Algorithmique et Programmation, IMA

L informatique en BCPST

Corrigé des TD 1 à 5

1 Représentation d une image

Introduction. I Étude rapide du réseau - Apprentissage. II Application à la reconnaissance des notes.

AWS avancé. Surveiller votre utilisation d EC2

4.2 Unités d enseignement du M1

Présentation du langage et premières fonctions

Bases de programmation. Cours 5. Structurer les données

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Exercices Corrigés Premières notions sur les espaces vectoriels

Cours 1 : La compilation

1. Structure d'un programme FORTRAN 95

Algorithmique I. Algorithmique I p.1/??

Opérations de base sur ImageJ

Programmation Web. Madalina Croitoru IUT Montpellier

pyensae StockPrices September 1, Manipulation de séries financières avec la classe StockPrices

Feuille TD n 1 Exercices d algorithmique éléments de correction

Théorie et codage de l information

Vision industrielle et télédétection - Détection d ellipses. Guillaume Martinez 17 décembre 2007

Analyse de la vidéo. Chapitre La modélisation pour le suivi d objet. 10 mars Chapitre La modélisation d objet 1 / 57

Fonctions de deux variables. Mai 2011

Gnuplot. Chapitre Lancer Gnuplot. 3.2 Options des graphes

MIS 102 Initiation à l Informatique

GUIDE DE DÉMARRAGE. SitagriPro Infinite FINANCEAGRI. Un service. c o r p o r a t e

4 Exemples de problèmes MapReduce incrémentaux

Baccalauréat S Antilles-Guyane 11 septembre 2014 Corrigé

Programmation avec Xcas ou Python

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

I. Programmation I. 1 Ecrire un programme en Scilab traduisant l organigramme montré ci-après (on pourra utiliser les annexes):

3.2. Matlab/Simulink Généralités

Etude des propriétés empiriques du lasso par simulations

Baccalauréat L spécialité, Métropole et Réunion, 19 juin 2009 Corrigé.

Compléments de documentation Scilab : affichage de texte et formatage de nombres

Travaux pratiques avec RapidMiner

BACCALAURÉAT GÉNÉRAL SESSION 2012 OBLIGATOIRE MATHÉMATIQUES. Série S. Durée de l épreuve : 4 heures Coefficient : 7 ENSEIGNEMENT OBLIGATOIRE

Perl Orienté Objet BioPerl There is more than one way to do it

Cours d initiation à la programmation en C++ Johann Cuenin

Outils pour les réseaux de neurones et contenu du CD-Rom

L ALGORITHMIQUE. Algorithme

C f tracée ci- contre est la représentation graphique d une

La classification automatique de données quantitatives

Initiation à la programmation en Python

Tp 1 correction. Structures de données (IF2)

Simulation de variables aléatoires

Limitations of the Playstation 3 for High Performance Cluster Computing

Exo7. Calculs de déterminants. Fiche corrigée par Arnaud Bodin. Exercice 1 Calculer les déterminants des matrices suivantes : Exercice 2.

CHAPITRE I. Modélisation de processus et estimation des paramètres d un modèle

Formats d images. 1 Introduction

Exercices - Fonctions de plusieurs variables : corrigé. Pour commencer

Corrigé des exercices sur les références

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Fonctions de plusieurs variables

ARDUINO DOSSIER RESSOURCE POUR LA CLASSE

Souad EL Bernoussi. Groupe d Analyse Numérique et Optimisation Rabat http ://

Programmation Python pour Arcgis

TP, première séquence d exercices.

TP 1 Introduction à Matlab Février 2009

COURS ALGORITHMIE. Mathématiques. Le monde merveilleux des algorithmes!! Croyez-moi, vous allez les adorer. Julien Bordas T.S 3

Cours de Systèmes d Exploitation

Transcription:

Certificat Big Data Apprentissage TP2: Séparateurs linéaires et perceptron Correction détaillée Olivier Schwander Ce document s accompagne d une archive contenant les codes sources, décomposé en plusieurs modules Python. Pour des raisons de concisions, la plupart des directives import sont omises : elles peuvent se déduire du code ou être retrouvées dans les fichiers sources. 1 Chargement des données Les données USPS sont réparties dans deux fichiers : la base d apprentissage zip.train.gz, la base de test zip.test.gz. On commence par écrire une fonction générique capable de charger l un ou l autre de ces fichiers : def load_file(path): raw = np.loadtxt(path) labels = raw[:, 0] # Première colonne: chiffre data = raw[:, 1:] # Deuxième colonne: pixels de l image return data, labels Puis deux fonctions pour charger une base ou l autre : def load_train(): return load_file("usps/zip.train.gz") def load_test(): return load_file("usps/zip.test.gz") Une fonction d affichage d une image est utile pour les tests : def display(img): img = img.reshape(16, 16) # Mise sous forme matricielle de l image pyplot.imshow(img, cmap=pyplot.gray()) # Affichage en niveau de gris pyplot.show() 1

2 Méthode des moindres carrés 2.1 Outils Deux variables vont être nécessaire dans la suite : max_iter pour limiter le nombre d itérations de la descente de gradient, epsilon qui représente le coefficient de la descente de gradient. On définit ces variables avec deux valeurs qui pourront éventuellement être adaptées par la suite : max_iter = 100 epsilon = 1e-3 La fonction F calcule la sortie pour une entrée x : def F(weights, x): return np.dot(weights, x) La fonction suivante permet de transformer un problème multi-classe en un problème de classification binaire. On attribue l étiquette +1 au point de la classe donnée en argument, et l étiquette 1 à tous les autres. def two_classes(labels, label_of_interest): n = labels.shape[0] ones = np.ones(n) minus_ones = -np.ones(n) return np.select([labels == label_of_interest, labels!= label_of_interest], [ones, minus_ones]) 2.2 Mise à jour La mise à jour des poids s effectue pour une entrée x et sa classe T x (+1 ou 1) avec la formule suivante : w i w i + ɛ(t x F (x))x i La fonction qui réalise cette mise à jour s écrit : def update(weights, x, t): error = (t - F(weights, x)) weights += epsilon * error * x Une version moins compacte et équivalente (bien que plus lente) pourrait s écrire : def update(weights, x, t): error = (t - F(weights, x)) for i in range(len(weights): weights[i] += epsilon * error * x[i] 2

2.3 Boucle La phase d apprentissage proprement dite est une méthode itérative qui applique la règle de mise à jour jusqu à la convergence de la fonction de coût. Une première version considère que la convergence est réalisée au bout d un certain nombre d itérations et s arrête donc au bout d un nombre fixe d étapes : def train1(data, labels): n = data.shape[0] # Nombre d observations d = data.shape[1] # Dimension des observations (et donc taille du vecteur de poids) iter_count = 0 weights = np.zeros(d) while iter_count < max_iter: for i in range(n): # Boucle sur toutes les observations update(weights, data[i], labels[i]) iter_count += 1 return weights Remarque : on initialise le vecteur de poids au vecteur nul. Une version plus évoluée calcule l erreur globale à chaque itération et s arrête quand celle-ci ne varie plus beaucoup (moins qu un certain seuil) : def train2(data, labels): n = data.shape[0] d = data.shape[1] iter_count = 0 weights = np.zeros(d) error_old = 0.0 error = 1.0 while iter_count < max_iter and abs(error - error_old) < 1e-3: error_old = error error = 0.0 # Erreur globale for i in range(n): update(weights, data[i], labels[i]) error += (labels[i] - F(weights, data[i]))**2 # Erreur sur une observation iter_count += 1 return weights 3

La troisième fonction sauvegarde les erreurs au fur et à mesure de façon à pouvoir tracer la courbe de l évolution de la fonction de coût : def train3(data, labels): n = data.shape[0] d = data.shape[1] iter_count = 0 weights = np.zeros(d) errors = [] # Liste des valeurs de l erreur globale error_old = 0.0 error = 1.0 while iter_count < max_iter and abs(error - error_old) > 1e-3: error_old = error error = 0.0 for i in range(n): update(weights, data[i], labels[i]) error += (labels[i] - F(weights, data[i]))**2 iter_count += 1 errors.append(error) # Sauvegarde de l erreur globale return weights, errors Attention : cette fonction renvoie maintenant un couple avec les poids et les erreurs, au lieu de simplement renvoyer les poids. 2.4 Interface Il reste encore à gérer le biais. On écrit pour cela une nouvelle fonction qui va se charger de rajouter une colonne aux données : def append_bias(data): n = data.shape[0] d = data.shape[1] ones = np.ones((n, 1)) # Colonne de 1 à rajouter data2 = np.concatenate([data, ones], axis=1) # Grâce à axis=1, c est une colonne # que l on rajoute return data2 Pour simplifier l utilisation des différentes fonctions, on va définir une dernière fonction avec un paramètre optionnel pour choisir si on veut utiliser une version avec ou sans la liste des erreurs en 4

sortie et qui va se charger d ajouter le biais : def train(data, labels, with_errors=false): data2 = append_bias(data) if with_errors: return train3(data2, labels) # weights, errors else: return train2(data2, labels) # weights 2.5 Prédiction On définit la fonction de Heaviside : def h(x): if x > 0: return 1 else: return -1 Deux fonctions permettent de prédire la classe d une entrée : la première calcule F et applique le seuillage, la seconde rajoute le biais et appelle la première fonction. def predict2(weights, x): return h(f(weights, x)) def predict(weights, x): ones = np.ones(1) x2 = np.concatenate([x, ones], axis=0) return predict2(weights, x2) 3 Évaluation sur des données aléatoires et visualisation On génère 20 points en dimension 2, à partir de deux lois normales : n = 10 d = 2 data0 = np.random.randn(n, d) + 3 data1 = np.random.randn(n, d) - 3 data = np.concatenate([data0, data1]) labels = np.concatenate([np.zeros(n), np.ones(n)]) # Deux classes étiquettées 0 et 1 labels = perceptron.two_classes(labels, 0) # Deux classes étiquettées -1 et 1 On apprend le perceptron sur ces données, en récupérant la liste des erreurs : 5

weights, errors = perceptron.train(data, labels, with_errors=true) print(weights) On affiche les classes prédites sur notre modèle pour les données d apprentissage : for i in range(data.shape[0]): print(i, labels[i], perceptron.predict(weights, data[i]), data[i]) Une visualisation des points et de l hyperplan : pyplot.scatter(data0[:,0], data0[:,1], marker="x", color="r", s=100) pyplot.scatter(data1[:,0], data1[:,1], marker="*", color="b", s=100) x0 = 0 y0 = -weights[2]/weights[1] x1 = -weights[2]/weights[0] y1 = 0 a = (y1 - y0) / (x1 - x0) b = y0 pyplot.plot([-10, +10], [-10 * a + b, +10 * a + b], color="g") pyplot.xlim(-6, 6) pyplot.ylim(-6, 6) pyplot.show() 6 4 2 0 2 4 6 6 4 2 0 2 4 6 On trace le coût en fonction de nombre d itération : pyplot.plot(errors) 6

pyplot.show() 16 14 12 10 8 6 4 2 0 0 10 20 30 40 50 60 On pourrait faire une véritable évaluation des performances, en générant de nouveaux points pour servir de base de tests. 4 Évaluation sur la base USPS 4.1 Précision Une mesure de la qualité de la classification est la précision. On calcule le taux de points dont la classe a été prédite correctement : def accuracy(truth, output): n = truth.shape[0] return (truth == output).sum() / n On pourrait écrire cette fonction de façon plus claire (mais plus lente) : def accuracy(truth, output): n = truth.shape[0] accur = 0. for i in range(n): if truth[i] == output[i]: accur += 1 return accur / n 7

4.2 Évaluation pour un chiffre On charge les données : data, labels = usps.load_train() data_test, labels_test = usps.load_test() Dans un premier temps, on se concentre sur le chiffre 1. On transforme les 10 classes en seulement deux classes +1 pour 1 et -1 pour les autres chiffres : labels_1 = perceptron.two_classes(labels, 1) On apprend le modèle : weights, errors = perceptron.train(data, labels_1, with_errors=true) On mesure les performances avec la précision, sur la base d apprentissage et la base de test : output = np.array([ perceptron.predict(weights, x) for x in data ]) print("score (train)", accuracy(labels_1, output)) output = np.array([ perceptron.predict(weights, x) for x in data_test ]) print("score (test)", accuracy(perceptron.two_classes(labels_test, 1), output)) 4.3 Évaluation sur tous les chiffres On peut faire une boucle pour calculer la précision pour chaque chiffre, en sauvegardant pour chaque chiffre une image pour la matrice de poids et la courbe de l évolution de l erreur : for k in range(10): labels_k = perceptron.two_classes(labels, k) weights, errors = perceptron.train(data, labels_k, with_errors=true) print(k) output = np.array([ perceptron.predict(weights, x) for x in data ]) print(" Score (train)", accuracy(labels_k, output)) output = np.array([ perceptron.predict(weights, x) for x in data_test ]) print(" Score (test)", accuracy(perceptron.two_classes(labels_test, k), output)) pyplot.clf() pyplot.imshow(weights[:-1].reshape((16, 16)), cmap=pyplot.gray()) pyplot.colorbar() pyplot.savefig("usps_" + str(k) + "-weights.png") pyplot.plot(errors) pyplot.savefig("usps_" + str(k) + "-errors.png") On obtient les précisions suivantes : 8

Chiffre Apprentissage Test 0 0.987 0.971 1 0.992 0.988 2 0.971 0.957 3 0.976 0.951 4 0.976 0.960 5 0.975 0.964 6 0.982 0.982 7 0.965 0.968 8 0.952 0.938 9 0.958 0.956 On peut visualiser la matrice de poids pour le chiffre 1 : 5 Utilisation de la bibliothèque sklearn Dans la suite du cours, on utilisera essentiellement la bibliothèque sklearn qui contient de nombreux algorithmes d apprentissage, ainsi que de fonctions utiles pour l évaluation de performances. L expérience précédente sur la base USPS se résume à : import numpy as np from matplotlib import pyplot 9

from sklearn.linear_model.perceptron import Perceptron from sklearn.metrics import accuracy_score import usps import perceptron # Pour la fonction two_classes data, labels = usps.load_train() data_test, labels_test = usps.load_test() for k in range(10): labels_k = perceptron.two_classes(labels, k) net = Perceptron() net.fit(data, labels_k) output_train = net.predict(data) output_test = net.predict(data_test) print(k) print(" Score (train)", accuracy_score(labels_k, output_train)) labels_k_test = perceptron.two_classes(labels_test, k) print(" Score (test)", accuracy_score(labels_k_test, output_test)) Les scores de classification obtenus sont très proches (les différences proviennent de différents choix d implémentation) : Chiffre Apprentissage Test 0 0.993 0.982 1 0.992 0.986 2 0.977 0.957 3 0.984 0.968 4 0.976 0.962 5 0.975 0.962 6 0.983 0.980 7 0.992 0.989 8 0.980 0.961 9 0.980 0.972 10