Samouczek: kategoryzowanie problemów z pomocą techniczną przy użyciu klasyfikacji wieloklasowej przy użyciu ML.NET

W tym przykładowym samouczku pokazano użycie ML.NET do utworzenia klasyfikatora problemów z usługą GitHub w celu wytrenowania modelu, który klasyfikuje i przewiduje etykietę Obszar dla problemu z usługą GitHub za pośrednictwem aplikacji konsolowej platformy .NET Core przy użyciu języka C# w programie Visual Studio.

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

  • Przygotowywanie danych
  • Przekształcanie danych
  • Trenowanie modelu
  • Ocena modelu
  • Przewidywanie za pomocą wytrenowanego modelu
  • Wdrażanie i przewidywanie przy użyciu załadowanego modelu

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

Wymagania wstępne

Tworzenie aplikacji konsolowej

Tworzenie projektu

  1. Utwórz aplikację konsolową języka C# o nazwie "GitHubIssueClassification". Wybierz opcję Dalej.

  2. Wybierz platformę .NET 7 jako platformę do użycia. Wybierz przycisk Utwórz.

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

    W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Dodaj>nowy folder. Wpisz "Dane" i naciśnij klawisz Enter.

  4. Utwórz katalog o nazwie Models w projekcie, aby zapisać model:

    W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Dodaj>nowy folder. Wpisz "Modele" i naciśnij klawisz Enter.

  5. 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, wybierz kartę Przeglądaj, wyszukaj Microsoft.ML i wybierz przycisk Zainstaluj . Wybierz przycisk OK w oknie dialogowym Podgląd zmian , a następnie wybierz przycisk Akceptuję w oknie dialogowym Akceptacja licencji , jeśli zgadzasz się z postanowieniami licencyjnymi dla pakietów wymienionych.

Przygotowywanie danych

  1. Pobierz zestawy danych issues_train.tsv i issues_test.tsv i zapisz je w utworzonym wcześniej folderze Data . Pierwszy zestaw danych szkoli model uczenia maszynowego, a drugi może służyć do oceny dokładności modelu.

  2. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy każdy z plików *.tsv i wybierz pozycję 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

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

using Microsoft.ML;
using GitHubIssueClassification;

Utwórz trzy pola globalne do przechowywania ścieżek do ostatnio pobranych plików oraz zmiennych globalnych dla zmiennych MLContext,DataView i PredictionEngine:

  • _trainDataPath zawiera ścieżkę do zestawu danych używanego do trenowania modelu.
  • _testDataPath zawiera ścieżkę do zestawu danych używanego do oceny modelu.
  • _modelPath ma ścieżkę, w której jest zapisywany wytrenowany model.
  • _mlContextMLContext to element, który zapewnia kontekst przetwarzania.
  • _trainingDataViewIDataView jest używany do przetwarzania zestawu danych trenowania.
  • _predEnginePredictionEngine<TSrc,TDst> jest używany w przypadku pojedynczych przewidywań.

Dodaj następujący kod do wiersza bezpośrednio poniżej instrukcji using, aby określić te ścieżki i inne zmienne:

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;

Utwórz kilka klas dla danych wejściowych i przewidywań. Dodaj nową klasę do projektu:

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

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

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

using Microsoft.ML.Data;

Usuń istniejącą definicję klasy i dodaj następujący kod, który zawiera dwie klasy GitHubIssue i IssuePrediction, do pliku 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;
}

Jest label to kolumna, którą chcesz przewidzieć. Zidentyfikowane Features są dane wejściowe, które dają modelowi do przewidywania etykiety.

Użyj atrybutu LoadColumnAttribute , aby określić indeksy kolumn źródłowych w zestawie danych.

GitHubIssue jest klasą wejściowego zestawu danych i ma następujące String pola:

  • pierwsza kolumna (identyfikator problemu w usłudze ID GitHub)
  • druga kolumna Area (przewidywanie trenowania)
  • trzecia kolumna Title (tytuł problemu w usłudze GitHub) jest pierwszym feature używanym do przewidywania Area
  • czwarta kolumna Description jest drugą feature używaną do przewidywania wartości Area

