Partager via


Tutoriel : Catégoriser les problèmes de prise en charge à l’aide de la classification multiclasse avec ML.NET

Cet exemple de tutoriel illustre l’utilisation de ML.NET pour créer un classifieur de problème GitHub afin d’entraîner un modèle classifie et prédit l’étiquette Zone d’un problème GitHub via une application console .NET à l’aide de C# dans Visual Studio.

Dans ce tutoriel, vous allez apprendre à :

  • Préparer vos données
  • Transformer les données
  • Entraîner le modèle
  • Évaluer le modèle
  • Prédire avec le modèle entraîné
  • Déployer et prédire avec un modèle chargé

Vous trouverez le code source de ce didacticiel dans le référentiel dotnet/samples .

Prerequisites

Création d’une application console

Création d’un projet

  1. Créez une application console C# appelée « GitHubIssueClassification ». Cliquez sur Suivant.

  2. Choisissez .NET 7 comme framework à utiliser. Cliquez sur Créer.

  3. Créez un répertoire nommé Data dans votre projet pour enregistrer vos fichiers de jeu de données :

    Dans l’Explorateur de solutions, cliquez avec le bouton droit sur votre projet, puis sélectionnez Ajouter>un nouveau dossier. Tapez « Données », puis appuyez sur Entrée.

  4. Créez un répertoire nommé Modèles dans votre projet pour enregistrer votre modèle :

    Dans l’Explorateur de solutions, cliquez avec le bouton droit sur votre projet, puis sélectionnez Ajouter>un nouveau dossier. Tapez « Modèles », puis appuyez sur Entrée.

  5. Installez le package NuGet Microsoft.ML :

    Note

    Cet exemple utilise la dernière version stable des packages NuGet mentionnés, sauf indication contraire.

    Dans l’Explorateur de solutions, cliquez avec le bouton droit sur votre projet, puis sélectionnez Gérer les packages NuGet. Choisissez « nuget.org » comme source du package, sélectionnez l’onglet Parcourir, recherchez Microsoft.ML et sélectionnez Installer. Sélectionnez le bouton OK dans la boîte de dialogue Aperçu des modifications , puis sélectionnez le bouton J’acceptedans la boîte de dialogue Acceptation de licence si vous acceptez les termes du contrat de licence pour les packages répertoriés.

Préparer vos données

  1. Téléchargez les jeux de données issues_train.tsv et les jeux de données issues_test.tsv et enregistrez-les dans le dossier Données que vous avez créé précédemment. Le premier jeu de données entraîne le modèle Machine Learning et le second peut être utilisé pour évaluer la précision de votre modèle.

  2. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur chacun des fichiers *.tsv, puis sélectionnez Propriétés. Sous Avancé, modifiez la valeur de Copie dans le répertoire de sortie pour copier si elle est plus récente.

Créer des classes et définir des chemins d’accès

Ajoutez les directives supplémentaires using suivantes en haut du fichier Program.cs :

using Microsoft.ML;
using GitHubIssueClassification;

Créez trois champs globaux pour contenir les chemins d’accès aux fichiers récemment téléchargés et les variables globales pour les MLContextvariables globales , DataViewet PredictionEngine:

  • _trainDataPath a le chemin d’accès au jeu de données utilisé pour entraîner le modèle.
  • _testDataPath a le chemin d’accès au jeu de données utilisé pour évaluer le modèle.
  • _modelPath a le chemin où est enregistré le modèle entraîné.
  • _mlContext est le MLContext contexte de traitement.
  • _trainingDataView est utilisé IDataView pour traiter le jeu de données d’entraînement.
  • _predEngine est utilisé PredictionEngine<TSrc,TDst> pour les prédictions uniques.

Ajoutez le code suivant à la ligne directement sous les using directives pour spécifier ces chemins et les autres variables :

string _appPath = Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]) ?? ".";
string _trainDataPath = Path.Combine(_appPath, "..", "..", "..", "Data", "issues_train.tsv");
string _testDataPath = Path.Combine(_appPath, "..", "..", "..", "Data", "issues_test.tsv");
string _modelPath = Path.Combine(_appPath, "..", "..", "..", "Models", "model.zip");

MLContext _mlContext;
PredictionEngine<GitHubIssue, IssuePrediction> _predEngine;
ITransformer _trainedModel;
IDataView _trainingDataView;

