Zelfstudie: Ondersteuningsproblemen categoriseren met behulp van classificatie van meerdere klassen met ML.NET

Deze voorbeeldzelfstudie illustreert het gebruik van ML.NET om een GitHub-probleemclassificatie te maken om een model te trainen dat het gebiedslabel voor een GitHub-probleem classificeert en voorspelt via een .NET Core-consoletoepassing met behulp van C# in Visual Studio.

In deze zelfstudie leert u het volgende:

  • Uw gegevens voorbereiden
  • De gegevens transformeren
  • Het model trainen
  • Het model evalueren
  • Voorspellen met het getrainde model
  • Implementeren en voorspellen met een geladen model

U vindt de broncode voor deze zelfstudie in de opslagplaats dotnet/samples .

Vereisten

Een consoletoepassing maken

Een project maken

  1. Maak een C# -consoletoepassing met de naam GitHubIssueClassification. Selecteer Next.

  2. Kies .NET 7 als het framework dat u wilt gebruiken. Selecteer Maken.

  3. Maak een map met de naam Gegevens in uw project om uw gegevenssetbestanden op te slaan:

    Klik in Solution Explorer met de rechtermuisknop op uw project en selecteerNieuwe maptoevoegen>. Typ 'Gegevens' en druk op Enter.

  4. Maak een map met de naam Modellen in uw project om uw model op te slaan:

    Klik in Solution Explorer met de rechtermuisknop op uw project en selecteerNieuwe maptoevoegen>. Typ 'Modellen' en druk op Enter.

  5. Installeer het Microsoft.ML NuGet-pakket:

    Notitie

    In dit voorbeeld wordt de meest recente stabiele versie van de genoemde NuGet-pakketten gebruikt, tenzij anders vermeld.

    Klik in Solution Explorer met de rechtermuisknop op uw project en selecteer NuGet-pakketten beheren. Kies 'nuget.org' als pakketbron, selecteer het tabblad Bladeren, zoek naar Microsoft.ML en selecteer de knop Installeren . Selecteer de knop OK in het dialoogvenster Voorbeeld van wijzigingen en selecteer vervolgens de knop Ik ga akkoord in het dialoogvenster Licentie-acceptatie als u akkoord gaat met de licentievoorwaarden voor de vermelde pakketten.

Uw gegevens voorbereiden

  1. Download de gegevenssets issues_train.tsv en issues_test.tsv en sla deze op in de map Gegevens die u eerder hebt gemaakt. De eerste gegevensset traint het machine learning-model en de tweede kan worden gebruikt om te evalueren hoe nauwkeurig uw model is.

  2. Klik in Solution Explorer met de rechtermuisknop op elk van de *.tsv-bestanden en selecteer Eigenschappen. Wijzig onder Geavanceerd de waarde van Kopiëren naar uitvoermap inKopiëren indien nieuwer.

Klassen maken en paden definiëren

Voeg de volgende aanvullende using instructies toe aan het begin van het bestand Program.cs :

using Microsoft.ML;
using GitHubIssueClassification;

Maak drie globale velden voor de paden naar de onlangs gedownloade bestanden en globale variabelen voor de MLContext,DataView en PredictionEngine:

  • _trainDataPath heeft het pad naar de gegevensset die wordt gebruikt om het model te trainen.
  • _testDataPath bevat het pad naar de gegevensset die wordt gebruikt om het model te evalueren.
  • _modelPath bevat het pad waar het getrainde model wordt opgeslagen.
  • _mlContext is de MLContext die de verwerkingscontext biedt.
  • _trainingDataView is de IDataView die wordt gebruikt om de trainingsgegevensset te verwerken.
  • _predEngine is de PredictionEngine<TSrc,TDst> die wordt gebruikt voor enkele voorspellingen.

Voeg de volgende code toe aan de regel direct onder de using-instructies om deze paden en de andere variabelen op te geven:

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;

Maak enkele klassen voor uw invoergegevens en voorspellingen. Voeg een nieuwe klasse toe aan uw project:

  1. Klik in Solution Explorer met de rechtermuisknop op het project en selecteervervolgens Nieuw itemtoevoegen>.

  2. Selecteer in het dialoogvenster Nieuw item toevoegen de optie Klasse en wijzig het veld Naam in GitHubIssueData.cs. Selecteer vervolgens de knop Toevoegen .

    Het bestand GitHubIssueData.cs wordt geopend in de code-editor. Voeg de volgende using instructie toe aan het begin van GitHubIssueData.cs:

using Microsoft.ML.Data;

Verwijder de bestaande klassedefinitie en voeg de volgende code, met twee klassen GitHubIssue en IssuePrediction, toe aan het bestand 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;
}

