Samouczek: analizowanie tonacji komentarzy witryny internetowej przy użyciu klasyfikacji binarnej w ML.NET

W tym samouczku pokazano, jak utworzyć aplikację konsolową platformy .NET Core, która klasyfikuje tonację z komentarzy witryny internetowej i podejmuje odpowiednie działania. Klasyfikator tonacji binarnej używa języka C# w programie Visual Studio 2022.

Ten samouczek zawiera informacje na temat wykonywania następujących czynności:

  • Tworzenie aplikacji konsolowej
  • Przygotowywanie danych
  • Ładowanie danych
  • Kompilowanie i trenowanie modelu
  • Ocena modelu
  • Przewidywanie przy użyciu modelu
  • Zobacz wyniki

Kod źródłowy tego samouczka można znaleźć w repozytorium dotnet/samples .

Wymagania wstępne

Tworzenie aplikacji konsolowej

  1. Utwórz aplikację konsolową języka C# o nazwie "SentimentAnalysis". Kliknij przycisk Dalej.

  2. Wybierz platformę .NET 6 jako strukturę do użycia. Kliknij przycisk Utwórz.

  3. Utwórz katalog o nazwie Dane w projekcie, aby zapisać pliki zestawu danych.

  4. Zainstaluj pakiet NuGet Microsoft.ML:

    Uwaga

    W tym przykładzie użyto najnowszej stabilnej wersji pakietów NuGet wymienionych, chyba że określono inaczej.

    W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Zarządzaj pakietami NuGet. Wybierz pozycję "nuget.org" jako źródło pakietu, a następnie wybierz kartę Przeglądaj . Wyszukaj Microsoft.ML, wybierz odpowiedni pakiet, a następnie wybierz przycisk Zainstaluj . Kontynuuj instalację, zgadzając się na postanowienia licencyjne wybranego pakietu.

Przygotowywanie danych

Uwaga

Zestawy danych na potrzeby tego samouczka pochodzą z sekcji "Od grupy do poszczególnych etykiet przy użyciu funkcji głębokich", Kotzias et. Al. KDD 2015 i hostowane w repozytorium UCI Machine Learning — Dua, D. i 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. Pobierz plik ZIP zestawu danych SENTIMENT SentimentEd Sentences z etykietami UCI i rozpakuj plik ZIP.

  2. yelp_labelled.txt Skopiuj plik do utworzonego katalogu danych.

  3. W Eksplorator rozwiązań kliknij prawym przyciskiem yelp_labeled.txt myszy plik i wybierz polecenie Właściwości. W obszarze Zaawansowane zmień wartość opcji Kopiuj do katalogu wyjściowego , aby skopiować, jeśli jest nowsza.

Tworzenie klas i definiowanie ścieżek

  1. Dodaj następujące dodatkowe using instrukcje na początku pliku Program.cs :

    using Microsoft.ML;
    using Microsoft.ML.Data;
    using SentimentAnalysis;
    using static Microsoft.ML.DataOperationsCatalog;
    
  2. Dodaj następujący kod do wiersza bezpośrednio poniżej instrukcji using , aby utworzyć pole do przechowywania ostatnio pobranej ścieżki pliku zestawu danych:

    string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "yelp_labelled.txt");
    
  3. Następnie utwórz klasy dla danych wejściowych i przewidywań. Dodaj nową klasę do projektu:

    • W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt, a następnie wybierz polecenie Dodaj>nowy element.

    • W oknie dialogowym Dodawanie nowego elementu wybierz pozycję Klasa i zmień pole Nazwa na SentimentData.cs. Następnie wybierz przycisk Dodaj .

  4. Plik SentimentData.cs zostanie otwarty w edytorze kodu. Dodaj następującą using instrukcję na początku pliku SentimentData.cs:

    using Microsoft.ML.Data;
    
  5. Usuń istniejącą definicję klasy i dodaj następujący kod, który zawiera dwie klasy SentimentData i SentimentPrediction, do pliku 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; }
    }
    

Jak dane zostały przygotowane

Klasa wejściowego zestawu danych, SentimentData, ma string wartość dla komentarzy użytkownika (SentimentText) i bool (Sentiment) 1 (dodatnie) lub 0 (ujemne) dla tonacji. Oba pola mają dołączone atrybuty LoadColumn , które opisują kolejność plików danych każdego pola. Ponadto właściwość ma atrybut ColumnName, Sentiment aby wyznaczyć go jako Label pole. Poniższy przykładowy plik nie ma wiersza nagłówka i wygląda następująco:

