Condividi tramite


Esercitazione: Analizzare il sentiment dei commenti del sito Web con la classificazione binaria in ML.NET

In questa esercitazione viene illustrato come creare un'applicazione console .NET Core che classifica le valutazioni dei commenti di un sito web ed esegue l'azione appropriata. Il classificatore di sentiment binario usa C# in Visual Studio 2022.

In questa esercitazione verranno illustrate le procedure per:

  • Creare un'applicazione console
  • Preparazione dei dati
  • Caricare i dati
  • Compilare ed eseguire il training del modello
  • Valutare il modello
  • Usare il modello per eseguire una stima
  • Visualizzare i risultati

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

Prerequisiti

Creare un'applicazione console

  1. Creare un'applicazione console C# denominata "SentimentAnalysis". Fare clic sul pulsante Next (Avanti).

  2. Scegliere .NET 6 come framework da usare. Fare clic sul pulsante Crea.

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

  4. 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 del pacchetto e quindi selezionare la scheda Sfoglia . Cercare Microsoft.ML, selezionare il pacchetto desiderato e quindi selezionare il pulsante Installa . Procedere con l'installazione accettando le condizioni di licenza per il pacchetto scelto.

Preparare i dati

Nota

I set di dati per questa esercitazione sono da 'From Group to Individual Label using Deep Features', Kotzias et. al,. KDD 2015 e ospitata nel repository UCI Machine Learning - Dua, D. e Karra Taniskidou, E. (2017). UCI Machine Learning Repository [http://archive.ics.uci.edu/ml]. Irvine, CA: University of California, School of Information and Computer Science.

  1. Scaricare il file con estensione zip del set di dati Sentiment Labeled Sentences di UCI e decomprimerlo.

  2. Copiare il file yelp_labelled.txt nella directory Data creata.

  3. In Esplora soluzioni fare clic con il pulsante destro del mouse sul file yelp_labeled.txt e scegliere Proprietà. In Avanzate modificare il valore di Copia in Directory di output in Copia se più recente.

Creare le classi e definire i percorsi

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

    using Microsoft.ML;
    using Microsoft.ML.Data;
    using SentimentAnalysis;
    using static Microsoft.ML.DataOperationsCatalog;
    
  2. Aggiungere il codice seguente alla riga seguente sotto le using istruzioni, per creare un campo per contenere il percorso del file del set di dati scaricato di recente:

    string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "yelp_labelled.txt");
    
  3. Successivamente, creare alcune classi per i dati di input e le stime. Aggiungere una nuova classe al progetto:

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

    • Nella finestra di dialogo Aggiungi nuovo elemento selezionare Classe e impostare il campo Nome su SentimentData.cs. Selezionare quindi il pulsante Aggiungi.

  4. Il file SentimentData.cs verrà aperto nell'editor del codice. Aggiungere l'istruzione using seguente all'inizio del file SentimentData.cs:

    using Microsoft.ML.Data;
    
  5. Rimuovere la definizione di classe esistente e aggiungere il codice seguente, che contiene le due classi SentimentData e SentimentPrediction, al file SentimentData.cs:

    public class SentimentData
    {
        [LoadColumn(0)]
        public string? SentimentText;
    
        [LoadColumn(1), ColumnName("Label")]
        public bool Sentiment;
    }
    
    public class SentimentPrediction : SentimentData
    {
    
        [ColumnName("PredictedLabel")]
        public bool Prediction { get; set; }
    
        public float Probability { get; set; }
    
        public float Score { get; set; }
    }
    

Come sono stati preparati i dati

La classe di set di dati di input, SentimentData, dispone di un string per i commenti utente (SentimentText) e di un valore bool (Sentiment) pari a 1 (positivo) o 0 (negativo) per la valutazione. Entrambi i campi hanno attributi LoadColumn associati, che descrivono l'ordine di file di dati di ogni campo. Inoltre, la proprietà Sentiment include un attributo ColumnName per designarlo come campo Label. Il file di esempio seguente non ha una riga di intestazione e ha l'aspetto seguente:

SentimentText Valutazione (etichetta)
La cameriera era un po' lenta a servire. 0
Crust is not good. 0
Wow... Amato questo posto. 1
Il servizio è stato molto rapido. 1

SentimentPrediction è la classe di stima usata dopo il training del modello. Questa classe eredita da SentimentData in modo che l'input SentimentText sia visualizzabile insieme alla stima di output. Il valore booleano Prediction è il valore di cui il modello esegue la stima quando riceve un nuovo input SentimentText.

La classe di output SentimentPrediction contiene altre due proprietà calcolate dal modello: Score, che è il punteggio non elaborato calcolato dal modello e Probability, che è il punteggio calibrato sulla probabilità che il testo esprima un sentiment positivo.

