Tutorial: Standpunktanalyse für Websitekommentare mit binärer Klassifikation in ML.NET

Dieses Tutorial zeigt Ihnen, wie Sie eine .NET Core-Konsolenanwendung erstellen, die den Standpunkt in Websitekommentaren klassifiziert und die entsprechenden Maßnahmen ergreift. Die binäre Standpunktklassifizierung verwendet C# in Visual Studio 2022.

In diesem Tutorial lernen Sie, wie die folgenden Aufgaben ausgeführt werden:

  • Erstellen einer Konsolenanwendung
  • Vorbereiten von Daten
  • Laden der Daten
  • Erstellen und Trainieren des Modells
  • Evaluieren des Modells
  • Verwenden des Modells für Vorhersagen
  • Anzeigen der Ergebnisse

Sie finden den Quellcode für dieses Tutorial im Repository dotnet/samples.

Voraussetzungen

Erstellen einer Konsolenanwendung

  1. Erstellen Sie eine C# -Konsolenanwendung mit dem Namen „SentimentAnalysis“. Klicken Sie auf die Schaltfläche Weiter.

  2. Wählen Sie .NET 6 als zu verwendendes Framework aus. Klicken Sie auf die Schaltfläche Erstellen .

  3. Erstellen Sie ein Verzeichnis mit dem Namen Data in Ihrem Projekt, um die Datasetdateien zu speichern.

  4. Installieren des Microsoft.ML NuGet-Pakets:

    Hinweis

    In diesem Beispiel wird, sofern nicht anders angegeben, die neueste stabile Version der genannten NuGet-Pakete verwendet.

    Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie NuGet-Pakete verwalten aus. Wählen Sie „nuget.org“ als Paketquelle aus und anschließend die Registerkarte Durchsuchen. Suchen Sie nach Microsoft.ML, wählen Sie das gewünschte Paket aus, und wählen Sie dann die Schaltfläche Installieren aus. Fahren Sie mit der Installation fort, indem Sie den Lizenzbedingungen für das von Ihnen gewählte Paket zustimmen.

Vorbereiten Ihrer Daten

Hinweis

Die für dieses Tutorial verwendeten Datasets stammen aus „From Group to Individual Labels using Deep Features“, Kotzias et. al. KDD 2015, und werden im UCI Machine Learning Repository – Dua, D. und Karra Taniskidou, E. gehostet. (2017). UCI Machine Learning Repository [http://archive.ics.uci.edu/ml ]. Irvine, CA: University of California, School of Information and Computer Science.

  1. Laden Sie die ZIP-Datei des Datasets „UCI Sentiment Labeled Sentences“ herunter, und entzippen Sie sie.

  2. Kopieren Sie die yelp_labelled.txt-Datei in das Verzeichnis Data, das Sie erstellt haben.

  3. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die Datei yelp_labeled.txt, und wählen Sie Eigenschaften aus. Ändern Sie unter Erweitert den Wert von In Ausgabeverzeichnis kopieren in Kopieren, wenn neuer.

Erstellen von Klassen und Definieren von Pfaden

  1. Fügen Sie am Anfang der Datei Program.cs folgende zusätzliche using-Anweisungen hinzu:

    using Microsoft.ML;
    using Microsoft.ML.Data;
    using SentimentAnalysis;
    using static Microsoft.ML.DataOperationsCatalog;
    
  2. Fügen Sie den folgenden Code in der Zeile direkt unter den using-Anweisungen hinzu, um ein Feld zu erstellen, das den Dateipfad des zuletzt heruntergeladenen Datasets enthält:

    string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "yelp_labelled.txt");
    
  3. Erstellen Sie anschließend Klassen für Ihre Eingabedaten und Vorhersagen. Fügen Sie dem Projekt eine neue Klasse hinzu:

    • Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie dann Hinzufügen>Neues Element aus.

    • Wählen Sie im Dialogfeld Neues Element hinzufügen die Option Klasse aus, und ändern Sie das Feld Name in SentimentData.cs. Wählen Sie dann die Schaltfläche Hinzufügen aus.

  4. Die Datei SentimentData.cs wird im Code-Editor geöffnet. Fügen Sie am Anfang der Datei SentimentData.cs die folgende using-Anweisung hinzu:

    using Microsoft.ML.Data;
    
  5. Entfernen Sie die vorhandene Klassendefinition, und fügen Sie den folgenden Code mit den beiden Klassen SentimentData und SentimentPrediction der Datei SentimentData.cs hinzu:

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