IssuePrediction jest klasą używaną do przewidywania po wytrenowanym modelu. Ma jeden string (Area) i PredictedLabelColumnName atrybut. Element PredictedLabel jest używany podczas przewidywania i oceny. Do oceny są używane dane wejściowe z danymi treningowymi, wartościami przewidywanymi i modelem.

Wszystkie operacje ML.NET są uruchamiane w klasie MLContext . Inicjowanie mlContext tworzy nowe środowisko ML.NET, które może być współużytkowane przez obiekty przepływu pracy tworzenia modelu. Jest ona podobna, koncepcyjnie, do DBContext w pliku Entity Framework.

Inicjowanie zmiennych

Zainicjuj _mlContext zmienną globalną przy użyciu nowego wystąpienia MLContext elementu z losowym inicjatorem (seed: 0) w celu powtarzalnych/deterministycznych wyników w wielu szkoleniach. Zastąp Console.WriteLine("Hello World!") wiersz następującym kodem:

_mlContext = new MLContext(seed: 0);

Ładowanie danych

ML.NET używa interfejsu IDataView jako elastycznego, wydajnego sposobu opisywania danych liczbowych lub tekstowych tabelarycznych. IDataView może ładować pliki tekstowe lub w czasie rzeczywistym (na przykład bazę danych SQL lub pliki dziennika).

Aby zainicjować i załadować zmienną _trainingDataView globalną w celu użycia jej dla potoku, dodaj następujący kod po zainicjowaniu mlContext :

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

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

Dodaj następujące elementy po wywołaniu LoadFromTextFile() metody :

var pipeline = ProcessData();

Metoda ProcessData wykonuje następujące zadania:

  • Wyodrębnia i przekształca dane.
  • Zwraca potok przetwarzania.

Utwórz metodę ProcessData w dolnej części pliku Program.cs przy użyciu następującego kodu:

IEstimator<ITransformer> ProcessData()
{

}

Wyodrębnianie funkcji i przekształcanie danych

Aby przewidzieć etykietę Area GitHub dla elementu GitHubIssue, użyj metody MapValueToKey(), aby przekształcić Area kolumnę w kolumnę typu Label klucza liczbowego (format akceptowany przez algorytmy klasyfikacji) i dodać ją jako nową kolumnę zestawu danych:

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

Następnie wywołaj metodę mlContext.Transforms.Text.FeaturizeText, która przekształca kolumny tekstowe (Title i Description) w wektor liczbowy dla każdej z wywołań TitleFeaturized i DescriptionFeaturized. Dołącz cechowanie obu kolumn do potoku przy użyciu następującego kodu:

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

Ostatni krok przygotowywania danych łączy wszystkie kolumny funkcji w kolumnie Funkcje przy użyciu metody Concatenate(). Domyślnie algorytm uczenia przetwarza tylko funkcje z kolumny Funkcje . Dołącz to przekształcenie do potoku przy użyciu następującego kodu:

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

Następnie dołącz element , AppendCacheCheckpoint aby buforować obiekt DataView, aby podczas iterowania danych wiele razy przy użyciu pamięci podręcznej mógł uzyskać lepszą wydajność, tak jak w przypadku następującego kodu:

.AppendCacheCheckpoint(_mlContext);

Ostrzeżenie

Użyj funkcji AppendCacheCheckpoint dla małych/średnich zestawów danych, aby zmniejszyć czas trenowania. NIE używaj go (usuń wartość . AppendCacheCheckpoint()) podczas obsługi bardzo dużych zestawów danych.

Zwróć potok na końcu ProcessData metody .

return pipeline;

Ten krok obsługuje przetwarzanie wstępne/cechowanie. Korzystanie z dodatkowych składników dostępnych w ML.NET może zapewnić lepsze wyniki w modelu.

Kompilowanie i trenowanie modelu

Dodaj następujące wywołanie do BuildAndTrainModelmetody jako następny wiersz po wywołaniu metody ProcessData() :

var trainingPipeline = BuildAndTrainModel(_trainingDataView, pipeline);

Metoda BuildAndTrainModel wykonuje następujące zadania:

  • Tworzy klasę algorytmu trenowania.
  • Trenuje model.
  • Przewiduje obszar na podstawie danych szkoleniowych.
  • Zwraca model.