Per questa esercitazione la proprietà più importante è Prediction.

Caricare i dati

I dati in ML.NET sono rappresentati come interfaccia IDataView. IDataView è un modo flessibile ed efficiente di descrivere i dati tabulari (numerici e di testo). È possibile caricare dati da un file di testo o in tempo reale, ad esempio da un database SQL o file di log, in un oggetto IDataView.

La classe MLContext è un punto di partenza per tutte le operazioni ML.NET. 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.

Preparare l'app, quindi caricare i dati:

  1. Sostituire la riga con il codice seguente per dichiarare e inizializzare la Console.WriteLine("Hello World!") variabile mlContext:

    MLContext mlContext = new MLContext();
    
  2. Aggiungere quanto segue come riga di codice successiva:

    TrainTestData splitDataView = LoadData(mlContext);
    
  3. Creare un LoadData() metodo nella parte inferiore del Program.cs file usando il codice seguente:

    TrainTestData LoadData(MLContext mlContext)
    {
    
    }
    

    Il metodo LoadData() esegue le attività seguenti:

    • Carica i dati.
    • Suddivide il set di dati caricati in set di dati di training e di test.
    • Restituisce i set di dati di training e di test divisi.
  4. Aggiungere il codice seguente come prima riga del metodo LoadData():

    IDataView dataView = mlContext.Data.LoadFromTextFile<SentimentData>(_dataPath, hasHeader: false);
    

    Il metodo LoadFromTextFile() definisce lo schema dei dati e legge nel file. Acquisisce le variabili di percorso dei dati e restituisce un oggetto IDataView.

Dividere il set di dati per il training e il test del modello

Quando si prepara un modello, usare parte del set di dati per il training e parte del set di dati per testare l'accuratezza del modello.

  1. Per dividere i dati caricati nei set di dati necessari, aggiungere il codice seguente come riga successiva nel metodo LoadData():

    TrainTestData splitDataView = mlContext.Data.TrainTestSplit(dataView, testFraction: 0.2);
    

    Il codice precedente usa il metodo TrainTestSplit() per suddividere il set di dati caricato in set di dati di training e test e restituirli nella DataOperationsCatalog.TrainTestData classe. Specificare la percentuale di dati del set di test con il parametro testFraction. Il valore predefinito è 10%, in questo caso usare il 20% per valutare più dati.

  2. Restituire splitDataView alla fine del metodo LoadData():

    return splitDataView;
    

Compilare ed eseguire il training del modello

  1. Aggiungere la chiamata seguente al BuildAndTrainModelmetodo sotto la chiamata al LoadData metodo:

    ITransformer model = BuildAndTrainModel(mlContext, splitDataView.TrainSet);
    

    Il metodo BuildAndTrainModel() esegue le attività seguenti:

    • Estrae e trasforma i dati.
    • Esegue il training del modello.
    • Esegue la stima del sentiment in base ai dati di test.
    • Restituisce il modello.
  2. Creare il BuildAndTrainModel() metodo , sotto il LoadData() metodo , usando il codice seguente:

    ITransformer BuildAndTrainModel(MLContext mlContext, IDataView splitTrainSet)
    {
    
    }
    

Estrarre e trasformare i dati

  1. Chiamare FeaturizeText quale riga di codice successiva:

    var estimator = mlContext.Transforms.Text.FeaturizeText(outputColumnName: "Features", inputColumnName: nameof(SentimentData.SentimentText))
    

    Il metodo FeaturizeText() nel codice precedente consente di convertire la colonna di testo (SentimentText) in una colonna Features di tipo di chiave numerica usata dall'algoritmo di apprendimento automatico e di aggiungerla come nuova colonna del set di dati:

    SentimentText Valutazione Funzionalità
    La cameriera era un po' lenta a servire. 0 [0.76, 0.65, 0.44, …]
    Crust is not good. 0 [0.98, 0.43, 0.54, …]
    Wow... Mi è piaciuto molto questo posto. 1 [0.35, 0.73, 0.46, …]
    Il servizio è stato molto rapido. 1 [0.39, 0, 0.75, …]

Aggiungere un algoritmo di apprendimento

Questa app usa un algoritmo di classificazione che classifica gli elementi o le righe di dati. L'app consente di classificare i commenti di un sito web come positivi o negativi, quindi di usare l'attività di classificazione binaria.

Aggiungere l'attività di Machine Learning alle definizioni di trasformazione dei dati aggiungendo il codice seguente come riga successiva di codice in BuildAndTrainModel():

.Append(mlContext.BinaryClassification.Trainers.SdcaLogisticRegression(labelColumnName: "Label", featureColumnName: "Features"));