Créez des classes pour vos données et prédictions d’entrée. Ajoutez une nouvelle classe à votre projet :

  1. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet, puis sélectionnez Ajouter>un nouvel élément.

  2. Dans la boîte de dialogue Ajouter un nouvel élément , sélectionnez Classe et remplacez le champ Nom par GitHubIssueData.cs. Ensuite, sélectionnez Ajouter.

    Le fichier GitHubIssueData.cs s’ouvre dans l’éditeur de code. Ajoutez la directive suivante using en haut de GitHubIssueData.cs :

    using Microsoft.ML.Data;
    
  3. Supprimez la définition de classe existante et ajoutez le code suivant au fichier GitHubIssueData.cs . Ce code a deux classes et GitHubIssueIssuePrediction.

    public class GitHubIssue
    {
        [LoadColumn(0)]
        public string? ID { get; set; }
        [LoadColumn(1)]
        public string? Area { get; set; }
        [LoadColumn(2)]
        public required string Title { get; set; }
        [LoadColumn(3)]
        public required string Description { get; set; }
    }
    
    public class IssuePrediction
    {
        [ColumnName("PredictedLabel")]
        public string? Area;
    }
    

    Il label s’agit de la colonne que vous souhaitez prédire. Les entrées identifiées Features sont les entrées que vous donnez au modèle pour prédire l’étiquette.

    Utilisez LoadColumnAttribute pour spécifier les index des colonnes sources dans le jeu de données.

    GitHubIssue est la classe de jeu de données d’entrée et comporte les champs suivants String :

    • Première colonne ID (ID de problème GitHub).
    • Deuxième colonne Area (prédiction pour l’entraînement).
    • La troisième colonne Title (titre du problème GitHub) est la première feature utilisée pour prédire le Area.
    • La quatrième colonne Description est la deuxième feature utilisée pour prédire le Area.

    IssuePrediction est la classe utilisée pour la prédiction après l’apprentissage du modèle. Il a un seul string (Area) et un PredictedLabelColumnName attribut. Il PredictedLabel est utilisé pendant la prédiction et l’évaluation. Pour l’évaluation, une entrée avec des données d’apprentissage, les valeurs prédites et le modèle sont utilisés.

    Toutes les opérations ML.NET démarrent dans la classe MLContext . L’initialisation mlContext crée un environnement ML.NET qui peut être partagé entre les objets de flux de travail de création de modèle. C’est similaire, conceptuellement, à DBContext in Entity Framework.

Initialiser les variables

Initialisez la _mlContext variable globale avec une nouvelle instance d’une MLContext valeur initiale aléatoire (seed: 0) pour des résultats reproductibles/déterministes sur plusieurs formations. Remplacez la Console.WriteLine("Hello World!") ligne par le code suivant :

_mlContext = new MLContext(seed: 0);

Chargement des données

ML.NET utilise l’interface IDataView comme moyen flexible et efficace de décrire des données tabulaires numériques ou textuelles. IDataView peut charger des fichiers texte ou en temps réel (par exemple, une base de données SQL ou des fichiers journaux).

Pour initialiser et charger la _trainingDataView variable globale afin de l’utiliser pour le pipeline, ajoutez le code suivant après l’initialisation mlContext :

_trainingDataView = _mlContext.Data.LoadFromTextFile<GitHubIssue>(_trainDataPath,hasHeader: true);

LoadFromTextFile() définit le schéma de données et lit dans le fichier. Il prend les variables de chemin d’accès aux données et retourne un IDataView.

Ajoutez ce qui suit après avoir appelé la LoadFromTextFile() méthode :

var pipeline = ProcessData();

La ProcessData méthode exécute les tâches suivantes :

  • Extrait et transforme les données.
  • Retourne le pipeline de traitement.

Créez la ProcessData méthode en bas du fichier Program.cs à l’aide du code suivant :

IEstimator<ITransformer> ProcessData()
{

}

Extraire des fonctionnalités et transformer les données

Comme vous souhaitez prédire l’étiquette GitHub de zone pour un GitHubIssue, utilisez la méthode MapValueToKey() pour transformer la Area colonne en colonne de type Label clé numérique (format accepté par les algorithmes de classification) et ajoutez-la en tant que nouvelle colonne de jeu de données :

var pipeline = _mlContext.Transforms.Conversion.MapValueToKey(inputColumnName: "Area", outputColumnName: "Label")

Ensuite, appelez mlContext.Transforms.Text.FeaturizeText, qui transforme les colonnes de texte (Title et Description) en vecteur numérique pour chaque appelé TitleFeaturized et DescriptionFeaturized. Ajoutez la vectorisation pour les deux colonnes au pipeline avec le code suivant :