Vorbereitung der Daten

Die SentimentData-Klasse des Eingabedatasets hat eine string für Benutzerkommentare (SentimentText) und einen bool (Sentiment) Wert von entweder 1 (positiv) oder 0 (negativ) für den Standpunkt. Beide Felder haben LoadColumn-Attribute, die an sie angefügt sind, wodurch die Reihenfolge der Datendateien für jedes Feld beschrieben wird. Darüber hinaus hat die Sentiment-Eigenschaft ein ColumnName-Attribut, um es als Label-Feld festzulegen. Die folgende Beispieldatei verfügt nicht über eine Kopfzeile und sieht wie folgt aus:

SentimentText Standpunkt (Bezeichnung)
Die Kellnerin hat etwas langsam bedient. 0
Die Kruste ist nicht gut. 0
Toll... Mir hat das Restaurant gefallen. 1
Wir wurden schnell bedient. 1

SentimentPrediction ist die nach dem Modelltraining verwendete Vorhersageklasse. Diese erbt von SentimentData, sodass die Eingabe SentimentText zusammen mit der Ausgabevorhersage angezeigt werden kann. Der boolesche Wert Prediction ist der Wert, den das Modell vorhersagt, wenn für dieses eine neue Eingabe für SentimentText bereitgestellt wird.

Die Ausgabeklasse SentimentPrediction enthält zwei weitere Eigenschaften, die von dem Modell berechnet werden: Score, die Rohbewertung, die vom Modell berechnet wird, und Probability, der für die Wahrscheinlichkeit, dass der Text eine positive Stimmung vermittelt, kalibrierte Wert.

Für dieses Tutorial ist Prediction die wichtigste Eigenschaft.

Laden der Daten

Daten im ML.NET werden angezeigt als ein IDataView interface. Mit IDataView können Tabellendaten (Zahlen und Text) flexibel und effizient beschrieben werden. Daten können aus einer Textdatei oder in Echtzeit (z. B. aus einer SQL-Datenbank oder aus Protokolldateien) in ein IDataView-Objekt geladen werden.

Die MLContext-Klasse ist der Ausgangspunkt für alle ML.NET-Vorgänge. Beim Initialisieren von mlContext wird eine neue ML.NET-Umgebung erstellt, die für alle Objekte des Workflows für die Modellerstellung gemeinsam genutzt werden kann. Die Klasse ähnelt dem Konzept von DBContext in Entity Framework.

Sie bereiten die App vor und laden anschließend die Daten:

  1. Ersetzen Sie die Zeile Console.WriteLine("Hello World!") durch den folgenden Code, um die mlContext-Variable zu deklarieren und zu initialisieren:

    MLContext mlContext = new MLContext();
    
  2. Fügen Sie den folgenden Text als nächste Codezeile ein:

    TrainTestData splitDataView = LoadData(mlContext);
    
  3. Erstellen Sie mithilfe folgenden Codes unten in der Datei Program.cs eine LoadData()-Methode:

    TrainTestData LoadData(MLContext mlContext)
    {
    
    }
    

    Die LoadData()-Methode führt die folgenden Aufgaben aus:

    • Laden der Daten.
    • Teilt das geladene Dataset in Trainings- und Testdatasets auf.
    • Gibt die aufgeteilten Trainings- und Testdatasets zurück.
  4. Fügen Sie den folgenden Code am Ende der ersten Zeile der LoadData()-Methode hinzu.

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

    Die LoadFromTextFile()-Methode definiert das Datenschema und liest in der Datei. Diese Methode akzeptiert Datenpfadvariablen und gibt ein IDataView-Objekt zurück.

