Machine Learning avec le cloud Amazon AWS

Il fut un temps où l’étude de l’apprentissage automatique ou apprentissage statistique était mon quotidien. Depuis on est passé du machine learning au Deep Learning sous fond de  cloud computing. Beaucoup de mots nouveaux pour des concepts pas si neufs en fait. En revanche, je dois avouer que le syntagme « Deep Learning » est un tantinet de rien du tout plus bankable et sexy que le titre d’un mémoire tel que: « Optimisation d’ensembles de classifieurs non paramétriques avec apprentissage par représentation partielle de l’information« . Et pour être tout à fait honnête il ne s’agit pas non plus exactement de la même chose.

Il fut donc un temps pas si lointain où je m’intéressais de près aux problématiques d’apprentissage. Depuis, pour toutes sortes de raison dont celle-ci, j’ai commencé à m’intéresser aussi aux services de cloud computing (doit-on vraiment dire infonuagique ?), notamment ceux offerts par Amazon (un célèbre vendeur de chaussettes et autres bidules essentiels).

Ce vendeur de babioles toutes aussi nécessaires les unes que les autre offre aussi un ensemble de services infonuagiques (AWS) pas piqué des hannetons.

Récemment, au gré de mes pérégrinations autour dece service, je rencontre cette promesse: Amazon Machine Learning. Forcément, cela m’interpelle aussi tins-je mordicus à tenter l’expérience.

La promesse est donc la suivante: on fournit des données en entrée, Amazon fournit la capacité de calcul et le savoir faire pour créer un modèle de prédiction, ou de classification sans trop avoir besoin de s’encombrer des détails d’implémentation.

Je veux tester. Alors comment faire ?

Le plus évident me semble alors de ressortir de fond des boules à mites des données sur lesquelles j’ai déjà pu travailler. En l’occurrence une célèbre base de données étiquetées de chiffres manuscrits (MNIST) dont voici quelques exemples ci-dessous.

Exemples de chiffres issus de la base de données MNIST
Exemples de chiffres issus de la base de données MNIST

Je me propose donc ici de relater cette expérience. Cette base de données a été exploitée par de nombreux chercheurs, et notamment Luis Oliviera qui vers 2003 obtenait un taux de reconnaissance de plus de 99%. Moi-même, dans un contexte légèrement différent mais sur les mêmes données, j’arrivais autour de 97%. La question est donc la suivante: comment, hors des laboratoires de recherche et 10 à 15 ans plus tard, les services grand public performent-ils?

Préparation de la base de données

L’aide en ligne de Amazon ML stipule que les données d’apprentissage doivent être au format CSV (Comma-separated values). Chaque ligne représente une observation et les colonnes représentes les différentes caractéristiques extraites pour chacune des observations. Dans notre cas, j’utilise les concavités et countours présentés par Olivera dans l’article « A methodology for feature selection using multiobjective genetic algorithms for hand written digit string recognition« .

Il s’agit globalement d’histogrammes sur les concavités (6 vecteurs de 13 dimensions = 78 caractéristiques).

Histograme des concavités
Histogramme des concavités

Concaténés avec 6 autres vecteurs d’histogramme des contours (6 vecteurs de 8 dimensions = 48 caractéristiques).

Histograme des contours
Histogramme des contours

Finalement, l’aire (nombre de pixels noirs) de chacune des 6 régions est ajoutée pour donner créer un point dans un espace de 78 + 48 + 6 = 132 dimensions. Les différents histogrammes sont normalisés mais je laisse le lecteur curieux le soin de se référer à l’article original pour en connaitre tous les détails.

Chacune des observations, ici des chiffres manuscrits, est donc réduite à n’être plus qu’un point dans cet espace de 132 dimensions.

J’ai retrouvé quelques unes des ces bases de données avec les caractéristiques extraites. Il ne reste plus qu’à les restructurer légèrement afin que Amazon ML puisse les lire. Il me faut donc les transformer au format CSV. Puisque dans mes fichiers les champs sont séparés par une espace (j’insiste sur le caractère féminin de ce mot dans le contexte typographique) et non pas par une virgule, un petit coup de

[pastacode lang= »bash » manual= »%20sed%20’s%2F%20%2F%2C%2Fg’%20TRAIN1k%20%3E%20TRAIN1k.csv » message= »Remplacer les espaces par des virgules dans un fichier » highlight= » » provider= »manual »/]

fera l’affaire pour remplacer toutes les espaces par de virgules.

Il est aussi dit que chacune des colonnes doit être identifiée par un nom. Pour ce faire, il existe deux méthodes. La première consiste à mettre le nom de chacune des caractéristiques au format CSV sur la première ligne du fichier. La seconde est des mettre ces informations dans un second fichier au même format. J’opte pour la seconde méthode puisque qu’elle me permettra de réutiliser le même fichier pour différentes base de données (en faisant varier la taille des données d’apprentissage par exemple). L’alternative étant de coller cette en-tête au début de chaque nouveau fichier. Au final, je me suis aperçu que nommer les colonnes était tout à fait optionnel.

