A l’heure actuelle l’intelligence artificielle est au cœur de tous les débats et cette discipline sera l’un des prochains défis du monde informatique. Depuis des années les chercheurs se sont penchés sur cette problématique, et avec la puissance de calcul augmentant, nous voyons de plus en plus d’exemples d’utilisations (Watson avec Geopardize, Alpha GO). Un des acteurs dans ce domaine est Microsoft, avec son offre Azure Machine Learning.

Cette offre possède de nombreux avantages notamment un studio, mais également des algorithmes préétablis, ainsi que l’exposition du modèle directement sous forme de WebServices. Cependant, l’un de ses avantages peut également se transformer en désavantage : le fait de devoir toujours avoir une connexion internet, dans un monde où la mobilité est de plus en plus présente mais pas forcément la connexion, il est bien d’avoir des solutions fonctionnant hors ligne.

Lors de la conférence annuelle (//Build 2018) de Microsoft à destination des développeurs, l’éditeur a annoncé la mise à disposition d’un package Nuget permettant de faire du machine learning  dans ses applications.

Nous sommes encore sur la naissance de ce framework open-source et cross-plateforme disponible sur github, (à l’heure où sont écrites ces lignes, nous sommes à la version 0.2.0), mais celui-ci laisse entrevoir l’énorme potentiel qui s’adresse à nous en tant que développeur.

L’un des avantages de cette solution est d’avoir son modèle en local, et surtout de pouvoir construire son propre modèle d’apprentissage. De plus ce framework n’est pas une enième brique indépendante, mais s’intègre dans un écosystème existant, pour venir compléter des technologies comme Tensorflow, CNTK, mais également permettre de manipuler l’intelligence artificielle à travers du C# et ne pas laisser ce domaine seulement à Python, R, …

Pourquoi avoir besoin du machine learning ?

Si vous n’êtes pas familiarisé avec le machine learning, une question légitime à se poser est : pourquoi aurions-nous besoin de ce type de mécanisme dans nos applications ? La réponse est plutôt simple, cela va nous permettre de programmer l’improgrammable. En prenant par exemple la problématique d’identifier si une photo contient un visage, avec une programmation traditionnelle il faudrait enchaîner une multitude de branchements afin de décrire ce qu’est un visage dans une image. Cette solution pourrait fonctionner mais elle serait énormément gourmande en temps de programmation. C’est ici qu’intervient le machine learning, nous pouvons donner un ensemble de photos et indiquer à l’algorithme quelle image contient un visage ou non.

Cette solution n’est pas magique, car il va falloir des données diversifiées et en quantité importante pour avoir un apprentissage de qualité. Le risque sinon est d’introduire un biais dans le modèle et d’orienter les décisions dans une mauvaise direction.

Il existe trois grandes tâches dans le domaine du machine learning :

  • Classification
  • Regression
  • Clustering

Exemple, les données du Titanic

Afin de prendre un exemple qui sort un peu de ceux proposés de base par Microsoft, et faire comprendre l’intérêt du machine learning, nous allons nous intéresser à une étude sociologique sur la catastrophe du Titanic.

L’expérimentation va se dérouler en deux temps. Dans un premier temps nous allons travailler sur un fichier Excel afin d’appréhender les données et simuler une prédiction à base de branchements conditionnels. Le but de la prédiction est de savoir si une personne va survivre. Pour cela nous entraînerons le modèle dans les deux cas avec les données présentes dans l’onglet Train (699 personnes) et nous testerons nos modèles sur l’onglet Test Data (192 personnes). Dans un second temps, nous reprendrons ce même exemple pour le traiter avec ML.NET.

Le jeu de données est présenté de la façon suivante (onglet Train) :

  • PassengerId
  • Survived (colonne que nous devons prédire)
  • Pclass (la classe du ticket (1ère, 2ème, 3ème))
  • Sex
  • Age
  • SibSp (nombre de frères / sœurs, épouses à bord)
  • Parch (nombre de parents, enfants à bord)
  • Ticket (numéro du ticket)
  • Fare (prix du ticket que nous avons arrondi)
  • Cabin (numéro de la cabine)
  • Embarked (port d’embarquement, C = Cherbourg, Q = Queenstown, S = Southampton)
  • AgeGroup (permet de catégoriser les âges en 3 catégories) [Généré pour le traitement par excel]
  • PriceGroup (permet de catégoriser les prix en 3 catégories) [Généré pour le traitement par excel]

A partir de maintenant il va falloir travailler sur les données pour en dégager un modèle. Il n’y a pas de recette miracle la plupart du temps il faut travailler avec son intuition, faire des hypothèses et expérimenter. Pour cela on va s’aider d’une fonctionnalité d’Excel : PivotTable.

Une première approche est de partir sur l’hypothèse qu’être une femme favorise les chances de survie (onglet : Model 1). Une femme a effectivement 74% de chance de survie. En appliquant directement ce modèle à savoir =IF(sex=”male”;0;1) dans Excel, alors nous avons un résultat de prédiction de l’ordre de 79% de réussite sur notre échantillon de test.

 

Une deuxième hypothèse expérimentée sur l’onglet Model 2, est de prendre en considération l’âge, en effectuant le comparatif nous voyons que la proportion de survie entre enfant et adulte n’a que très peu d’incidence sur le pourcentage de survie. Nous pouvons donc considérer que cette variable n’est pas importante.

Une troisième hypothèse (onglet : Model 3) est de prendre en compte la classe du billet ici nous voyons une incidence sur la proportion de survie, notamment avec les personnes ayant un billet de 3ème classe.

La dernière hypothèse est de travailler sur le prix des billets (Onglet : Model 4) où nous pouvons constater de légère fluctuation qui pourront améliorer notre modèle.  Notre modèle devient ainsi :

=IF(Sex=”male”;0;IF(Class=3;IF(Fare>20;0;1);1))

Nous obtenons un pourcentage de réussite de prédiction de 82%.

Un peu de programmation

Nous allons maintenant travailler avec ML.NET afin de pouvoir réaliser un comparatif. Afin de simplifier le code nous avons transformé l’onglet Train ainsi que l’onglet TestData en CSV.

Commençons par créer une application console sous .NET CORE.

Rajoutons le package Nuget Microsoft.ML

Maintenant que nous avons la base, nous allons construire notre pipeline d’apprentissage. Vous pouvez retrouver le code dans la classe Prediction dans la méthode Training.

Nous devons ensuite charger nos données de notre fichier CSV, pour cela nous devons créer une classe qui servira à stocker l’emplacement des données pour l’apprentissage de notre modèle.

Nous utilisons l’attribut colonne pour spécifier l’ordre de l’information dans le fichier, vous pouvez également spécifier un nom pour les colonnes. Dans notre cas, nous avons taggé l’information « survived » avec le nom Label car c’est cette colonne que nous souhaitons prédire.

Pour charger les données dans notre modèle, il faut utiliser la classe TextLoader que nous paramétrons avec la classe que nous venons de créer. N’oubliez pas de spécifier le séparateur, par défaut celui-ci est TAB.

Une fois les données chargées, nous devons les transformer en entier pour qu’elles puissent être interprétées par le pipeline. Dans notre cas afin de gagner du temps j’ai raffiné déjà les données en transformant par exemple la colonne « Sex » en 0 et en 1, de même pour la colonne « TEmbarked », celle-ci a été transformée en nombre plutôt que d’utiliser les caractères. Pour réaliser cela vous avez plusieurs classes à votre disposition dont Dictionarizer (transforme un texte en un nombre), TextFeaturizer (transforme le texte en un vecteur de nombres, basé sur un système de m-grams extractions).

Maintenant nous allons devoir construire le vecteur Features qui indiquera à notre modèle les colonnes pertinentes pour faire son apprentissage. Nous concaténons donc les colonnes pour produire une colonne Features, dans laquelle  nous pouvons mettre plus de colonnes que dans notre modèle sous Excel étant donné que la complexité est gérée par le framework :

Nous pouvons également améliorer légèrement notre apprentissage car en regardant nos données on s’aperçoit que la colonne âge n’est pas remplie pour tous les éléments, nous pouvons donc exclure ces lignes lorsque la valeur est vide.

La partie traitement des données est finalisée, il nous faut donc choisir l’algorithme d’apprentissage. Ici pas de recette magique à chaque projet son algorithme, dans notre cas nous partirons avec un algorithme de type : FastForestBinaryClassifier. Celui-ci peut prendre des hyperparameters (NumLeaves, NumTrees, …) permettant de faire varier les résultats.

Nous devons indiquer maintenant sur quel champ de notre objet nous souhaitons prédire la valeur :

On lance l’entraînement :

Le modèle est maintenant entraîné. Nous sommes dans un cas où l’apprentissage est relativement rapide vu la faible quantité de données que nous avons, mais pour l’exercice nous pouvons sauvegarder le modèle. Cette capacité permet d’avoir un projet dédié uniquement à l’apprentissage et inclure le modèle ensuite dans le projet qui devra l’exploiter.

Le chargement du modèle se fait d’une façon tout aussi simple :

Exploitons enfin notre modèle

Pour cela nous allons récupérer les données du fichier TitanicPredict.csv à travers le Framework CSVHelper. Lorsque vous avez votre liste d’objets vous devez l’envoyer à votre modèle afin qu’il vous fournisse ses prédictions.

ManifestPrediction contient la colonne prédite « Survived » taggée avec le nom de colonne PredictedLabel, ainsi que l’id du survivant qui va nous permettre de consolider nos données.

L’ensemble de ces résultats sont stockés dans un fichier output.csv.

J’ai rajouté ces résultats dans notre fichier Excel de départ dans l’onglet « Test Data » afin de faire une comparaison sur le taux de réussite, celui-ci est de 87%. Ce qui est légèrement mieux que le résultat obtenu à la main avec uniquement des if.

Pour aller plus loin

Nous pourrions encore améliorer nos résultats avec plus de données et en testant divers paramètres. Pour cela le framework nous fournit également des evaluators avec différentes mesures. Dans notre cas nous pouvons utiliser BinaryClassificationEvaluator, il faut également lui fournir des données, pour cette démo j’ai transféré un set de données du fichier d’entraînement afin de créer le fichier test. Bien entendu plus il y a de donnée plus ce test sera pertinent.

De manière générale, l’amélioration des modèles passe par le fait d’augmenter le nombre de données, d’éviter les cas extrêmes (événement extérieur rare), rajouter des dimensions (croiser avec des données météos par exemple …).

Conclusion

Bien que le framework proposé par Microsoft ne soit pas encore en Release, il offre déjà d’énormes capacités, pour très peu d’efforts de développement. Le processus pour faire du machine learning avec ce framework peut se résumer avec le schéma suivant :

Dans cet exemple nous n’avons traité que le cas de la Classification, mais ML.NET permet déjà de traiter la régression avec des algorithmes de type FastTreeRegressor ou de clustering avec KMeansPlusPlusClusterer.

Les domaines d’application de l’IA dans vos projets sont très variés, nous pouvons citer par exemple :

  • l’analyse de sentiments dans les commentaires
  • la détection de faux commentaires
  • la prédiction de ventes d’un objet dans le futur permettant d’avoir une gestion des stocks plus efficiente
  • la production de notes de musiques

Cependant Il ne faut pas tomber dans le travers de tout ré-implémenter, avant de vous lancer dans la construction d’un modèle, il faut s’assurer qu’il n’existe pas déjà, ou si un modèle proche du votre pourrait être détourné afin de répondre à votre besoin.

Vous pouvez retrouver les sources de ce projet sur notre github.