.Append(_mlContext.Transforms.Text.FeaturizeText(inputColumnName: "Title", outputColumnName: "TitleFeaturized"))
.Append(_mlContext.Transforms.Text.FeaturizeText(inputColumnName: "Description", outputColumnName: "DescriptionFeaturized"))

La dernière étape de la préparation des données combine toutes les colonnes de caractéristiques dans la colonne Features à l’aide de la méthode Concatenate(). Par défaut, un algorithme d’apprentissage traite uniquement les fonctionnalités de la colonne Fonctionnalités . Ajoutez cette transformation au pipeline avec le code suivant :

.Append(_mlContext.Transforms.Concatenate("Features", "TitleFeaturized", "DescriptionFeaturized"))

Ensuite, ajoutez un AppendCacheCheckpoint pour mettre en cache DataView. Par conséquent, lorsque vous effectuez une itération sur les données plusieurs fois à l’aide du cache, vous pouvez obtenir de meilleures performances, comme avec le code suivant :

.AppendCacheCheckpoint(_mlContext);

Avertissement

Utilisez AppendCacheCheckpoint pour les jeux de données de petite/moyenne taille pour réduire le temps d’entraînement. Ne pas l’utiliser (supprimer . AppendCacheCheckpoint()) lors de la gestion de jeux de données très volumineux.

Retourne le pipeline à la fin de la ProcessData méthode.

return pipeline;

Cette étape gère le prétraitement/caractérisation. L’utilisation de composants supplémentaires disponibles dans ML.NET peut améliorer les résultats avec votre modèle.

Générer et entraîner le modèle

Ajoutez l’appel suivant à la BuildAndTrainModelméthode comme ligne suivante après l’appel à la ProcessData() méthode :

var trainingPipeline = BuildAndTrainModel(_trainingDataView, pipeline);

La BuildAndTrainModel méthode exécute les tâches suivantes :

  • Crée la classe d’algorithme d’entraînement.
  • Effectue l’apprentissage du modèle.
  • Prédit la zone en fonction des données d’apprentissage.
  • Retourne le modèle.

Créez la BuildAndTrainModel méthode, juste après la déclaration de la ProcessData() méthode, à l’aide du code suivant :

IEstimator<ITransformer> BuildAndTrainModel(IDataView trainingDataView, IEstimator<ITransformer> pipeline)
{

}

À propos de la tâche de classification

La classification est une tâche Machine Learning qui utilise des données pour déterminer la catégorie, le type ou la classe d’un élément ou d’une ligne de données et qui est souvent l’un des types suivants :

  • Binaire : A ou B.
  • Multiclasse : plusieurs catégories qui peuvent être prédites à l’aide d’un modèle unique.

Pour ce type de problème, utilisez un algorithme d’apprentissage de classification multiclasse, car votre prédiction de catégorie de problème peut être l’une des plusieurs catégories (multiclasse) au lieu de deux (binaires).

Ajoutez l’algorithme Machine Learning aux définitions de transformation de données en ajoutant ce qui suit comme première ligne de code dans BuildAndTrainModel():

