Esercitazione: Classificare i problemi di supporto usando la classificazione multiclasse con ML.NET

Questa esercitazione di esempio illustra come usare ML.NET per creare un classificatore di problemi di GitHub per eseguire il training di un modello che classifica e stima l'etichetta Area per un problema di GitHub tramite un'applicazione console .NET Core con C# in Visual Studio.

In questa esercitazione verranno illustrate le procedure per:

  • Preparare i dati
  • Trasformare i dati
  • Eseguire il training del modello
  • Valutare il modello
  • Eseguire stime con il modello sottoposto a training
  • Eseguire distribuzione e stime con un modello caricato

È possibile trovare il codice sorgente per questa esercitazione nel repository dotnet/samples.

Prerequisiti

Creare un'applicazione console

Creare un progetto

  1. Creare un'applicazione console C# denominata "GitHubIssueClassification". Selezionare Avanti.

  2. Scegliere .NET 7 come framework da usare. Selezionare Crea.

  3. Creare una directory denominata Data nel progetto per salvare i file del set di dati:

    In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto e selezionare Aggiungi>Nuova cartella. Digitare "Dati" e premere INVIO.

  4. Creare una directory denominata Models nel progetto per salvare il modello:

    In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto e selezionare Aggiungi>Nuova cartella. Digitare "Modelli" e premere INVIO.

  5. Installare il pacchetto NuGet Microsoft.ML:

    Nota

    Questo esempio usa la versione stabile più recente dei pacchetti NuGet menzionati a meno che non sia specificato in altro modo.

    In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto e selezionare Gestisci pacchetti NuGet. Scegliere "nuget.org" come origine pacchetto, selezionare la scheda Sfoglia, cercare Microsoft.ML e selezionare il pulsante Installa . Selezionare il pulsante OK nella finestra di dialogo Anteprima modifiche e quindi selezionare il pulsante Accetto nella finestra di dialogo Accettazione della licenza se si accettano le condizioni di licenza per i pacchetti elencati.

Preparare i dati

  1. Scaricare i set di dati issues_train.tsv e i set di dati issues_test.tsv e salvarli nella cartella Dati creata in precedenza. Il primo set di dati esegue il training del modello di apprendimento automatico e il secondo può essere usato per valutare il livello di accuratezza del modello.

  2. In Esplora soluzioni fare clic con il pulsante destro del mouse su ognuno dei file *.tsv e selezionare Proprietà. In Avanzate modificare il valore di Copia in Directory di output in Copia se più recente.

Creare le classi e definire i percorsi

Aggiungere le istruzioni using seguenti all'inizio del file Program.cs:

using Microsoft.ML;
using GitHubIssueClassification;

Creare tre campi globali per i percorsi dei file scaricati di recente e variabili globali per MLContext,DataView e PredictionEngine:

  • _trainDataPath contiene il percorso del set di dati usato per il training del modello.
  • _testDataPath contiene il percorso del set di dati usato per valutare il modello.
  • _modelPath contiene il percorso in cui è salvato il modello sottoposto a training.
  • _mlContext è l'elemento MLContext che specifica il contesto di elaborazione.
  • _trainingDataView è l'elemento IDataView usato per elaborare il set di dati di training.
  • _predEngine è l'elemento PredictionEngine<TSrc,TDst> usato per le stime singole.

Aggiungere il codice seguente alla riga direttamente sotto le istruzioni using per specificare tali percorsi e le altre variabili:

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;

Creare alcune classi per i dati di input e le stime. Aggiungere una nuova classe al progetto:

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto e quindi selezionare Aggiungi>Nuovo elemento.

  2. Nella finestra di dialogo Aggiungi nuovo elemento selezionare Classe e modificare il valore del campo Nome impostando GitHubIssueData.cs. Selezionare quindi il pulsante Aggiungi.

    Il file GitHubIssueData.cs viene aperto nell'editor del codice. Aggiungere l'istruzione using seguente all'inizio del file GitHubIssueData.cs:

using Microsoft.ML.Data;

Rimuovere la definizione di classe esistente e aggiungere il codice seguente, che contiene le due classi GitHubIssue e IssuePrediction, al file GitHubIssueData.cs:

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;
}

label è la colonna sulla quale eseguire le stime. Gli elementi Features identificati sono gli input indicati al modello per stimare l'etichetta.