SdcaLogisticRegressionBinaryTrainer è l'algoritmo del training di classificazione. Viene aggiunto alla estimator e accetta l'oggetto SentimentText (Features) da cui sono state estratte le caratteristiche e i parametri di input Label per l'apprendimento in base ai 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():

Console.WriteLine("=============== Create and Train the Model ===============");
var model = estimator.Fit(splitTrainSet);
Console.WriteLine("=============== End of training ===============");
Console.WriteLine();

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

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

Restituire il modello alla fine del metodo BuildAndTrainModel():

return model;

Valutare il modello

Dopo aver eseguito il training del modello, usare i dati di test per convalidare le prestazioni del modello.

  1. Creare il metodo Evaluate() subito dopo BuildAndTrainModel() con il codice seguente:

    void Evaluate(MLContext mlContext, ITransformer model, IDataView splitTestSet)
    {
    
    }
    

    Il metodo Evaluate() esegue le attività seguenti:

    • Carica il set di dati di test.
    • Crea l'analizzatore BinaryClassification.
    • Valuta il modello e crea le metriche.
    • Visualizza le metriche.
  2. Aggiungere una chiamata al nuovo metodo sotto la chiamata al BuildAndTrainModel metodo usando il codice seguente:

    Evaluate(mlContext, model, splitDataView.TestSet);
    
  3. Trasformare i dati splitTestSet aggiungendo il codice seguente a Evaluate():

    Console.WriteLine("=============== Evaluating Model accuracy with Test data===============");
    IDataView predictions = model.Transform(splitTestSet);
    

    Il codice precedente usa il metodo Transform() per effettuare previsioni per più righe di input specificate di un set di dati di test.

  4. Valutare il modello aggiungendo il codice seguente come riga successiva nel metodo Evaluate():

    CalibratedBinaryClassificationMetrics metrics = mlContext.BinaryClassification.Evaluate(predictions, "Label");
    

Dopo aver impostato la stima (predictions), il metodo Evaluate() valuta il modello confrontando i valori stimati con gli oggetti Labels effettivi presenti nel set di dati di test e restituisce un oggetto CalibratedBinaryClassificationMetrics relativo alle prestazioni del modello.

Visualizzazione delle metriche per la convalida del modello

Usare il codice seguente per visualizzare le metriche:

Console.WriteLine();
Console.WriteLine("Model quality metrics evaluation");
Console.WriteLine("--------------------------------");
Console.WriteLine($"Accuracy: {metrics.Accuracy:P2}");
Console.WriteLine($"Auc: {metrics.AreaUnderRocCurve:P2}");
Console.WriteLine($"F1Score: {metrics.F1Score:P2}");
Console.WriteLine("=============== End of model evaluation ===============");
  • La metrica Accuracy ottiene l'accuratezza di un modello, che è la percentuale di stime corrette nel set di test.

  • La metrica AreaUnderRocCurve indica con quale affidabilità il modello classifica correttamente le classi positive e negative. AreaUnderRocCurve deve avvicinarsi il più possibile a 1.

  • La metrica F1Score produce il punteggio F1 del modello, che è una misura di equilibrio tra precisione e richiamo. F1Score deve avvicinarsi il più possibile a 1.

Stimare i risultati dei dati di test

  1. Creare il metodo UseModelWithSingleItem() subito dopo il metodo Evaluate(), usando il codice seguente:

    void UseModelWithSingleItem(MLContext mlContext, ITransformer model)
    {
    
    }
    

    Il metodo UseModelWithSingleItem() esegue le attività seguenti:

    • Crea un singolo commento di dati di test.
    • Esegue la stima del sentiment in base ai dati di test.
    • Combina i dati di test e le stime per i report.
    • Visualizza i risultati stimati.
  2. Aggiungere una chiamata al nuovo metodo direttamente sotto la chiamata al Evaluate() metodo usando il codice seguente:

    UseModelWithSingleItem(mlContext, model);
    
  3. Aggiungere il codice seguente per creare come prima riga nel metodo UseModelWithSingleItem():

    PredictionEngine<SentimentData, SentimentPrediction> predictionFunction = mlContext.Model.CreatePredictionEngine<SentimentData, SentimentPrediction>(model);
    

    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.

  4. Aggiungere un commento per testare la stima del modello sottoposto a training nel metodo UseModelWithSingleItem() creando un'istanza di SentimentData:

    SentimentData sampleStatement = new SentimentData
    {
        SentimentText = "This was a very bad steak"
    };
    
  5. Passare i dati di commento del test a PredictionEngine aggiungendo quanto segue quali righe successive del codice nel metodo UseModelWithSingleItem():

    var resultPrediction = predictionFunction.Predict(sampleStatement);
    

    La funzione Predict() esegue una stima su una singola colonna di dati.

  6. Visualizzare SentimentText e la corrispondente stima della valutazione tramite il codice seguente:

    Console.WriteLine();
    Console.WriteLine("=============== Prediction Test of model with a single sample and test dataset ===============");
    
    Console.WriteLine();
    Console.WriteLine($"Sentiment: {resultPrediction.SentimentText} | Prediction: {(Convert.ToBoolean(resultPrediction.Prediction) ? "Positive" : "Negative")} | Probability: {resultPrediction.Probability} ");
    
    Console.WriteLine("=============== End of Predictions ===============");
    Console.WriteLine();
    