SentimentText Tonacja (etykieta)
Kelnerka była trochę wolna w obsłudze. 0
Crust nie jest dobry. 0
Wow... Kochał to miejsce. 1
Usługa była bardzo szybka. 1

SentimentPrediction to klasa przewidywania używana po trenowaniu modelu. Dziedziczy SentimentData po nim tak, aby dane wejściowe SentimentText mogły być wyświetlane wraz z przewidywaniem danych wyjściowych. Wartość Prediction logiczna jest wartością przewidywaną przez model w przypadku dostarczenia nowych danych wejściowych SentimentText.

Klasa SentimentPrediction danych wyjściowych zawiera dwie inne właściwości obliczane przez model: Score — nieprzetworzone wyniki obliczone przez model i Probability — wynik skalibrowany do prawdopodobieństwa, że tekst ma pozytywną tonację.

W tym samouczku najważniejszą właściwością jest Prediction.

Ładowanie danych

Dane w ML.NET są reprezentowane jako interfejs IDataView. IDataView to elastyczny, wydajny sposób opisywania danych tabelarycznych (liczbowych i tekstowych). Dane można załadować z pliku tekstowego lub w czasie rzeczywistym (na przykład bazy danych SQL lub plików dziennika) do IDataView obiektu.

Klasa MLContext jest punktem wyjścia dla wszystkich operacji ML.NET. Inicjowanie mlContext tworzy nowe środowisko ML.NET, które może być współużytkowane przez obiekty przepływu pracy tworzenia modelu. Jest to podobne, koncepcyjnie, do DBContext w programie Entity Framework.

Przygotuj aplikację, a następnie załaduj dane:

  1. Zastąp Console.WriteLine("Hello World!") wiersz następującym kodem, aby zadeklarować i zainicjować zmienną mlContext:

    MLContext mlContext = new MLContext();
    
  2. Dodaj następujący kod jako następny wiersz kodu:

    TrainTestData splitDataView = LoadData(mlContext);
    
  3. Utwórz metodę LoadData() w dolnej części Program.cs pliku przy użyciu następującego kodu:

    TrainTestData LoadData(MLContext mlContext)
    {
    
    }
    

    Metoda LoadData() wykonuje następujące zadania:

    • Ładuje dane.
    • Dzieli załadowany zestaw danych na zestawy danych trenowania i testowania.
    • Zwraca podzielone zestawy danych trenowania i testowania.
  4. Dodaj następujący kod jako pierwszy wiersz LoadData() metody:

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

    Metoda LoadFromTextFile() definiuje schemat danych i odczytuje go w pliku. Pobiera zmienne ścieżki danych i zwraca wartość IDataView.

Dzielenie zestawu danych na potrzeby trenowania i testowania modelu

Podczas przygotowywania modelu należy użyć części zestawu danych do wytrenowania go i części zestawu danych w celu przetestowania dokładności modelu.

  1. Aby podzielić załadowane dane na potrzebne zestawy danych, dodaj następujący kod jako następny wiersz w metodzie LoadData() :

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

    Poprzedni kod używa metody TrainTestSplit(), aby podzielić załadowany zestaw danych na zestawy danych trenowania i testowania oraz zwracać je w DataOperationsCatalog.TrainTestData klasie. Określ procent danych zestawu testów za pomocą parametru testFraction. Wartość domyślna to 10%, w tym przypadku użyjesz wartości 20%, aby ocenić więcej danych.

  2. Zwróć wartość splitDataView na końcu LoadData() metody :

    return splitDataView;
    

Kompilowanie i trenowanie modelu

  1. Dodaj następujące wywołanie do BuildAndTrainModelmetody poniżej wywołania LoadData metody :

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

    Metoda BuildAndTrainModel() wykonuje następujące zadania:

    • Wyodrębnia i przekształca dane.
    • Trenuje model.
    • Przewiduje tonację na podstawie danych testowych.
    • Zwraca model.
  2. Utwórz metodę BuildAndTrainModel() poniżej LoadData() metody , używając następującego kodu:

    ITransformer BuildAndTrainModel(MLContext mlContext, IDataView splitTrainSet)
    {
    
    }
    