Usare LoadColumnAttribute per specificare gli indici delle colonne di origine nel set di dati.

GitHubIssue è la classe del set di dati input e ha i seguenti campi String:

  • La prima colonna ID (ID problema di GitHub)
  • La seconda colonna Area (stima per il training)
  • La terza colonna Title (titolo del problema GitHub) è la prima feature usata per la stima di Area
  • la quarta colonna Description è la seconda feature usata per stimare l'oggetto Area

IssuePrediction è la classe usata per la stima dopo il training del modello. Dispone di un string singolo (Area) e di un attributo PredictedLabelColumnName. PredictedLabel viene usato durante la valutazione e la stima. Per la valutazione vengono usati un input con dati di training, i valori stimati e il modello.

Tutte le operazioni di ML.NET iniziano nella classe MLContext . L'inizializzazione di mlContext crea un nuovo ambiente ML.NET che può essere condiviso tra gli oggetti del flusso di lavoro di creazione del modello. Dal punto di vista concettuale è simile a DBContext in Entity Framework.

Inizializzare le variabili

Inizializzare la _mlContext variabile globale con una nuova istanza di MLContext con un valore di inizializzazione casuale (seed: 0) per risultati ripetibili/deterministici in più training. Sostituire la riga con il Console.WriteLine("Hello World!") codice seguente:

_mlContext = new MLContext(seed: 0);

Caricare i dati

ML.NET usa l'interfaccia IDataView come modo flessibile ed efficiente per descrivere i dati numerici o tabulari. IDataView può caricare file testo o in tempo reale (ad esempio, file di database SQL o di log).

Per inizializzare e caricare la _trainingDataView variabile globale per usarla per la pipeline, aggiungere il codice seguente dopo l'inizializzazione mlContext :

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

LoadFromTextFile() definisce lo schema dei dati e legge il contenuto del file. Acquisisce le variabili di percorso dei dati e restituisce un oggetto IDataView.

Aggiungere quanto segue dopo aver chiamato il LoadFromTextFile() metodo:

var pipeline = ProcessData();

Il metodo ProcessData esegue le attività seguenti:

  • Estrae e trasforma i dati.
  • Restituisce la pipeline di elaborazione.

Creare il ProcessData metodo nella parte inferiore del file Program.cs usando il codice seguente:

IEstimator<ITransformer> ProcessData()
{

}

Estrarre funzionalità e trasformare i dati

Dato che si vuole stimare l'etichetta GitHub Area per un GitHubIssue, usare il metodo MapValueToKey() per trasformare la colonna Area in una colonna Label di tipo chiave numerica (un formato accettato dagli algoritmi di classificazione) e aggiungerla come nuova colonna del set di dati:

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

Chiamare mlContext.Transforms.Text.FeaturizeTextquindi , che trasforma le colonne di testo (Title e Description) in un vettore numerico per ogni chiamata TitleFeaturized e DescriptionFeaturized. Aggiungere l'estrazione delle funzionalità per entrambe le colonne alla pipeline con il codice seguente:

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

L'ultimo passaggio della preparazione dei dati combina tutte le colonne di funzionalità nella colonna Features usando il metodo Concatenate(). Per impostazione predefinita, un algoritmo di apprendimento elabora solo le funzionalità della colonna Features. Aggiungere questa trasformazione alla pipeline con il codice seguente:

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

Aggiungere quindi AppendCacheCheckpoint per memorizzare nella cache la vista dati e ottenere prestazioni migliori quando si esegue più volte l'iterazione dei dati usando la cache, come nel codice seguente:

.AppendCacheCheckpoint(_mlContext);

Avviso

Usare AppendCacheCheckpoint per i set di dati di piccole e medie dimensioni per ridurre i tempi di training. NON usarlo (rimuovere. AppendCacheCheckpoint()) durante la gestione di set di dati molto grandi.

Applicare return alla pipeline alla fine del metodo ProcessData.

return pipeline;

Questo passaggio gestisce la pre-elaborazione/estrazione delle funzionalità. Usando i componenti aggiuntivi disponibili in ML.NET, è possibile ottenere risultati migliori con il modello.

Compilare ed eseguire il training del modello

Aggiungere la chiamata seguente al BuildAndTrainModelmetodo come riga successiva dopo la chiamata al ProcessData() metodo :

var trainingPipeline = BuildAndTrainModel(_trainingDataView, pipeline);