Aufteilen des Datasets für Modelltraining und -test

Wenn Sie ein Modell vorbereiten, verwenden Sie einen Teil des Datasets, um es zu trainieren, und einen anderen Teil, um die Genauigkeit des Modells zu testen.

  1. Um die geladenen Daten in die erforderlichen Datasets aufzuteilen, fügen Sie den folgenden Code als nächste Zeile in die LoadData()-Methode ein:

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

    Der vorherige Code verwendet die TrainTestSplit()-Methode, um das geladene Dataset in Trainings- und Testdatasets aufzuteilen und diese in der DataOperationsCatalog.TrainTestData-Klasse zurückzugeben. Geben Sie den Prozentsatz der Daten des Testsatzes mit dem testFraction-Parameter an. Der Standard ist 10 %. In diesem Fall verwenden Sie 20 %, um mehr Daten auszuwerten.

  2. Geben Sie splitDataView am Ende der LoadData()-Methode zurück:

    return splitDataView;
    

Erstellen und Trainieren des Modells

  1. Fügen Sie der BuildAndTrainModel-Methode in der LoadData-Methode unter dem Aufruf den folgenden Aufruf hinzu:

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

    Die BuildAndTrainModel()-Methode führt die folgenden Aufgaben aus:

    • Extrahieren und Transformieren der Daten.
    • Trainieren des Modells.
    • Vorhersagen des Standpunkts anhand der Testdaten.
    • Zurückgeben des Modells.
  2. Erstellen Sie mit dem folgenden Code die BuildAndTrainModel()-Methode unterhalb der LoadData()-Methode:

    ITransformer BuildAndTrainModel(MLContext mlContext, IDataView splitTrainSet)
    {
    
    }
    

Extrahieren und Transformieren der Daten

  1. Rufen Sie FeaturizeText als die nächste Codezeile auf:

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

    Die FeaturizeText()-Methode im vorherigen Code konvertiert die Textspalte (SentimentText) in eine Spalte vom Typ Features mit numerischem Schlüssel, die vom Machine Learning-Algorithmus verwendet wird, und fügt sie als neue Datasetspalte hinzu:

    SentimentText Standpunkt Features
    Die Kellnerin hat etwas langsam bedient. 0 [0,76, 0,65, 0,44, …]
    Die Kruste ist nicht gut. 0 [0,98, 0,43, 0,54, …]
    Toll... Mir hat das Restaurant gefallen. 1 [0,35, 0,73, 0,46, …]
    Wir wurden schnell bedient. 1 [0,39, 0, 0,75, …]

Hinzufügen eines Lernalgorithmus

Diese App verwendet einen Klassifizierungsalgorithmus, der Elemente oder Datenzeilen kategorisiert. Die App kategorisiert Websitekommentare entweder als positiv oder negativ. Also verwenden Sie die binäre Klassifizierungsaufgabe.

Fügen Sie den unten aufgeführten Code als nächste Codezeilen in BuildAndTrainModel() ein, um die Machine Learning-Aufgabe festzulegen und ihn an die Datentransformationsdefinitionen anzufügen:

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

SdcaLogisticRegressionBinaryTrainer ist Ihr Klassifizierungsalgorithmus für das Training. Dieser wird an den estimator angefügt, und akzeptiert den mit Features ausgestatteten SentimentText (Features) und die Label-Eingabeparameter, um aus den historischen Daten zu lernen.

Trainieren des Modells

Fügen Sie den unten aufgeführten Code als nächste Codezeilen in die BuildAndTrainModel()-Methode ein, um das Modell an die splitTrainSet-Daten anzupassen und das trainierte Modell zurückzugeben:

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

Mit der Fit()-Methode wird Ihr Modell trainiert, indem das Dataset transformiert und das Training angewendet wird.

Zurückgeben des für die Evaluierung trainierten Modells

Geben Sie das Modell am Ende der BuildAndTrainModel()-Methode zurück:

return model;

Evaluieren des Modells