Usare il modello per le stime

Distribuire e prevedere gli elementi del batch

  1. Creare il metodo UseModelWithBatchItems() subito dopo il metodo UseModelWithSingleItem(), usando il codice seguente:

    void UseModelWithBatchItems(MLContext mlContext, ITransformer model)
    {
    
    }
    

    Il metodo UseModelWithBatchItems() esegue le attività seguenti:

    • Crea i dati di test in batch.
    • Esegue la stima del sentiment in base ai dati di test.
    • Combina i dati di test e le stime per i report.
    • Visualizza i risultati stimati.
  2. Aggiungere una chiamata al nuovo metodo direttamente sotto la chiamata al UseModelWithSingleItem() metodo usando il codice seguente:

    UseModelWithBatchItems(mlContext, model);
    
  3. Aggiungere alcuni commenti per testare le stime del modello sottoposto a training nel metodo UseModelWithBatchItems():

    IEnumerable<SentimentData> sentiments = new[]
    {
        new SentimentData
        {
            SentimentText = "This was a horrible meal"
        },
        new SentimentData
        {
            SentimentText = "I love this spaghetti."
        }
    };
    

Prevedere la valutazione del commento

Usare il modello per stimare la valutazione dei dati del commento usando il metodo Transform():

IDataView batchComments = mlContext.Data.LoadFromEnumerable(sentiments);

IDataView predictions = model.Transform(batchComments);

// Use model to predict whether comment data is Positive (1) or Negative (0).
IEnumerable<SentimentPrediction> predictedResults = mlContext.Data.CreateEnumerable<SentimentPrediction>(predictions, reuseRowObject: false);

Combinare e visualizzare le stime

Creare un'intestazione per le stime con il codice seguente:

Console.WriteLine();

Console.WriteLine("=============== Prediction Test of loaded model with multiple samples ===============");

Poiché SentimentPrediction viene ereditato da SentimentData, il metodo Transform() ha compilato SentimentText con i campi previsti. Mentre il processo ML.NET elabora, ogni componente aggiunge colonne e ciò rende più facile visualizzare i risultati:

foreach (SentimentPrediction prediction  in predictedResults)
{
    Console.WriteLine($"Sentiment: {prediction.SentimentText} | Prediction: {(Convert.ToBoolean(prediction.Prediction) ? "Positive" : "Negative")} | Probability: {prediction.Probability} ");
}
Console.WriteLine("=============== End of predictions ===============");

Risultati

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

Model quality metrics evaluation
--------------------------------
Accuracy: 83.96%
Auc: 90.51%
F1Score: 84.04%

=============== End of model evaluation ===============

=============== Prediction Test of model with a single sample and test dataset ===============

Sentiment: This was a very bad steak | Prediction: Negative | Probability: 0.1027377
=============== End of Predictions ===============

=============== Prediction Test of loaded model with a multiple samples ===============

Sentiment: This was a horrible meal | Prediction: Negative | Probability: 0.1369192
Sentiment: I love this spaghetti. | Prediction: Positive | Probability: 0.9960636
=============== End of predictions ===============

=============== End of process ===============
Press any key to continue . . .

Congratulazioni! A questo punto, è stato creato correttamente un modello di apprendimento automatico per la classificazione e la stima del sentiment dei messaggi.

La creazione di modelli efficaci è un processo iterativo. Questo modello ha inizialmente una qualità inferiore, perché l'esercitazione usa set di dati di dimensioni contenute per consentire il training rapido del modello. Se non si è soddisfatti della qualità del modello, è possibile provare a migliorarlo fornendo set di dati di training più grandi o scegliendo algoritmi di training diversi con iper parametri diversi per ogni algoritmo.

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

Passaggi successivi

In questa esercitazione sono state illustrate le procedure per:

  • Creare un'applicazione console
  • Preparazione dei dati
  • Caricare i dati
  • Compilare ed eseguire il training del modello
  • Valutare il modello
  • Usare il modello per eseguire una stima
  • Visualizzare i risultati

Passare all'esercitazione successiva per altre informazioni