Nommer nos caractéristiques ne ressemble évidemment à rien dans notre cas quand on comprend comment elles ont été extraites. Je choisis donc de les nommer Feature_1, Feature_2, etc. La dernière colonne se nommera Target puisque c’est la cible (la bonne réponse, la classe recherchée). Le petit one liner (oserais-je un uniligne?) qui va bien est le suivant:

[pastacode lang= »bash » manual= »for%20I%20in%20%60seq%20132%60%3B%20do%20echo%20-ne%20%22Feature_%24I%2C%22%3B%20done%20%3E%20header.csv%3B%20%20echo%20Target%20%3E%3E%20header.csv » message= »Générations des noms de colonnes dans un fichier CSV » highlight= » » provider= »manual »/]

J’ai donc 133 valeurs séparées par des virgules, les 132 premières étant Feature_1, Feature_2, et la dernière Target. Ce qui correspond à mon fichier d’entrée.

Upload du fichier

Il faut le mettre dans S3 (ou Redshift). Par exemple j’en ai mis un ici. Le fichier d’en-tête est quant à lui ici.

Il faut bien s’assurer que Amazon ML a les permissions pour accéder aux fichiers déposés sur S3. Bizarrement, cela s’avère ne pas être trivial et je suis resté longtemps avec le message ci-dessous.

Message d'erreur Amazon ML
Message d’erreur Amazon ML

Une fois que le système est bien configuré, on arrive à ceci:

Capture d'écran d'Amazon ML qui est content d'avoir validé notre fichier d'entrée.
Capture d’écran d’Amazon ML qui est content d’avoir validé notre fichier d’entrée.

Attention à bien choisir le type de donnée pour la cible. Le système supporte comme entrées et sorties des valeurs binaires, des valeurs numériques, des classes et du texte.

target-data-type

 

En laissant par défaut une valeur numérique comme sortie attendue, on crée un système qui fait de la prédiction et non pas un classificateur (ou classifieur). Et on se retrouve avec des résultats farfelus comme le montre la figure plus basse (farfelu pour notre problème spécifique, la prédiction de valeur étant dans d’autres cas un excellent cas d’application de l’apprentissage supervisé).

2016-11-06-17_59_54-parametres

Ce graphique nous dit que si on confond 1 avec 2, c’est moins grave que si on confond 1 avec 9 (car 1 est plus proche de 2). En prédiction (par exemple si on cherche à prédire une grandeur physique comme une vitesse) ça peut avoir un certain sens. Par contre, en classification il n’y a pas ce genre de proximité. On a trouvé la bonne réponse ou pas. Soit c’est un 1, soit c’est un 2, mais ce n’est pas entre les deux.

Donc on reprend. On choisi bien une target qui sera une Category.

Une fois l’apprentissage terminé, on a intérêt tester avec une nouvelle base de données, appelée base de test (ou de validation mais n’entrons pas dans ces détails). J’ai créé un premier modèle à partir de 5000 observations (uniformément distribuées). Et un base de test de 25000.

Le processus est vraiment simple. Une fois la base de données accessible, on appuie sur bouton et l’apprentissage commence. Cela n’a pris que quelques minutes pour créer un modèle à partir de 5000 observations.

On ne sait rien du modèle généré mais on peut en récupérer le taux de reconnaissance. Dans ce cas, un peu moins de 95% sur la base d’apprentissage. Si on ne peut récupérer le modèle, on peut cependant l’utiliser pour faire 3 choses:

  • mesure sa performance en généralisation en lui passant une nouvelle base de données étiquetées
  • classifier des bases de données non-étiquetées
  • classifier en temps réel des observations (par exemple venant d’une application smartphone)

Je me suis arrêté à la mesure de performance en généralisation en faisant varier la taille de l’ensemble d’apprentissage. La figure plus bas montre les taux de reconnaissance obtenus sur les bases d’apprentissage et de test. On semble arriver à une asymptote autour des 98% de reconnaissance, ce qui est un score tout à fait honorable pour un classificateur complètement généraliste.

Taux de reconnaissance sur les base d'apprentissage et de test

Outre un taux de reconnaissance, Amazon ML permet de visualiser une matrice de confusion (voir ci-dessous) et même de télécharger l’ensemble des prédictions faites par le classificateur.

Matrice de confusion

Conclusion

Amazon offre la possibilité d’utiliser son infrastructure pour faire de l’apprentissage supervisé. Il n’est pas nécessaire de comprendre comment l’apprentissage se fait, il suffit d’avoir des données étiquetées, de les mettre au bon format et de les envoyer. Les résultats, du moins sur des bases issue de MNIST sont tout à fait respectables. Bien qu’on ne puisse pas récupérer les modèles, on peut les utiliser couplés avec les autres services AWS. En d’autre termes, tout un chacun peut maintenant avoir un service web basé sur de l’apprentissage supervisé sans avoir de compétences particulières dans le domaine. Il faut bien sûr des données étiquetés et surtout, de bonnes features  bien extraites. Sur ce dernier point, la prochaine étape sera peut-être un Amazon Deep Learning ou quelque service du genre, permettant de laisser au système le soin de déterminer la meilleure représentation des données.