Wyodrębnianie i przekształcanie danych

  1. Wywołaj FeaturizeText metodę jako następny wiersz kodu:

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

    Metoda FeaturizeText() w poprzednim kodzie konwertuje kolumnę tekstową (SentimentText) na kolumnę typu Features klucza liczbowego używaną przez algorytm uczenia maszynowego i dodaje ją jako nową kolumnę zestawu danych:

    SentimentText Opinia Funkcje
    Kelnerka była trochę wolna w obsłudze. 0 [0.76, 0.65, 0.44, ...]
    Crust nie jest dobry. 0 [0.98, 0.43, 0.54, ...]
    Wow... Kochał to miejsce. 1 [0.35, 0.73, 0.46, ...]
    Usługa była bardzo szybka. 1 [0.39, 0, 0.75, ...]

Dodawanie algorytmu uczenia

Ta aplikacja używa algorytmu klasyfikacji, który kategoryzuje elementy lub wiersze danych. Aplikacja kategoryzuje komentarze witryny internetowej jako pozytywne lub negatywne, więc użyj zadania klasyfikacji binarnej.

Dołącz zadanie uczenia maszynowego do definicji przekształcania danych, dodając następujący wiersz kodu w BuildAndTrainModel()pliku :

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

SdcaLogisticRegressionBinaryTrainer to algorytm trenowania klasyfikacji. Jest on dołączany do elementu estimator i akceptuje cechowane SentimentText (Features) oraz Label parametry wejściowe, które mają uczyć się na podstawie danych historycznych.

Trenowanie modelu

Dopasuj model do splitTrainSet danych i zwróć wytrenowany model, dodając następujący wiersz kodu w metodzie BuildAndTrainModel() :

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

Metoda Fit() trenuje model, przekształcając zestaw danych i stosując trenowanie.

Zwracanie modelu wytrenowanego do użycia do oceny

Zwróć model na końcu BuildAndTrainModel() metody:

return model;

Ocena modelu

Po wytrenowanym modelu użyj danych testowych, aby zweryfikować wydajność modelu.

  1. Utwórz metodę Evaluate() tuż po BuildAndTrainModel(), przy użyciu następującego kodu:

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

    Metoda Evaluate() wykonuje następujące zadania:

    • Ładuje testowy zestaw danych.
    • Tworzy ewaluator BinaryClassification.
    • Ocenia model i tworzy metryki.
    • Wyświetla metryki.
  2. Dodaj wywołanie do nowej metody poniżej wywołania BuildAndTrainModel metody przy użyciu następującego kodu:

    Evaluate(mlContext, model, splitDataView.TestSet);
    
  3. Przekształć dane, splitTestSet dodając następujący kod do Evaluate()elementu :

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

    Poprzedni kod używa metody Transform(), aby przewidywać wiele dostarczonych wierszy wejściowych zestawu danych testowych.

  4. Oceń model, dodając następujący wiersz kodu w metodzie Evaluate() :

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

Po utworzeniu zestawu przewidywania (predictions) metoda Evaluate() ocenia model, który porównuje przewidywane wartości z wartościami rzeczywistymi Labels w zestawie danych testowych i zwraca obiekt CalibratedBinaryClassificationMetrics na temat sposobu działania modelu.

Wyświetlanie metryk weryfikacji modelu

Użyj następującego kodu, aby wyświetlić metryki:

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 ===============");
  • Metryka Accuracy pobiera dokładność modelu, który jest proporcją poprawnych przewidywań w zestawie testowym.

  • AreaUnderRocCurve Metryka wskazuje, w jaki sposób model prawidłowo klasyfikuje klasy dodatnie i ujemne. Chcesz, aby obiekt AreaUnderRocCurve był jak najbardziej zbliżony do jednego.

  • F1Score Metryka pobiera wynik F1 modelu, który jest miarą równowagi między precyzją a kompletnością. Chcesz, aby obiekt F1Score był jak najbardziej zbliżony do jednego.