De label is de kolom die u wilt voorspellen. De geïdentificeerde Features zijn de invoer die u het model geeft om het label te voorspellen.

Gebruik LoadColumnAttribute om de indexen van de bronkolommen in de gegevensset op te geven.

GitHubIssue is de klasse van de invoergegevensset en heeft de volgende String velden:

  • de eerste kolom ID (GitHub-probleem-id)
  • de tweede kolom Area (de voorspelling voor training)
  • de derde kolom Title (Titel van GitHub-probleem) is de eerste feature die wordt gebruikt voor het voorspellen van de Area
  • de vierde kolom is de tweede feature die Description wordt gebruikt voor het voorspellen van deArea

IssuePrediction is de klasse die wordt gebruikt voor voorspelling nadat het model is getraind. Het heeft één string (Area) en een PredictedLabelColumnName kenmerk. De PredictedLabel wordt gebruikt tijdens voorspelling en evaluatie. Voor de evaluatie wordt een invoer met trainingsgegevens, de voorspelde waarden en het model gebruikt.

Alle ML.NET bewerkingen beginnen in de klasse MLContext . Als u initialiseert mlContext , wordt er een nieuwe ML.NET omgeving gemaakt die kan worden gedeeld met de werkstroomobjecten voor het maken van modellen. Het is conceptueel DBContext vergelijkbaar met in Entity Framework.

Variabelen initialiseren

Initialiseer de _mlContext globale variabele met een nieuw exemplaar van MLContext met een willekeurige seed (seed: 0) voor herhaalbare/deterministische resultaten voor meerdere trainingen. Vervang de Console.WriteLine("Hello World!") regel door de volgende code:

_mlContext = new MLContext(seed: 0);

De gegevens laden

ML.NET gebruikt de IDataView-interface als een flexibele, efficiënte manier om numerieke gegevens of gegevens in tabelvorm te beschrijven. IDataView kan tekstbestanden of in realtime laden (bijvoorbeeld SQL-database of logboekbestanden).

Als u de _trainingDataView globale variabele wilt initialiseren en laden om deze te gebruiken voor de pijplijn, voegt u de volgende code toe na de mlContext initialisatie:

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

De LoadFromTextFile() definieert het gegevensschema en leest in het bestand. De gegevenspadvariabelen worden opgenomen en er wordt een IDataViewgeretourneerd.

Voeg het volgende toe nadat u de methode hebt LoadFromTextFile() aangeroepen:

var pipeline = ProcessData();

Met ProcessData de methode worden de volgende taken uitgevoerd:

  • Extraheert en transformeert de gegevens.
  • Retourneert de verwerkingspijplijn.

Maak de ProcessData methode onderaan het bestand Program.cs met behulp van de volgende code:

IEstimator<ITransformer> ProcessData()
{

}

Functies extraheren en de gegevens transformeren

Als u het GitHub-label Area voor een GitHubIssuewilt voorspellen, gebruikt u de methode MapValueToKey() om de Area kolom te transformeren in een kolom van het numerieke sleuteltype Label (een indeling die wordt geaccepteerd door classificatiealgoritmen) en voegt u deze toe als een nieuwe gegevenssetkolom:

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

Roep vervolgens mlContext.Transforms.Text.FeaturizeTextaan , waarmee de tekstkolommen (Title en Description) worden omgezet in een numerieke vector voor elke aangeroepen TitleFeaturized en DescriptionFeaturized. Voeg de featurization voor beide kolommen toe aan de pijplijn met de volgende code:

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

In de laatste stap van de gegevensvoorbereiding worden alle functiekolommen gecombineerd in de kolom Functies met behulp van de methode Concatenate(). Standaard verwerkt een leeralgoritmen alleen functies uit de kolom Functies . Voeg deze transformatie toe aan de pijplijn met de volgende code:

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

Voeg vervolgens een AppendCacheCheckpoint toe om de DataView in de cache op te laden, zodat wanneer u de gegevens meerdere keren door middel van de cache gebruikt, betere prestaties kunnen krijgen, zoals met de volgende code:

.AppendCacheCheckpoint(_mlContext);

Waarschuwing

Gebruik AppendCacheCheckpoint voor kleine/middelgrote gegevenssets om de trainingstijd te verlagen. Gebruik het NIET (verwijder . AppendCacheCheckpoint()) bij het verwerken van zeer grote gegevenssets.

Retourneer de pijplijn aan het einde van de ProcessData methode.

return pipeline;

In deze stap wordt de voorverwerking/featurization verwerkt. Door extra onderdelen te gebruiken die beschikbaar zijn in ML.NET kunt u betere resultaten met uw model mogelijk maken.

Het model bouwen en trainen

Voeg de volgende aanroep toe aan de BuildAndTrainModelmethode als de volgende regel na de aanroep van de ProcessData() methode:

var trainingPipeline = BuildAndTrainModel(_trainingDataView, pipeline);

Met BuildAndTrainModel de methode worden de volgende taken uitgevoerd:

  • Hiermee maakt u de trainingsalgoritmenklasse.
  • Traint het model.
  • Voorspelt gebied op basis van trainingsgegevens.
  • Retourneert het model.

Maak de BuildAndTrainModel methode, net na de declaratie van de ProcessData() methode, met behulp van de volgende code:

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

}

Over de classificatietaak

Classificatie is een machine learning-taak die gebruikmaakt van gegevens om de categorie, het type of de klasse van een item of rij met gegevens te bepalen . Deze taak is vaak een van de volgende typen:

  • Binair: A of B.
  • Meerdere klassen: meerdere categorieën die kunnen worden voorspeld met behulp van één model.

Gebruik voor dit type probleem een leeralgoritmen voor classificatie met meerdere klassen, omdat de voorspelling van uw probleemcategorie een van meerdere categorieën (meerdere klassen) kan zijn in plaats van slechts twee (binair).

Voeg het machine learning-algoritme toe aan de definities van gegevenstransformatie door het volgende toe te voegen als de eerste regel code in BuildAndTrainModel():

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

De SdcaMaximumEntropy is uw trainingsalgoritme voor classificatie met meerdere klassen. Dit wordt toegevoegd aan de pipeline en accepteert de featurized Title en Description (Features) en de Label invoerparameters om te leren van de historische gegevens.

Het model trainen

Pas het model aan de splitTrainSet gegevens aan en retourneer het getrainde model door het volgende toe te voegen als de volgende regel code in de BuildAndTrainModel() methode:

_trainedModel = trainingPipeline.Fit(trainingDataView);

Met de Fit()methode wordt uw model getraind door de gegevensset te transformeren en de training toe te passen.

De PredictionEngine is een handige API, waarmee u een voorspelling kunt doorgeven en vervolgens kunt uitvoeren op één exemplaar van gegevens. Voeg dit toe als de volgende regel in de BuildAndTrainModel() methode:

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

Voorspellen met het getrainde model

Voeg een GitHub-probleem toe om de voorspelling van het getrainde model in de Predict methode te testen door een exemplaar van te maken: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.."
};

Gebruik de functie Predict() om een voorspelling te doen op één rij met gegevens:

var prediction = _predEngine.Predict(issue);

Het model gebruiken: voorspellingsresultaten

Geef GitHubIssue en de bijbehorende Area labelvoorspelling weer om de resultaten te delen en erop te reageren. Maak een weergave voor de resultaten met behulp van de volgende Console.WriteLine() code:

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

Het model retourneren dat is getraind voor gebruik voor evaluatie

Retourneer het model aan het einde van de BuildAndTrainModel methode.

return trainingPipeline;

Het model evalueren

Nu u het model hebt gemaakt en getraind, moet u het evalueren met een andere gegevensset voor kwaliteitsborging en validatie. In de Evaluate methode wordt het model dat is gemaakt in BuildAndTrainModel doorgegeven om te worden geëvalueerd. Maak de Evaluate methode, net na BuildAndTrainModel, zoals in de volgende code:

void Evaluate(DataViewSchema trainingDataViewSchema)
{

}

Met Evaluate de methode worden de volgende taken uitgevoerd:

  • Laadt de testgegevensset.
  • Hiermee maakt u de evaluator voor meerdere klassen.
  • Evalueert het model en maakt metrische gegevens.
  • Geeft de metrische gegevens weer.

Voeg een aanroep toe aan de nieuwe methode, direct onder de BuildAndTrainModel methode-aanroep, met behulp van de volgende code:

Evaluate(_trainingDataView.Schema);

Zoals u eerder hebt gedaan met de trainingsgegevensset, laadt u de testgegevensset door de volgende code toe te voegen aan de Evaluate methode:

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

Met de methode Evaluate() worden de metrische kwaliteitsgegevens voor het model berekend met behulp van de opgegeven gegevensset. Het retourneert een MulticlassClassificationMetrics -object dat de algemene metrische gegevens bevat die zijn berekend door classificatie-evaluators met meerdere klassen. Als u de metrische gegevens wilt weergeven om de kwaliteit van het model te bepalen, moet u ze eerst ophalen. Let op het gebruik van de methode Transform() van de globale machine learning-variabele _trainedModel (een ITransformer) om de functies in te voeren en voorspellingen te retourneren. Voeg de volgende code toe aan de Evaluate methode als de volgende regel:

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