Il metodo BuildAndTrainModel esegue le attività seguenti:

  • Crea la classe di algoritmo di training.
  • Esegue il training del modello.
  • Esegue la stima dell'area sulla base dei dati di training.
  • Restituisce il modello.

Creare il BuildAndTrainModel metodo , subito dopo la dichiarazione del ProcessData() metodo , usando il codice seguente:

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

}

Informazioni sull'attività di classificazione

La classificazione è un'attività di apprendimento automatico che usa i dati per determinare la categoria, il tipo o la classe di un elemento o una riga di dati ed è spesso di uno dei tipi seguenti:

  • Binarie: A o B.
  • Multiclasse: più categorie che possono essere stimate tramite un singolo modello.

Per questo tipo di problema, usare un algoritmo di Machine Learning di classificazione multiclasse, poiché la stima della categoria di problemi può essere una tra più categorie (multiclasse) anziché solo due categorie (binarie).

Aggiungere l'algoritmo di apprendimento automatico alle definizioni di trasformazione dei dati aggiungendo il codice seguente come prima riga di codice in BuildAndTrainModel():

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

SdcaMaximumEntropy è l'algoritmo di training di classificazione multiclasse. Viene aggiunto a pipeline e accetta gli elementi Title e Description (Features) con estrazione di funzionalità e i parametri di input Label per l'apprendimento dai dati cronologici.

Eseguire il training del modello

Eseguire il fit del modello ai dati splitTrainSet e restituire il modello sottoposto a training aggiungendo il codice seguente come riga successiva nel metodo BuildAndTrainModel():

_trainedModel = trainingPipeline.Fit(trainingDataView);

Il metodo Fit() esegue il training del modello trasformando il set di dati e applicando il training.

PredictionEngine è un'API di servizio che consente di passare e quindi effettuare una stima su una singola istanza di dati. Aggiungere il codice seguente come riga successiva nel metodo BuildAndTrainModel():

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

Eseguire stime con il modello sottoposto a training

Aggiungere un problema di GitHub per testare la stima del modello sottoposto a training nel metodo Predict creando un'istanza di 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.."
};

Usare la funzione Predict() per eseguire una stima su una singola colonna di dati:

var prediction = _predEngine.Predict(issue);

Usare il modello: risultati della stima

Visualizzare GitHubIssue e la stima dell'etichetta Area corrispondente per condividere i risultati e agire su di essi di conseguenza. Creare una visualizzazione per i risultati usando il codice Console.WriteLine() seguente:

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

Restituire il modello di cui è stato eseguito il training da usare per la valutazione

Restituire il modello alla fine del metodo BuildAndTrainModel.

return trainingPipeline;

Valutare il modello

Ora che è stato creato ed eseguito il training del modello, è necessario valutarlo con un set di dati diverso per il controllo di qualità e la convalida. Nel metodo Evaluate viene passato il modello creato in BuildAndTrainModel per la valutazione. Creare il metodo Evaluate subito dopo BuildAndTrainModel, come nel codice seguente:

void Evaluate(DataViewSchema trainingDataViewSchema)
{

}

Il metodo Evaluate esegue le attività seguenti:

  • Carica il set di dati di test.
  • Crea l'analizzatore multiclasse.
  • Valuta il modello e crea le metriche.
  • Visualizza le metriche.

Aggiungere una chiamata al nuovo metodo, subito sotto la chiamata al BuildAndTrainModel metodo, usando il codice seguente:

Evaluate(_trainingDataView.Schema);

Come in precedenza con il training set, caricare il set di dati di test aggiungendo il codice seguente al metodo Evaluate:

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

Il metodo Evaluate() calcola le metriche di qualità per il modello usando il set di dati specificato. Restituisce un oggetto MulticlassClassificationMetrics che contiene le metriche complessive calcolate dagli analizzatori della classificazione multiclasse. Per visualizzare la metrica per determinare la qualità del modello, è prima necessario ottenerla. Osservare l'uso del metodo Transform() della variabile globale _trainedModel di apprendimento automatico (un oggetto ITransformer) per l'input di funzionalità e la generazione di stime. Aggiungere il codice seguente al metodo Evaluate come riga successiva:

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

