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
- Visual Studio 2022 med arbetsbelastningen ".NET Desktop Development" installerad.
- Fliken GitHub-ärenden avgränsade filen (issues_train.tsv).
- Testfliken GitHub utfärdar en avgränsad fil (issues_test.tsv).
Skapa ett konsolprogram
Skapa ett projekt
Skapa ett C# -konsolprogram med namnet "GitHubIssueClassification". Välj Nästa.
Välj .NET 7 som ramverk att använda. Välj Skapa.
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.
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.
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
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.
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:
I Solution Explorer högerklickar du på projektet och väljer sedan Lägg till>nytt objekt.
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örstafeature
som används för att förutsägaArea
- den fjärde kolumnen
Description
är den andrafeature
som används för att förutsägaArea
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 PredictedLabel
ColumnName
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 DBContext
Entity 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 GitHubIssue
anvä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 BuildAndTrainModel
metoden 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