Verwenden Sie nach dem Training Ihres Modells Ihre Testdaten, um die Leistung Ihres Modells zu validieren.

  1. Erstellen Sie mit dem folgenden Code die Evaluate()-Methode direkt nach BuildAndTrainModel():

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

    Die Evaluate()-Methode führt die folgenden Aufgaben aus:

    • Laden des Testdatasets.
    • Erstellen des Auswerters der binären Klassifizierung.
    • Evaluieren des Modells und Erstellen von Metriken.
    • Anzeigen der Metriken.
  2. Fügen Sie der neuen Methode mit dem folgenden Code einen Aufruf unterhalb der BuildAndTrainModel-Methode hinzu:

    Evaluate(mlContext, model, splitDataView.TestSet);
    
  3. Fügen Sie Evaluate() den folgenden Code hinzu, um die splitTestSet-Daten zu transformieren:

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

    Der vorherige Code verwendet die Transform()-Methode trifft Vorhersagen für mehrere bereitgestellte Eingabezeilen eines Testdatasets.

  4. Fügen Sie den unten aufgeführten Code als nächste Codezeile in die Evaluate()-Methode ein, um das Modell auszuwerten:

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

Nach der Vorhersagekonfiguration (predictions) wertet die Evaluate()-Methode das Modell aus. Dabei werden die Vorhersagewerte mit den tatsächlichen Labels im Testdataset verglichen und die CalibratedBinaryClassificationMetrics für das Modell zurückgegeben.

Anzeigen der Metriken zur Modellvalidierung

Zeigen Sie die Metriken mithilfe des folgenden Codes an:

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 ===============");
  • Die Accuracy-Metrik ermittelt die Genauigkeit eines Modells, d.h. den Anteil der korrekten Vorhersagen im Testsatz.

  • Die AreaUnderRocCurve-Metrik gibt an, wie sicher das Modell die positiven und negativen Klassen korrekt klassifiziert. Sie möchten, dass der AreaUnderRocCurve so nah wie möglich bei 1 liegt.

  • Die F1Score-Metrik ermittelt den F1-Score des Modells, der ein Maß für das Gleichgewicht zwischen Genauigkeit und Wiederkennung ist. Sie möchten, dass der F1Score so nah wie möglich bei 1 liegt.

Vorhersagen der Testdatenergebnisse

  1. Erstellen Sie die UseModelWithSingleItem()-Methode mit dem folgenden Code direkt nach der Evaluate()-Methode:

    void UseModelWithSingleItem(MLContext mlContext, ITransformer model)
    {
    
    }
    

    Die UseModelWithSingleItem()-Methode führt die folgenden Aufgaben aus:

    • Erstellen eines einzelnen Kommentars aus Testdaten.
    • Vorhersagen des Standpunkts anhand der Testdaten.
    • Kombinieren von Testdaten und Vorhersagen für die Berichterstattung.
    • Anzeigen der vorhergesagten Ergebnisse.
  2. Fügen Sie der neuen Methode mit dem folgenden Code einen Aufruf direkt unter der Evaluate()-Methode hinzu:

    UseModelWithSingleItem(mlContext, model);
    
  3. Fügen Sie den folgenden Code hinzu, um die erste Zeile in der UseModelWithSingleItem()-Methode zu erstellen:

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

    Die PredictionEngine ist eine Hilfs-API, mit der Sie eine Vorhersage für eine einzelne Instanz der Daten treffen können. PredictionEngine ist nicht threadsicher. Die Verwendung in Singlethread-oder Prototypumgebungen ist zulässig. Zur Verbesserung der Leistung und Threadsicherheit in Produktionsumgebungen verwenden Sie den PredictionEnginePool-Dienst, der einen ObjectPool aus PredictionEngine-Objekten für die Verwendung in Ihrer gesamten Anwendung erstellt. Informationen zur Verwendung von PredictionEnginePool in einer ASP.NET Core-Web-API finden Sie in dieser Anleitung.

    Hinweis

    Die PredictionEnginePool-Diensterweiterung ist derzeit als Vorschauversion verfügbar.

  4. Fügen Sie einen Kommentar hinzu, um die Vorhersage des trainierten Modells in der UseModelWithSingleItem()-Methode zu testen, indem Sie eine SentimentData-Instanz erstellen:

    SentimentData sampleStatement = new SentimentData
    {
        SentimentText = "This was a very bad steak"
    };
    
  5. Übergeben Sie die Testkommentardaten an die PredictionEngine, indem Sie Folgendes als nächste Codezeile in der UseModelWithSingleItem()-Methode hinzufügen:

    var resultPrediction = predictionFunction.Predict(sampleStatement);
    

    Die Predict()-Funktion trifft eine Vorhersage für eine einzelne Datenzeile.

  6. Mithilfe des folgenden Codes können Sie den SentimentText und den dazugehörige Standpunkt anzeigen:

    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();
    