Przewidywanie wyniku danych testowych

  1. Utwórz metodę UseModelWithSingleItem() tuż po metodzie Evaluate() przy użyciu następującego kodu:

    void UseModelWithSingleItem(MLContext mlContext, ITransformer model)
    {
    
    }
    

    Metoda UseModelWithSingleItem() wykonuje następujące zadania:

    • Tworzy pojedynczy komentarz danych testowych.
    • Przewiduje tonację na podstawie danych testowych.
    • Łączy dane testowe i przewidywania na potrzeby raportowania.
    • Wyświetla przewidywane wyniki.
  2. Dodaj wywołanie do nowej metody bezpośrednio w ramach Evaluate() wywołania metody przy użyciu następującego kodu:

    UseModelWithSingleItem(mlContext, model);
    
  3. Dodaj następujący kod, aby utworzyć jako pierwszy wiersz w metodzie UseModelWithSingleItem() :

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

    PredictionEngine to wygodny interfejs API, który umożliwia przewidywanie pojedynczego wystąpienia danych. PredictionEngine nie jest bezpieczny wątkowo. Dopuszczalne jest użycie w środowiskach jednowątkowych lub prototypowych. Aby zwiększyć wydajność i bezpieczeństwo wątków w środowiskach produkcyjnych, użyj PredictionEnginePool usługi , która tworzy ObjectPoolPredictionEngine obiekty do użycia w całej aplikacji. Zapoznaj się z tym przewodnikiem dotyczącym sposobu używania PredictionEnginePool w internetowym interfejsie API ASP.NET Core.

    Uwaga

    PredictionEnginePool Rozszerzenie usługi jest obecnie dostępne w wersji zapoznawczej.

  4. Dodaj komentarz, aby przetestować przewidywanie wytrenowanego modelu w metodzie UseModelWithSingleItem() , tworząc wystąpienie SentimentDataklasy :

    SentimentData sampleStatement = new SentimentData
    {
        SentimentText = "This was a very bad steak"
    };
    
  5. Przekaż dane komentarza testowego do obiektu PredictionEngine , dodając następujące wiersze kodu w metodzie UseModelWithSingleItem() :

    var resultPrediction = predictionFunction.Predict(sampleStatement);
    

    Funkcja Predict() tworzy przewidywanie dla pojedynczego wiersza danych.

  6. Wyświetl SentimentText i odpowiadające im przewidywanie tonacji przy użyciu następującego kodu:

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

Korzystanie z modelu do przewidywania

Wdrażanie i przewidywanie elementów wsadowych

  1. Utwórz metodę UseModelWithBatchItems() tuż po metodzie UseModelWithSingleItem() przy użyciu następującego kodu:

    void UseModelWithBatchItems(MLContext mlContext, ITransformer model)
    {
    
    }
    

    Metoda UseModelWithBatchItems() wykonuje następujące zadania:

    • Tworzy dane testowe wsadowe.
    • Przewiduje tonację na podstawie danych testowych.
    • Łączy dane testowe i przewidywania na potrzeby raportowania.
    • Wyświetla przewidywane wyniki.
  2. Dodaj wywołanie do nowej metody bezpośrednio w ramach UseModelWithSingleItem() wywołania metody przy użyciu następującego kodu:

    UseModelWithBatchItems(mlContext, model);
    
  3. Dodaj kilka komentarzy, aby przetestować przewidywania wytrenowanego modelu w metodzie UseModelWithBatchItems() :

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

Przewidywanie tonacji komentarzy

Użyj modelu, aby przewidzieć tonację danych komentarzy przy użyciu metody 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);

Łączenie i wyświetlanie przewidywań

Utwórz nagłówek dla przewidywań przy użyciu następującego kodu:

Console.WriteLine();

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

Ponieważ SentimentPrediction jest dziedziczony z SentimentDataklasy , Transform() metoda wypełniona SentimentText polami przewidywanymi. Podczas przetwarzania ML.NET każdy składnik dodaje kolumny i ułatwia wyświetlanie wyników:

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

Wyniki

Wyniki powinny być podobne do poniższych. Podczas przetwarzania są wyświetlane komunikaty. Mogą pojawić się ostrzeżenia lub przetwarzanie komunikatów. Zostały one usunięte z poniższych wyników w celu zapewnienia przejrzystości.

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

Gratulacje! Udało Ci się utworzyć model uczenia maszynowego do klasyfikowania i przewidywania tonacji komunikatów.

Tworzenie udanych modeli jest procesem iteracyjnym. Ten model ma początkową niższą jakość, ponieważ w samouczku używane są małe zestawy danych w celu zapewnienia szybkiego trenowania modelu. Jeśli nie jesteś zadowolony z jakości modelu, możesz spróbować go ulepszyć, udostępniając większe zestawy danych szkoleniowych lub wybierając różne algorytmy trenowania z różnymi hiperparatami dla każdego algorytmu.

Kod źródłowy tego samouczka można znaleźć w repozytorium dotnet/samples .

Następne kroki

W niniejszym samouczku zawarto informacje na temat wykonywania następujących czynności:

  • Tworzenie aplikacji konsolowej
  • Przygotowywanie danych
  • Ładowanie danych
  • Kompilowanie i trenowanie modelu
  • Ocena modelu
  • Używanie modelu do przewidywania
  • Zobacz wyniki

Przejdź do następnego samouczka, aby dowiedzieć się więcej