Dela via


Självstudie: Kategorisera supportproblem med klassificering med flera klasser med ML.NET

Den här exempelsjälvstudien visar hur du använder ML.NET för att skapa en GitHub-problemklassificerare för att träna en modell som klassificerar och förutsäger areaetiketten för ett GitHub-problem via ett .NET Core-konsolprogram med C# i Visual Studio.

I den här guiden får du lära dig att:

  • Förbereda dina data
  • Transformera data
  • Träna modellen
  • Utvärdera modellen
  • Förutsäga med den tränade modellen
  • Distribuera och förutsäga med en inläst modell

Du hittar källkoden för den här självstudien på lagringsplatsen dotnet/samples .

Krav

Skapa ett konsolprogram

Skapa ett projekt

  1. Skapa ett C# -konsolprogram med namnet "GitHubIssueClassification". Välj Nästa.

  2. Välj .NET 7 som ramverk att använda. Välj Skapa.

  3. Skapa en katalog med namnet Data i projektet för att spara datauppsättningsfilerna:

    I Solution Explorer högerklickar du på projektet och väljer Lägg till>ny mapp. Skriv "Data" och tryck på Retur.

  4. Skapa en katalog med namnet Models i projektet för att spara din modell:

    I Solution Explorer högerklickar du på projektet och väljer Lägg till>ny mapp. Skriv "Models" (Modeller) och tryck på Retur.

  5. Installera Microsoft.ML NuGet-paketet:

    Anteckning

    I det här exemplet används den senaste stabila versionen av De NuGet-paket som nämns om inget annat anges.

    I Solution Explorer högerklickar du på projektet och väljer Hantera NuGet-paket. Välj "nuget.org" som paketkälla, välj fliken Bläddra, sök efter Microsoft.ML och välj knappen Installera . Välj knappen OK i dialogrutan Förhandsgranska ändringar och välj sedan knappen Jag accepterar i dialogrutan Godkännande av licens om du godkänner licensvillkoren för de paket som anges.

Förbereda dina data

  1. Ladda ned datauppsättningarna issues_train.tsv och issues_test.tsv och spara dem i mappen Data som du skapade tidigare. Den första datauppsättningen tränar maskininlärningsmodellen och den andra kan användas för att utvärdera hur exakt din modell är.

  2. I Solution Explorer högerklickar du på var och en av *.tsv-filerna och väljer Egenskaper. Under Avancerat ändrar du värdet för Kopiera till utdatakatalog till Kopiera om nyare.

Skapa klasser och definiera sökvägar

Lägg till följande ytterligare using instruktioner överst i filen Program.cs :

using Microsoft.ML;
using GitHubIssueClassification;

Skapa tre globala fält för att lagra sökvägarna till de nyligen nedladdade filerna och globala variabler för MLContext,DataView och PredictionEngine:

  • _trainDataPath har sökvägen till den datauppsättning som används för att träna modellen.
  • _testDataPath har sökvägen till datauppsättningen som används för att utvärdera modellen.
  • _modelPath har sökvägen där den tränade modellen sparas.
  • _mlContext är som MLContext ger bearbetningskontext.
  • _trainingDataView är den IDataView som används för att bearbeta träningsdatauppsättningen.
  • _predEngine är den PredictionEngine<TSrc,TDst> som används för enskilda förutsägelser.

Lägg till följande kod på raden direkt under using-instruktionerna för att ange sökvägarna och de andra variablerna:

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;

Skapa några klasser för dina indata och förutsägelser. Lägg till en ny klass i projektet:

  1. I Solution Explorer högerklickar du på projektet och väljer sedan Lägg till>nytt objekt.

  2. I dialogrutan Lägg till nytt objekt väljer du Klass och ändrar fältet Namn till GitHubIssueData.cs. Välj sedan knappen Lägg till .

    Filen GitHubIssueData.cs öppnas i kodredigeraren. Lägg till följande using -instruktion överst i GitHubIssueData.cs:

using Microsoft.ML.Data;

Ta bort den befintliga klassdefinitionen och lägg till följande kod, som har två klasser GitHubIssue och IssuePrediction, i filen 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;
}