De volgende metrische gegevens worden geëvalueerd voor classificatie met meerdere klassen:

  • Micronauwkeurigheid: elk voorbeeldklassepaar draagt in gelijke mate bij aan de metrische nauwkeurigheid. U wilt dat micronauwkeurigheid er zo dicht mogelijk bij ligt.

  • Macronauwkeurigheid: elke klasse draagt in gelijke mate bij aan de metrische waarde voor nauwkeurigheid. Minderheidsklassen krijgen hetzelfde gewicht als de grotere klassen. U wilt dat macronauwkeurigheid zo dicht mogelijk bij een nauwkeurigheid ligt.

  • Logboekverlies: zie Logboekverlies. U wilt dat logboekverlies zo dicht mogelijk bij nul is.

  • Vermindering van logboekverlies: varieert van [-inf, 1,00], waarbij 1,00 perfecte voorspellingen is en 0 gemiddelde voorspellingen aangeeft. U wilt dat het verminderen van logboekverlies zo dicht mogelijk bij een van de twee komt.

De metrische gegevens voor modelvalidatie weergeven

Gebruik de volgende code om de metrische gegevens weer te geven, de resultaten te delen en er vervolgens actie op te ondernemen:

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

Het model opslaan in een bestand

Zodra u tevreden bent met uw model, slaat u het op in een bestand om voorspellingen te doen op een later tijdstip of in een andere toepassing. Voeg de volgende code toe aan de methode Evaluate.

SaveModelAsFile(_mlContext, trainingDataViewSchema, _trainedModel);

Maak de SaveModelAsFile methode onder uw Evaluate methode.

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

}

Voeg de volgende code toe aan uw SaveModelAsFile methode. Deze code maakt gebruik van de Save methode om het getrainde model te serialiseren en op te slaan als een zip-bestand.

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

Implementeren en voorspellen met een model

Voeg een aanroep toe aan de nieuwe methode, direct onder de Evaluate methode-aanroep, met behulp van de volgende code:

PredictIssue();

Maak de PredictIssue methode, net na de Evaluate methode (en net vóór de SaveModelAsFile methode), met behulp van de volgende code:

void PredictIssue()
{

}

Met PredictIssue de methode worden de volgende taken uitgevoerd:

  • Het opgeslagen model laden
  • Hiermee wordt één probleem met testgegevens gemaakt.
  • Hiermee wordt een gebied voorspeld op basis van testgegevens.
  • Combineert testgegevens en voorspellingen voor rapportage.
  • Geeft de voorspelde resultaten weer.

Laad het opgeslagen model in uw toepassing door de volgende code toe te voegen aan de PredictIssue methode:

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

Voeg een GitHub-probleem toe om de voorspelling van het getrainde model in de Predict methode te testen door een exemplaar van te maken:GitHubIssue

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

Zoals u eerder hebt gedaan, maakt u een PredictionEngine exemplaar met de volgende code:

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

De PredictionEngine is een handige API waarmee u een voorspelling kunt uitvoeren op één exemplaar van gegevens. PredictionEngine is niet thread-safe. Het is acceptabel om te gebruiken in omgevingen met één thread of prototype. Voor verbeterde prestaties en threadveiligheid in productieomgevingen gebruikt u de PredictionEnginePool service, waarmee een ObjectPool van PredictionEngine -objecten wordt gemaakt voor gebruik in uw toepassing. Raadpleeg deze handleiding over het gebruik PredictionEnginePool in een ASP.NET Core web-API.

Notitie

PredictionEnginePool de service-extensie is momenteel in preview.

Gebruik de PredictionEngine om het GitHub-label Area te voorspellen door de volgende code toe te voegen aan de PredictIssue methode voor de voorspelling:

var prediction = _predEngine.Predict(singleIssue);

Het geladen model gebruiken voor voorspelling

Weergeven Area om het probleem te categoriseren en erop te reageren. Maak een weergave voor de resultaten met behulp van de volgende Console.WriteLine() code:

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

Resultaten

De resultaten moeten er ongeveer als volgt uitzien. Terwijl de pijplijn wordt verwerkt, worden berichten weergegeven. Mogelijk ziet u waarschuwingen of worden berichten verwerkt. Deze berichten zijn voor de duidelijkheid verwijderd uit de volgende resultaten.

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

Gefeliciteerd U hebt nu een machine learning-model gebouwd voor het classificeren en voorspellen van een gebiedslabel voor een GitHub-probleem. U vindt de broncode voor deze zelfstudie in de opslagplaats dotnet/samples .

Volgende stappen

In deze zelfstudie heeft u het volgende geleerd:

  • Uw gegevens voorbereiden
  • De gegevens transformeren
  • Het model trainen
  • Het model evalueren
  • Voorspellen met het getrainde model
  • Implementeren en voorspellen met een geladen model

Ga naar de volgende zelfstudie voor meer informatie