ML.NET
ML.NET est une librairie de Machine Learning libre et multiplateforme qui permet de construire des solutions et de les intégrer aux applications .NET. D’abord développée par Microsoft Research, ML.NET a évolué et est maintenant utilisée par beaucoup de produits du groupe comme Windows, Bing et Azure.
La librairie permet de s’intégrer facilement dans des applications C# et F#, sans prérequis en développement ou optimisation de modèles de Machine Learning.
Les ingénieurs de Microsoft ont construit ML.NET avec le support de Frameworks réputés tels que Light GBM, Accord.NET, CNTK, et bientôt TensorFlow.
ML.NET permet d’améliorer ses applications .NET avec par exemple la prédiction de prix, l’analyse de textes et de sentiments, via l’utilisation de modèles personnalisés.
Evolution des versions
7 mai 2018 | ML.NET 0.1 : Initial release |
6 juin 2018 | ML.NET 0.2 : Arrivée du clustering |
9 juillet 2018 | ML.NET 0.3 : Introduction de LightGBM. |
7 aout 2018 | ML.NET 0.4 : Utilisation de SymSGD et Word Embedding Transform. |
Les problèmes gérés par ML.NET
ML.NET permet de résoudre des problèmes de classification binaire, multiclasse et des régressions. Dans la suite de cet article, nous allons nous intéresser à la régression.
Cas pratique : prédiction de la quantité de sucre dans des produits alimentaires
Le jeu de données
Open Food Facts répertorie les informations sur les produits alimentaires : ingrédients, informations nutritionnelles, labels etc.
Les données proviennent majoritairement de la collecte citoyenne (crowdsourcing) des informations.
Le jeu de données fait 576 984 lignes pour 243 colonnes, soit un total de 140 207 112 de cellules.
La variable de sortie
La valeur à prédire est le taux de sucre d’un produit, parfois manquante dans notre jeu de données : Sugars_100g. C’est une variable continue de type float comprise entre 0 et 100. Le problème de prédiction est donc une régression.
Extraction des données
Le jeu de données complet fait 1,66 GB.
Comme dans la plupart des problèmes de modélisation, on divise ces données en 2 fichiers :
– productSugar-train.csv : contient les données de test pour évaluer et optimiser le modèle (6051 lignes)
– productSugar-test.csv : contient les données d’entrainement (6050 lignes)
Pour des raisons de performance lors du chargement et de l’entrainement du modèle, on ne garde qu’une quantité raisonnable de données (2% des données initiales).
Pour simplifier l’extraction, des scripts adaptés ont été développés en Powershell :
– count.ps1 : Compter le nombre de lignes d’un fichier.
– extract.ps1 : Extraire les lignes comprises entre n1 et n2 dans un nouveau fichier. Utilise l’encodage UTF8.
ML.Net utilise un mécanisme de pipeline au long duquel on créé et entraine le modèle.
Les données sont d’abord chargées et utilisées dans la méthode Train().
La classe CategoricalOneHotVectorizer permet de convertir la variable brands au format numérique pour la rendre compatible avec l’algorithme d’apprentissage.
Il reste à lister toutes les colonnes utilisées lors de l’apprentissage avec la classe ColumnConcatenator. Pour les écrire à la main, la méthode GetInputColumnsByReflexion() a été développée. La sélection des colonnes est expliquée dans la suite de l’article.
Sélection des variables du modèle
Chaque ligne contient 243 variables.
Quelles variables utiliser pour prédire la quantité de sucre d’un produit ?
Pour répondre à cette question, un premier test a été fait avec la totalité des 243 variables. Immédiatement, on constate que les lignes contenant des valeurs manquantes sont supprimées par ML.net. Il ne reste aucune ligne, ce qui rend cette méthode inutilisable. Il existe plusieurs façons de gérer ce problème, comme remplacer les valeurs manquantes par la moyenne.
Le 2ème test effectué vise à supprimer certaines colonnes pour garder le maximum de lignes.
Pour trouver les colonnes à garder, une analyse via Excel nous permet de déterminer les colonnes les moins ‘vides’.
On choisit arbitrairement les 13 variables continues ayant le moins de valeurs manquantes possible, ainsi que la variable qualitative brands qui définit la marque du produit.
Génération de la classe produit (243 variables)
Le modèle que nous allons choisir est de type Microsoft.ML.PredictionModel.
Ce modèle est une classe générique qui prend en paramètre une classe définissant une propriété pour chaque colonne à utiliser.
Pour éviter d’écrire à la main les 243 propriétés de la classe Product, on utilise un fichier de génération de code t4 Text Template.
L’astuce consiste à déclarer l’entité Product comme classe partielle. Le fichier t4 génère une autre classe partielle du même nom, contenant les 243 variables en commentaire.
Ainsi, pour chaque colonne de notre fichier de données productSugar-train.csv, un attribut sera créé. Il ne reste plus qu’à dé-commenter les colonnes sélectionnées dans la section précédente.
Les plugins VSCode compatibles avec t4
Il existe 2 plugins VSCode qui gèrent les fichiers t4.
– TT-Processor : pour exécuter la génération de code à la sauvegarde d’un fichier t4.
– T4 syntax : pour avoir une coloration syntaxique des templates t4.
Avec Visual Studio, il n’y a même pas besoin de plugin pour les t4.
Sélection du modèle d’entraînement
ML.Net implémente plusieurs modèles d’entrainement compatibles avec des problèmes de régression.
La qualité de chaque modèle est évaluée par plusieurs métriques :
– Rms : l’erreur quadratique moyenne, aussi connue sous le nom de « risque quadratique ». Plus cette valeur est faible, plus le modèle est précis.
– RSquared : le coefficient de détermination. Compris entre 0 et 1, il indique que le modèle est aléatoire si la valeur est proche de 0 ou précis si la valeur est proche de 1.
Pour trouver le modèle de régression le plus précis dans notre cas, plusieurs tests ont été effectués.
FastTreeRegressor est une régression qui utilise le gradient boosting ainsi que des arbres de décisions.
Tester son modèle : prédiction d’une valeur
Une fois que le modèle a été entrainé, il est possible de le tester pour un cas précis.
Pour cela, on utilise la classe productSugars_100gPrediction qui contient la variable de sortie Sugars_100g.
Ensuite, on créer la classe TestProduct dans laquelle on entre toutes les variables d’entrée. La variable de sortie initialisée à 0, et sera évaluée par le modèle.
La méthode ML.Net utilisée, Predict(), prend en entrée un produit défini par les 13 variables sélectionnées précédemment, et sort une valeur pour Sugars_100g.
ProductSugars_100gPrediction prediction = model.Predict(TestProduct.Product1);
Console.WriteLine("Predicted Sugars_100g: {0}, actual Sugars_100g: 8.75", prediction.Sugars_100g);
Ce qui donne le résultat suivant :
Export des modèles ML.NET au format ONNX
Open Neural Network Exchange (ONNX) est un format de modèle de deep learning qui permet l’interopérabilité entre différentes framework.
Avec la release 0.3 de ML.NET, il est possible d’exporter certains modèles ML.NET au format ONXX-ML.
Les transformations suivantes sont supportées depuis ML.NET 0.3 : Concat, KeyToVector, NAReplace, Normalize, Term et Categorical. Les Learners FastTree, LightGBM et Logistic Regression sont également supportés.
Pour visualiser ces modèles ONNX, on utilise l’application Netron, développée avec Electron.
Avec l’arrivée de ML.NET 0.3, on peux désormais utiliser LightGBM, un framework de Gradient Boosting (GBDT, GBRT, GBM or MART) utilisé pour les algorithmes de décision basés sur des arbres, du Ranking ou encore de la classification. LightGBM a déjà fait ses preuves pour de nombreux défis sur kaggle.com.
Depuis la version 0.4, d’autres ajouts ont été faits, comme SymSGD (Parallel Stochastic Gradient Descent with Sound Combiners) et le Word Embedding Transform pour le natural language processing (NLP).
Les sources du projets liées à cet article sont disponibles sur GitHub. Il est aussi possible de faire de l’analyse de sentiments ou encore de la classification, en suivant les exemples officiels disponibles.