var trainingPipeline = pipeline.Append(_mlContext.MulticlassClassification.Trainers.SdcaMaximumEntropy("Label", "Features"))
        .Append(_mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

SdcaMaximumEntropy est votre algorithme d’apprentissage de classification multiclasse. Cela est ajouté à pipeline et accepte les fonctionnalités Title et Description (Features) ainsi que les paramètres d’entrée Label pour apprendre à partir des données historiques.

Entraîner le modèle

Ajuster le modèle aux splitTrainSet données et renvoyer le modèle entraîné en ajoutant la ligne de code suivante dans la BuildAndTrainModel() méthode :

_trainedModel = trainingPipeline.Fit(trainingDataView);

La Fit()méthode entraîne votre modèle en transformant le jeu de données et en appliquant l’entraînement.

PredictionEngine est une API pratique qui vous permet de passer et d’effectuer une prédiction sur une seule instance de données. Ajoutez-le comme ligne suivante dans la BuildAndTrainModel() méthode :

_predEngine = _mlContext.Model.CreatePredictionEngine<GitHubIssue, IssuePrediction>(_trainedModel);

Prédire avec le modèle entraîné

Ajoutez un problème GitHub pour tester la prédiction du modèle entraîné dans la Predict méthode en créant une instance de GitHubIssue:

GitHubIssue issue = new GitHubIssue() {
    Title = "WebSockets communication is slow in my machine",
    Description = "The WebSockets communication used under the covers by SignalR looks like is going slow in my development machine.."
};

Utilisez la fonction Predict() pour effectuer une prédiction sur une seule ligne de données :

var prediction = _predEngine.Predict(issue);

Utiliser le modèle : Résultats de prédiction

Affichez GitHubIssue et la prédiction d’étiquette correspondante Area pour partager les résultats et agir sur eux en conséquence. Créez un affichage pour les résultats à l’aide du code suivant Console.WriteLine() :

Console.WriteLine($"=============== Single Prediction just-trained-model - Result: {prediction.Area} ===============");

Retourner le modèle entraîné à utiliser pour l’évaluation

Retourne le modèle à la fin de la BuildAndTrainModel méthode.

return trainingPipeline;

Évaluer le modèle

Maintenant que vous avez créé et entraîné le modèle, vous devez l’évaluer avec un autre jeu de données pour l’assurance qualité et la validation. Dans la Evaluate méthode, le modèle créé dans BuildAndTrainModel est passé à évaluer. Créez la Evaluate méthode, juste après BuildAndTrainModel, comme dans le code suivant :

void Evaluate(DataViewSchema trainingDataViewSchema)
{

}

La Evaluate méthode exécute les tâches suivantes :

  • Charge le jeu de données de test.
  • Crée l’évaluateur multiclasse.
  • Évalue le modèle et crée des métriques.
  • Affiche les métriques.

Ajoutez un appel à la nouvelle méthode, juste sous l’appel BuildAndTrainModel de méthode, à l’aide du code suivant :

Evaluate(_trainingDataView.Schema);

Comme vous l’avez fait précédemment avec le jeu de données d’entraînement, chargez le jeu de données de test en ajoutant le code suivant à la Evaluate méthode :

var testDataView = _mlContext.Data.LoadFromTextFile<GitHubIssue>(_testDataPath,hasHeader: true);

La méthode Evaluate() calcule les métriques de qualité pour le modèle à l’aide du jeu de données spécifié. Elle retourne un MulticlassClassificationMetrics objet qui contient les métriques globales calculées par les évaluateurs de classification multiclasses. Pour afficher les métriques pour déterminer la qualité du modèle, vous devez d’abord les obtenir. Notez l’utilisation de la méthode Transform() de la variable globale Machine Learning _trainedModel (un ITransformer) pour entrer les fonctionnalités et retourner des prédictions. Ajoutez le code suivant à la Evaluate méthode comme ligne suivante :

var testMetrics = _mlContext.MulticlassClassification.Evaluate(_trainedModel.Transform(testDataView));

Les métriques suivantes sont évaluées pour la classification multiclasse :

  • Micro Precisiony : chaque paire échantillon-classe contribue de façon égale à la métrique de précision. Vous souhaitez que la précision micro soit aussi proche que possible.
  • Précision des macros : chaque classe contribue également à la métrique de précision. Les classes minoritaires ont un poids égal à celui des classes plus grandes. Vous souhaitez que la précision des macros soit aussi proche que possible.
  • Perte de journal : voir Perte de journal. Vous souhaitez que la perte de journal soit aussi proche de zéro que possible.
  • Réduction de la perte de journal : plages de [-inf, 1.00], où 1.00 est des prédictions parfaites et 0 indique les prédictions moyennes. Vous souhaitez que la réduction de la perte de journal soit aussi proche que possible.

Afficher les métriques pour la validation du modèle

Utilisez le code suivant pour afficher les métriques, partager les résultats, puis agir dessus :

Console.WriteLine($"*************************************************************************************************************");
Console.WriteLine($"*       Metrics for Multi-class Classification model - Test Data     ");
Console.WriteLine($"*------------------------------------------------------------------------------------------------------------");
Console.WriteLine($"*       MicroAccuracy:    {testMetrics.MicroAccuracy:0.###}");
Console.WriteLine($"*       MacroAccuracy:    {testMetrics.MacroAccuracy:0.###}");
Console.WriteLine($"*       LogLoss:          {testMetrics.LogLoss:#.###}");
Console.WriteLine($"*       LogLossReduction: {testMetrics.LogLossReduction:#.###}");
Console.WriteLine($"*************************************************************************************************************");

Enregistrer le modèle dans un fichier

Une fois satisfait de votre modèle, enregistrez-le dans un fichier pour effectuer des prédictions ultérieurement ou dans une autre application. Ajoutez le code suivant à la méthode Evaluate .

SaveModelAsFile(_mlContext, trainingDataViewSchema, _trainedModel);

Créez la SaveModelAsFile méthode sous votre Evaluate méthode.

void SaveModelAsFile(MLContext mlContext,DataViewSchema trainingDataViewSchema, ITransformer model)
{

}

Ajoutez le code suivant à votre méthode SaveModelAsFile. Ce code utilise la Save méthode pour sérialiser et stocker le modèle entraîné en tant que fichier zip.

mlContext.Model.Save(model, trainingDataViewSchema, _modelPath);

Déployer et prédire avec un modèle

Ajoutez un appel à la nouvelle méthode, juste sous l’appel Evaluate de méthode, à l’aide du code suivant :

PredictIssue();

Créez la PredictIssue méthode, juste après la Evaluate méthode (et juste avant la SaveModelAsFile méthode), à l’aide du code suivant :

void PredictIssue()
{

}

La PredictIssue méthode exécute les tâches suivantes :

  • Charge le modèle enregistré.
  • Crée un problème unique de données de test.
  • Prédit la zone en fonction des données de test.
  • Combine les données de test et les prédictions pour la création de rapports.
  • Affiche les résultats prédits.

Chargez le modèle enregistré dans votre application en ajoutant le code suivant à la PredictIssue méthode :

ITransformer loadedModel = _mlContext.Model.Load(_modelPath, out var modelInputSchema);

Ajoutez un problème GitHub pour tester la prédiction du modèle entraîné dans la Predict méthode en créant une instance de GitHubIssue:

GitHubIssue singleIssue = new GitHubIssue() { Title = "Entity Framework crashes", Description = "When connecting to the database, EF is crashing" };

Comme vous l’avez fait précédemment, créez une PredictionEngine instance avec le code suivant :

_predEngine = _mlContext.Model.CreatePredictionEngine<GitHubIssue, IssuePrediction>(loadedModel);

PredictionEngine est une API pratique qui vous permet d’effectuer une prédiction sur une seule instance de données. PredictionEngine n’est pas thread-safe. Il est acceptable d’utiliser dans des environnements monothreads ou prototypes. Pour améliorer les performances et la sécurité des threads dans les environnements de production, utilisez le PredictionEnginePool service, qui crée un ObjectPool objet PredictionEngine à utiliser dans votre application. Consultez ce guide sur l’utilisation PredictionEnginePool dans une API web ASP.NET Core.

Note

PredictionEnginePool l’extension de service est actuellement en préversion.

Utilisez la PredictionEngine méthode pour prédire l’étiquette GitHub de zone en ajoutant le code suivant à la PredictIssue méthode de prédiction :

var prediction = _predEngine.Predict(singleIssue);

Utiliser le modèle chargé pour la prédiction

Affichez Area pour catégoriser le problème et agir sur celui-ci en conséquence. Créez un affichage pour les résultats à l’aide du code suivant Console.WriteLine() :

Console.WriteLine($"=============== Single Prediction - Result: {prediction.Area} ===============");

Results

Vos résultats doivent être similaires à ce qui suit. Au fur et à mesure que le pipeline traite, il affiche les messages. Vous pouvez voir des avertissements ou des messages de traitement. Ces messages ont été supprimés des résultats suivants pour plus de clarté.

=============== Single Prediction just-trained-model - Result: area-System.Net ===============
*************************************************************************************************************
*       Metrics for Multi-class Classification model - Test Data
*------------------------------------------------------------------------------------------------------------
*       MicroAccuracy:    0.738
*       MacroAccuracy:    0.668
*       LogLoss:          .919
*       LogLossReduction: .643
*************************************************************************************************************
=============== Single Prediction - Result: area-System.Data ===============

Félicitations! Vous avez maintenant créé un modèle Machine Learning pour classifier et prédire une étiquette de zone pour un problème GitHub. Vous trouverez le code source de ce didacticiel dans le référentiel dotnet/samples .

Étapes suivantes

Dans ce didacticiel, vous avez appris à :

  • Préparer vos données
  • Transformer les données
  • Entraîner le modèle
  • Évaluer le modèle
  • Prédire avec le modèle entraîné
  • Déployer et prédire avec un modèle chargé

Passez au tutoriel suivant pour en savoir plus.