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
Set di dati Sentiment Labeled Sentences di UCI (file con estensione zip)
Creare un'applicazione console
Creare un'applicazione console C# denominata "SentimentAnalysis". Fare clic sul pulsante Next (Avanti).
Scegliere .NET 6 come framework da usare. Fare clic sul pulsante Crea.
Creare una directory denominata Data nel progetto per salvare i file del set di dati.
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.
Scaricare il file con estensione zip del set di dati Sentiment Labeled Sentences di UCI e decomprimerlo.
Copiare il file
yelp_labelled.txt
nella directory Data creata.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
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;
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");
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.
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;
Rimuovere la definizione di classe esistente e aggiungere il codice seguente, che contiene le due classi
SentimentData
eSentimentPrediction
, 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:
Sostituire la riga con il codice seguente per dichiarare e inizializzare la
Console.WriteLine("Hello World!")
variabile mlContext:MLContext mlContext = new MLContext();
Aggiungere quanto segue come riga di codice successiva:
TrainTestData splitDataView = LoadData(mlContext);
Creare un
LoadData()
metodo nella parte inferiore delProgram.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.
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.
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.Restituire
splitDataView
alla fine del metodoLoadData()
:return splitDataView;
Compilare ed eseguire il training del modello
Aggiungere la chiamata seguente al
BuildAndTrainModel
metodo sotto la chiamata alLoadData
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.
Creare il
BuildAndTrainModel()
metodo , sotto ilLoadData()
metodo , usando il codice seguente:ITransformer BuildAndTrainModel(MLContext mlContext, IDataView splitTrainSet) { }
Estrarre e trasformare i dati
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 colonnaFeatures
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.
Creare il metodo
Evaluate()
subito dopoBuildAndTrainModel()
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.
Aggiungere una chiamata al nuovo metodo sotto la chiamata al
BuildAndTrainModel
metodo usando il codice seguente:Evaluate(mlContext, model, splitDataView.TestSet);
Trasformare i dati
splitTestSet
aggiungendo il codice seguente aEvaluate()
: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.
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
Creare il metodo
UseModelWithSingleItem()
subito dopo il metodoEvaluate()
, 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.
Aggiungere una chiamata al nuovo metodo direttamente sotto la chiamata al
Evaluate()
metodo usando il codice seguente:UseModelWithSingleItem(mlContext, model);
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 ilPredictionEnginePool
servizio , che crea unObjectPool
oggetto diPredictionEngine
oggetti da usare in tutta l'applicazione. Vedere questa guida su come usarePredictionEnginePool
in un'API Web di ASP.NET Core.Nota
L'estensione del servizio
PredictionEnginePool
è attualmente in anteprima.Aggiungere un commento per testare la stima del modello sottoposto a training nel metodo
UseModelWithSingleItem()
creando un'istanza diSentimentData
:SentimentData sampleStatement = new SentimentData { SentimentText = "This was a very bad steak" };
Passare i dati di commento del test a
PredictionEngine
aggiungendo quanto segue quali righe successive del codice nel metodoUseModelWithSingleItem()
:var resultPrediction = predictionFunction.Predict(sampleStatement);
La funzione Predict() esegue una stima su una singola colonna di dati.
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
Creare il metodo
UseModelWithBatchItems()
subito dopo il metodoUseModelWithSingleItem()
, 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.
Aggiungere una chiamata al nuovo metodo direttamente sotto la chiamata al
UseModelWithSingleItem()
metodo usando il codice seguente:UseModelWithBatchItems(mlContext, model);
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