Verwenden des Modells für eine Vorhersage

Bereitstellen und Vorhersagen von Batchelementen

  1. Erstellen Sie die UseModelWithBatchItems()-Methode mit dem folgenden Code direkt nach der UseModelWithSingleItem()-Methode:

    void UseModelWithBatchItems(MLContext mlContext, ITransformer model)
    {
    
    }
    

    Die UseModelWithBatchItems()-Methode führt die folgenden Aufgaben aus:

    • Erstellen von Batchtestdaten.
    • Vorhersagen des Standpunkts anhand der Testdaten.
    • Kombinieren von Testdaten und Vorhersagen für die Berichterstattung.
    • Anzeigen der vorhergesagten Ergebnisse.
  2. Fügen Sie der neuen Methode mit dem folgenden Code einen Aufruf direkt unter der UseModelWithSingleItem()-Methode hinzu:

    UseModelWithBatchItems(mlContext, model);
    
  3. Fügen Sie einige Kommentare zum Testen der Vorhersagen des trainierten Modells in der UseModelWithBatchItems()-Methode hinzu:

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

Vorhersagen des Standpunkts in einem Kommentar

Verwenden Sie das Modell, um den Standpunkt der Kommentardaten mit der Transform()-Methode vorherzusagen:

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

Kombinieren und Anzeigen von Vorhersagen

Erstellen Sie mit dem folgenden Code einen Header für die Vorhersagen:

Console.WriteLine();

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

Da SentimentPrediction von SentimentData geerbt wird, füllt die Transform()-Methode den SentimentText mit den vorhergesagten Feldern aus. Im Laufe des ML.NET-Prozesses fügt jede Komponente Spalten hinzu, sodass die Ergebnisse leicht angezeigt werden können:

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 ===============");

Ergebnisse

Die Ergebnisse sollten den unten dargestellten ähneln. Während der Verarbeitung werden Meldungen angezeigt. Sie können Warnungen oder Verarbeitungsmeldungen sehen. Diese wurden der Übersichtlichkeit halber aus den folgenden Ergebnissen entfernt.

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

Herzlichen Glückwunsch! Sie haben jetzt erfolgreich ein Machine Learning-Modell zum Klassifizieren und Vorhersagen von Standpunkten in Mitteilungen erstellt.

Erfolgreiche Modelle zu erstellen ist ein iterativer Prozess. Dieses Modell hat erst geringere Qualität, da das Tutorial kleine Datasets verwendet, um schnelles Modelltraining zu ermöglichen. Wenn Sie nicht mit der Modellqualität zufrieden sind, können Sie versuchen, sie durch die Bereitstellung größerer Trainingsdatasets oder die Auswahl anderer Trainingsalgorithmen mit anderen Hyperparametern für jeden Algorithmus zu verbessern.

Sie finden den Quellcode für dieses Tutorial im Repository dotnet/samples.

Nächste Schritte

In diesem Tutorial haben Sie gelernt, wie die folgenden Aufgaben ausgeführt werden:

  • Erstellen einer Konsolenanwendung
  • Vorbereiten von Daten
  • Laden der Daten
  • Erstellen und Trainieren des Modells
  • Evaluieren des Modells
  • Verwenden des Modells für Vorhersagen
  • Anzeigen der Ergebnisse

Wechseln Sie zum nächsten Tutorial, um mehr zu erfahren.