Le metriche seguenti vengono valutate per la classificazione multiclasse:

  • MicroAccuracy (Accuratezza micro): ogni coppia campione-classe contribuisce nello stesso modo alla metrica di accuratezza. Si vuole che l'accuratezza micro sia il più vicina possibile.

  • MacroAccuracy (Accuratezza macro): ogni classe contribuisce nello stesso modo alla metrica di accuratezza. Alle classi di minoranza viene assegnato un peso uguale a quello delle classi più grandi. Si vuole che l'accuratezza della macro sia il più vicina possibile.

  • LogLoss (Perdita di log): vedere Perdita di log. Il valore desiderato per LogLoss è il valore più prossimo a 0.

  • Riduzione della perdita di log: intervalli da [-inf, 1,00], dove 1,00 è una stima perfetta e 0 indica stime medie. Si vuole che la riduzione della perdita di log sia il più vicina possibile.

Visualizzare le metriche per la convalida del modello

Usare il codice seguente per visualizzare le metriche, condividere i risultati e quindi intervenire su di essi:

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($"*************************************************************************************************************");

Salvare il modello in un file

Quando si è soddisfatti con il modello ottenuto, salvarlo in un file per poter effettuare stime in un secondo momento o in un'altra applicazione. Aggiungere il codice seguente al metodo Evaluate .

SaveModelAsFile(_mlContext, trainingDataViewSchema, _trainedModel);

Creare il metodo SaveModelAsFile sotto il metodo Evaluate.

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

}

Aggiungere il codice seguente al metodo SaveModelAsFile. Questo codice usa il metodo Save per serializzare e archiviare il modello sottoposto a training come file ZIP.

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

Eseguire distribuzione e stime con un modello

Aggiungere una chiamata al nuovo metodo, subito sotto la chiamata al Evaluate metodo, usando il codice seguente:

PredictIssue();

Creare il metodo PredictIssue, subito dopo il metodo Evaluate e subito prima del metodo SaveModelAsFile, usando il codice seguente:

void PredictIssue()
{

}

Il metodo PredictIssue esegue le attività seguenti:

  • Carica il modello salvato
  • Crea un singolo problema con dati di test.
  • Stima l'area in base ai dati di test.
  • Combina i dati di test e le stime per i report.
  • Visualizza i risultati stimati.

Caricare il modello salvato nell'applicazione aggiungendo il codice seguente al metodo PredictIssue:

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

Aggiungere un problema di GitHub per testare la stima del modello sottoposto a training nel metodo Predict creando un'istanza di GitHubIssue:

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

Come in precedenza, creare un'istanza PredictionEngine con il codice seguente:

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

PredictionEngine è un'API utile che consente di eseguire una stima su una singola istanza di dati. PredictionEngine non è thread-safe. È accettabile usare in ambienti a thread singolo o prototipo. Per migliorare le prestazioni e la thread safety negli ambienti di produzione, usare il PredictionEnginePool servizio , che crea un ObjectPool oggetto di PredictionEngine oggetti da usare in tutta l'applicazione. Vedere questa guida su come usare PredictionEnginePool in un'API Web di ASP.NET Core.

Nota

L'estensione del servizio PredictionEnginePool è attualmente in anteprima.

Usare PredictionEngine per stimare l'etichetta di Area GitHub aggiungendo il codice seguente al metodo PredictIssue per la stima:

var prediction = _predEngine.Predict(singleIssue);

Usare il modello caricato per la stima

Visualizzare Area per classificare il problema e agire su di esso di conseguenza. Creare una visualizzazione per i risultati usando il codice Console.WriteLine() seguente:

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

Risultati

I risultati dovrebbero essere simili a quanto riportato di seguito. Durante l'elaborazione della pipeline, vengono visualizzati messaggi. Possono essere mostrati avvisi o messaggi relativi all'elaborazione. Questi messaggi sono stati rimossi dai risultati seguenti per maggiore chiarezza.

=============== 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 ===============

Congratulazioni! È stato creato correttamente un modello di apprendimento automatico per la classificazione e la stima di un'etichetta Area per un problema di GitHub. È possibile trovare il codice sorgente per questa esercitazione nel repository dotnet/samples.

Passaggi successivi

In questa esercitazione sono state illustrate le procedure per:

  • Preparare i dati
  • Trasformare i dati
  • Eseguire il training del modello
  • Valutare il modello
  • Eseguire stime con il modello sottoposto a training
  • Eseguire distribuzione e stime con un modello caricato

Passare all'esercitazione successiva per altre informazioni