Utwórz metodę BuildAndTrainModel tuż po deklaracji metody przy użyciu następującego ProcessData() kodu:

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

}

Informacje o zadaniu klasyfikacji

Klasyfikacja to zadanie uczenia maszynowego, które używa danych do określania kategorii, typu lub klasy elementu lub wiersza danych i jest często jednym z następujących typów:

  • Binarne: A lub B.
  • Wieloklasowa: wiele kategorii, które można przewidzieć przy użyciu jednego modelu.

W przypadku tego typu problemu użyj algorytmu uczenia klasyfikacji wieloklasowej, ponieważ przewidywanie kategorii problemów może być jedną z wielu kategorii (wieloklasowych), a nie tylko dwie (binarne).

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

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

SdcaMaximumEntropy to algorytm trenowania klasyfikacji wieloklasowej. Jest to dołączane do elementu pipeline i akceptuje cechowane Title i Description (Features) oraz Label parametry wejściowe do nauki z danych historycznych.

Trenowanie modelu

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

_trainedModel = trainingPipeline.Fit(trainingDataView);

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

PredictionEngine to wygodny interfejs API, który umożliwia przekazanie, a następnie wykonanie przewidywania dla pojedynczego wystąpienia danych. Dodaj to jako następny wiersz w metodzie BuildAndTrainModel() :

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

Przewidywanie za pomocą wytrenowanego modelu

Dodawanie problemu z usługą GitHub w celu przetestowania przewidywania wytrenowanego modelu w metodzie Predict przez utworzenie wystąpienia elementu 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.."
};

Użyj funkcji Predict() prognozowania dla pojedynczego wiersza danych:

var prediction = _predEngine.Predict(issue);

Korzystanie z modelu: wyniki przewidywania

Wyświetlanie GitHubIssue i odpowiednie Area przewidywanie etykiet w celu udostępnienia wyników i odpowiedniego działania na nich. Utwórz wyświetlanie wyników przy użyciu następującego Console.WriteLine() kodu:

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

Zwracanie modelu wytrenowanego do użycia do oceny

Zwróć model na końcu BuildAndTrainModel metody.

return trainingPipeline;

Ocena modelu

Teraz, po utworzeniu i wytrenowanym modelu, musisz ocenić go przy użyciu innego zestawu danych w celu zapewnienia jakości i weryfikacji. W metodzie Evaluate model utworzony w BuildAndTrainModel pliku jest przekazywany do oceny. Utwórz metodę Evaluate tuż po BuildAndTrainModelmetodzie , jak w poniższym kodzie:

void Evaluate(DataViewSchema trainingDataViewSchema)
{

}

Metoda Evaluate wykonuje następujące zadania:

  • Ładuje testowy zestaw danych.
  • Tworzy wieloklasowy ewaluator.
  • Ocenia model i tworzy metryki.
  • Wyświetla metryki.

Dodaj wywołanie do nowej metody, bezpośrednio pod BuildAndTrainModel wywołaniem metody, używając następującego kodu:

Evaluate(_trainingDataView.Schema);

Podobnie jak wcześniej w przypadku zestawu danych trenowania, załaduj zestaw danych testowego, dodając następujący kod do Evaluate metody:

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

Metoda Evaluate() oblicza metryki jakości modelu przy użyciu określonego zestawu danych. Zwraca MulticlassClassificationMetrics obiekt zawierający ogólne metryki obliczane przez ewaluatorów klasyfikacji wieloklasowej. Aby wyświetlić metryki w celu określenia jakości modelu, należy je najpierw pobrać. Zwróć uwagę na użycie metody Transform() zmiennej globalnej uczenia _trainedModel maszynowego ( ITransformer) do wprowadzania funkcji i zwracania przewidywań. Dodaj następujący kod do Evaluate metody jako następny wiersz:

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