label är den kolumn som du vill förutsäga. De identifierade Features är de indata som du ger modellen för att förutsäga etiketten.

Använd LoadColumnAttribute för att ange index för källkolumnerna i datauppsättningen.

GitHubIssue är indatauppsättningsklassen och har följande String fält:

  • den första kolumnen ID (GitHub-ärende-ID)
  • den andra kolumnen Area (förutsägelsen för träning)
  • den tredje kolumnen Title (GitHub-ärenderubrik) är den första feature som används för att förutsäga Area
  • den fjärde kolumnen Description är den andra feature som används för att förutsäga Area

IssuePrediction är klassen som används för förutsägelse när modellen har tränats. Den har ett enda string (Area) och ett PredictedLabelColumnName attribut. PredictedLabel används under förutsägelse och utvärdering. För utvärdering används indata med träningsdata, förutsagda värden och modellen.

Alla ML.NET åtgärder startar i MLContext-klassen . När du initierar mlContext skapas en ny ML.NET miljö som kan delas mellan arbetsflödesobjekten för modellskapande. Det liknar begreppsmässigt i DBContextEntity Framework.

Initiera variabler

Initiera den _mlContext globala variabeln med en ny instans av MLContext med ett slumpmässigt frö (seed: 0) för repeterbara/deterministiska resultat över flera träningar. Ersätt raden Console.WriteLine("Hello World!") med följande kod:

_mlContext = new MLContext(seed: 0);

Läsa in data

ML.NET använder IDataView-gränssnittet som ett flexibelt och effektivt sätt att beskriva numeriska data eller tabelldata i text. IDataView kan läsa in antingen textfiler eller i realtid (till exempel SQL-databas eller loggfiler).

Om du vill initiera och läsa in den _trainingDataView globala variabeln för att kunna använda den för pipelinen lägger du till följande kod efter initieringen mlContext :

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

LoadFromTextFile() definierar dataschemat och läser i filen. Den tar in datasökvägsvariablerna och returnerar en IDataView.

Lägg till följande när du har anropat LoadFromTextFile() metoden :

var pipeline = ProcessData();

Metoden ProcessData kör följande uppgifter:

  • Extraherar och transformerar data.
  • Returnerar bearbetningspipelinen.

ProcessData Skapa metoden längst ned i filen Program.cs med hjälp av följande kod:

IEstimator<ITransformer> ProcessData()
{

}

Extrahera funktioner och transformera data

När du vill förutsäga Area GitHub-etiketten för en GitHubIssueanvänder du metoden MapValueToKey() för att omvandla Area kolumnen till en kolumn av numerisk nyckeltyp Label (ett format som accepteras av klassificeringsalgoritmer) och lägger till den som en ny datauppsättningskolumn:

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

Anropa sedan mlContext.Transforms.Text.FeaturizeText, som omvandlar textkolumnerna (Title och Description) till en numerisk vektor för varje som heter TitleFeaturized och DescriptionFeaturized. Lägg till funktionaliseringen för båda kolumnerna i pipelinen med följande kod:

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

Det sista steget i förberedelsen av data kombinerar alla funktionskolumner i kolumnen Funktioner med hjälp av metoden Concatenate(). Som standard bearbetar en inlärningsalgoritm endast funktioner från kolumnen Funktioner . Lägg till den här omvandlingen i pipelinen med följande kod:

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

Lägg sedan till en AppendCacheCheckpoint för att cachelagra DataView så att när du itererar över data flera gånger med cacheminnet kan det få bättre prestanda, som med följande kod:

.AppendCacheCheckpoint(_mlContext);

Varning

Använd AppendCacheCheckpoint för små/medelstora datamängder för att minska träningstiden. Använd DEN INTE (ta bort . AppendCacheCheckpoint()) vid hantering av mycket stora datamängder.

Returnera pipelinen i slutet av ProcessData metoden.

return pipeline;

Det här steget hanterar förbearbetning/funktionalisering. Om du använder ytterligare komponenter som är tillgängliga i ML.NET kan du få bättre resultat med din modell.

Skapa och träna modellen

Lägg till följande anrop till BuildAndTrainModelmetoden som nästa rad efter anropet till ProcessData() metoden:

var trainingPipeline = BuildAndTrainModel(_trainingDataView, pipeline);

Metoden BuildAndTrainModel kör följande uppgifter:

  • Skapar träningsalgoritmklassen.
  • Tränar modellen.
  • Förutsäger område baserat på träningsdata.
  • Returnerar modellen.

BuildAndTrainModel Skapa metoden, precis efter deklarationen ProcessData() av metoden, med hjälp av följande kod:

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

}

Om klassificeringsuppgiften

Klassificering är en maskininlärningsuppgift som använder data för att fastställa kategori, typ eller klass för ett objekt eller en rad med data och som ofta är en av följande typer:

  • Binär: antingen A eller B.
  • Multiklass: flera kategorier som kan förutsägas med hjälp av en enda modell.

För den här typen av problem använder du en inlärningsalgoritm för multiklassklassificering eftersom förutsägelsen för problemkategorin kan vara en av flera kategorier (multiklass) i stället för bara två (binär).

Lägg till maskininlärningsalgoritmen i definitionerna för datatransformering genom att lägga till följande som den första kodraden i BuildAndTrainModel():

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

SdcaMaximumEntropy är din multiklassklassificeringsträningsalgoritm. Detta läggs till pipeline i och accepterar de funktionaliserade Title och Description (Features) och indataparametrarna Label för att lära av historiska data.

Träna modellen

Anpassa modellen till data och returnera den tränade modellen genom att splitTrainSet lägga till följande som nästa kodrad i BuildAndTrainModel() metoden:

_trainedModel = trainingPipeline.Fit(trainingDataView);

Metoden Fit()tränar din modell genom att transformera datauppsättningen och tillämpa träningen.

PredictionEngine är ett bekvämlighets-API som gör att du kan skicka in och sedan utföra en förutsägelse på en enda instans av data. Lägg till detta som nästa rad i BuildAndTrainModel() metoden:

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

Förutsäga med den tränade modellen

Lägg till ett GitHub-problem för att testa den tränade modellens förutsägelse i Predict metoden genom att skapa en instans av 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.."
};

Använd funktionen Predict() gör en förutsägelse på en enda rad med data:

var prediction = _predEngine.Predict(issue);

Använd modellen: förutsägelseresultat

Visa GitHubIssue och motsvarande Area etikettförutsägelse för att dela resultaten och agera på dem i enlighet med detta. Skapa en visning för resultaten med hjälp av följande Console.WriteLine() kod:

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

Returnera den modell som tränats att användas för utvärdering

Returnera modellen i slutet av BuildAndTrainModel metoden.

return trainingPipeline;

Utvärdera modellen

Nu när du har skapat och tränat modellen måste du utvärdera den med en annan datauppsättning för kvalitetssäkring och validering. Evaluate I -metoden skickas den modell som skapats i BuildAndTrainModel in för att utvärderas. Evaluate Skapa -metoden, precis efter BuildAndTrainModel, som i följande kod:

void Evaluate(DataViewSchema trainingDataViewSchema)
{

}

Metoden Evaluate kör följande uppgifter:

  • Läser in testdatauppsättningen.
  • Skapar utvärderaren för flera grupper.
  • Utvärderar modellen och skapar mått.
  • Visar måtten.

Lägg till ett anrop till den nya metoden direkt under metodanropet BuildAndTrainModel med hjälp av följande kod:

Evaluate(_trainingDataView.Schema);

Precis som du gjorde tidigare med träningsdatauppsättningen läser du in testdatamängden genom att lägga till följande kod i Evaluate metoden:

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

Metoden Evaluate() beräknar kvalitetsmåtten för modellen med den angivna datamängden. Det returnerar ett MulticlassClassificationMetrics objekt som innehåller de övergripande måtten som beräknas av multiklassklassificeringsutvärderingar. Om du vill visa måtten för att fastställa modellens kvalitet måste du hämta dem först. Observera användningen av metoden Transform() för den globala variabeln för maskininlärning _trainedModel (en ITransformer) för att mata in funktionerna och returnera förutsägelser. Lägg till följande kod i Evaluate metoden som nästa rad:

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