Następujące metryki są oceniane pod kątem klasyfikacji wieloklasowej:

  • Micro Accuracy — każda para klas próbek współtworzy metryki dokładności. Chcesz, aby mikro dokładności był jak najbardziej zbliżony do jednego.

  • Dokładność makr — każda klasa współtworzy metryki dokładności. Klasy mniejszości mają taką samą wagę jak większe klasy. Chcesz, aby dokładność makra był jak najbardziej zbliżona do jednego.

  • Log-loss — zobacz Log Loss (Utrata dziennika). Chcesz, aby strata dziennika był jak najbardziej zbliżona do zera.

  • Redukcja utraty dzienników — zakresy od [-inf, 1,00], gdzie 1,00 jest doskonałymi przewidywaniami, a 0 oznacza średnie przewidywania. Chcesz, aby zmniejszenie strat dzienników było jak najbardziej zbliżone do jednego.

Wyświetlanie metryk weryfikacji modelu

Użyj następującego kodu, aby wyświetlić metryki, udostępnić wyniki, a następnie wykonać na nich działania:

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

Zapisywanie modelu w pliku

Po zakończeniu pracy z modelem zapisz go w pliku w celu przewidywania w późniejszym czasie lub w innej aplikacji. Dodaj następujący kod do metody Evaluate:

SaveModelAsFile(_mlContext, trainingDataViewSchema, _trainedModel);

Utwórz metodę SaveModelAsFile poniżej Evaluate metody .

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

}

Dodaj następujący kod do SaveModelAsFile metody . Ten kod używa Save metody do serializacji i przechowywania wytrenowanego modelu jako pliku zip.

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

Wdrażanie i przewidywanie za pomocą modelu

Dodaj wywołanie do nowej metody, bezpośrednio pod Evaluate wywołaniem metody, używając następującego kodu:

PredictIssue();

Utwórz metodę PredictIssue tuż po Evaluate metodzie (i tuż przed metodą), używając następującego SaveModelAsFile kodu:

void PredictIssue()
{

}

Metoda PredictIssue wykonuje następujące zadania:

  • Ładuje zapisany model
  • Tworzy pojedynczy problem z danymi testowym.
  • Przewiduje obszar na podstawie danych testowych.
  • Łączy dane testowe i przewidywania na potrzeby raportowania.
  • Wyświetla przewidywane wyniki.

Załaduj zapisany model do aplikacji, dodając następujący kod do PredictIssue metody:

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

Dodawanie problemu z usługą GitHub w celu przetestowania przewidywania wytrenowanego modelu w metodzie Predict przez utworzenie wystąpienia elementu GitHubIssue:

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

Podobnie jak wcześniej, utwórz PredictionEngine wystąpienie przy użyciu następującego kodu:

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

PredictionEngine to wygodny interfejs API, który umożliwia przewidywanie dla pojedynczego wystąpienia danych. PredictionEngine nie jest bezpieczne 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. Zobacz ten przewodnik dotyczący używania PredictionEnginePool w internetowym interfejsie API ASP.NET Core.

Uwaga

PredictionEnginePool Rozszerzenie usługi jest obecnie w wersji zapoznawczej.

Użyj elementu , PredictionEngine aby przewidzieć etykietę Area GitHub (Obszar w usłudze GitHub), dodając następujący kod do PredictIssue metody przewidywania:

var prediction = _predEngine.Predict(singleIssue);

Używanie załadowanego modelu do przewidywania

Wyświetl Area w celu kategoryzowania problemu i odpowiedniego działania. Utwórz wyświetlanie wyników przy użyciu następującego Console.WriteLine() kodu:

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

Wyniki

Wyniki powinny być podobne do poniższych. W miarę przetwarzania potoku są wyświetlane komunikaty. Mogą pojawić się ostrzeżenia lub komunikaty przetwarzania. Te komunikaty zostały usunięte z poniższych wyników w celu uzyskania jasności.

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

Gratulacje! Udało Ci się pomyślnie skompilować model uczenia maszynowego do klasyfikowania i przewidywania etykiety Obszar dla problemu z usługą GitHub. 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:

  • Przygotowywanie danych
  • Przekształcanie danych
  • Trenowanie modelu
  • Ocena modelu
  • Przewidywanie za pomocą wytrenowanego modelu
  • Wdrażanie i przewidywanie przy użyciu załadowanego modelu

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