Följande mått utvärderas för multiklassklassificering:

  • Mikronoggrannhet – varje exempelklasspar bidrar lika till noggrannhetsmåttet. Du vill att mikronoggrannheten ska vara så nära en som möjligt.

  • Makronoggrannhet – Varje klass bidrar lika till noggrannhetsmåttet. Minoritetsklasser får lika stor vikt som de större klasserna. Du vill att makronoggrannhet ska vara så nära ett som möjligt.

  • Loggförlust – se Loggförlust. Du vill att loggförlusten ska vara så nära noll som möjligt.

  • Minskning av loggförlust – intervall från [-inf, 1,00], där 1,00 är perfekta förutsägelser och 0 anger medelvärdesförutsägelser. Du vill att loggförlustminskningen ska vara så nära en som möjligt.

Visa måtten för modellvalidering

Använd följande kod för att visa måtten, dela resultaten och sedan agera på dem:

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

Spara modellen i en fil

När du är nöjd med din modell sparar du den i en fil för att göra förutsägelser vid ett senare tillfälle eller i ett annat program. Lägg till följande kod i metoden Evaluate.

SaveModelAsFile(_mlContext, trainingDataViewSchema, _trainedModel);

SaveModelAsFile Skapa metoden under din Evaluate metod.

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

}

Lägg till följande kod i din SaveModelAsFile metod. Den här koden använder Save metoden för att serialisera och lagra den tränade modellen som en zip-fil.

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

Distribuera och förutsäga med en modell

Lägg till ett anrop till den nya metoden direkt under metodanropet Evaluate med hjälp av följande kod:

PredictIssue();

PredictIssue Skapa metoden, precis efter Evaluate -metoden (och precis före SaveModelAsFile metoden), med hjälp av följande kod:

void PredictIssue()
{

}

Metoden PredictIssue kör följande uppgifter:

  • Läser in den sparade modellen
  • Skapar ett enda problem med testdata.
  • Förutsäger område baserat på testdata.
  • Kombinerar testdata och förutsägelser för rapportering.
  • Visar de förutsagda resultaten.

Läs in den sparade modellen i ditt program genom att lägga till följande kod i PredictIssue metoden:

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

Lägg till ett GitHub-problem för att testa den tränade modellens förutsägelse i Predict metoden genom att skapa en instans av GitHubIssue:

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

Som du gjorde tidigare skapar du en PredictionEngine instans med följande kod:

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

PredictionEngine är ett bekvämlighets-API som gör att du kan utföra en förutsägelse på en enda instans av data. PredictionEngine är inte trådsäkert. Det är acceptabelt att använda i entrådade miljöer eller prototypmiljöer. För bättre prestanda och trådsäkerhet i produktionsmiljöer använder du PredictionEnginePool tjänsten, som skapar ett ObjectPool objekt PredictionEngine för användning i hela programmet. Se den här guiden om hur du använder PredictionEnginePool i ett ASP.NET Core webb-API.

Anteckning

PredictionEnginePool tjänsttillägget är för närvarande i förhandsversion.

PredictionEngine Använd för att förutsäga Area GitHub-etiketten genom att lägga till följande kod i PredictIssue metoden för förutsägelsen:

var prediction = _predEngine.Predict(singleIssue);

Använd den inlästa modellen för förutsägelse

Visa Area för att kategorisera problemet och agera på det. Skapa en visning för resultaten med hjälp av följande Console.WriteLine() kod:

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

Resultat

Dina resultat bör likna följande. När pipelinen bearbetas visas meddelanden. Du kan se varningar eller bearbeta meddelanden. Dessa meddelanden har tagits bort från följande resultat för tydlighetens skull.

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

Grattis! Nu har du skapat en maskininlärningsmodell för att klassificera och förutsäga en områdesetikett för ett GitHub-problem. Du hittar källkoden för den här självstudien på lagringsplatsen dotnet/samples .

Nästa steg

I den här självstudiekursen lärde du dig att:

  • Förbereda dina data
  • Transformera data
  • Träna modellen
  • Utvärdera modellen
  • Förutsäga med den tränade modellen
  • Distribuera och förutsäga med en inläst modell

Gå vidare till nästa självstudie om du vill veta mer