Självstudie: Analysera sentiment för webbplatskommentarer med binär klassificering i ML.NET
Den här självstudien visar hur du skapar ett .NET Core-konsolprogram som klassificerar sentiment från webbplatskommentarer och vidtar lämpliga åtgärder. Klassificeraren för binär sentiment använder C# i Visual Studio 2022.
I den här guiden får du lära dig att:
- Skapa ett konsolprogram
- Förbereda data
- Läsa in data
- Skapa och träna modellen
- Utvärdera modellen
- Använda modellen för att göra en förutsägelse
- Visa resultaten
Du hittar källkoden för den här självstudien på lagringsplatsen dotnet/samples .
Krav
Skapa ett konsolprogram
Skapa ett C# -konsolprogram med namnet "SentimentAnalysis". Klicka på knappen Nästa.
Välj .NET 6 som ramverk att använda. Klicka på knappen Skapa.
Skapa en katalog med namnet Data i projektet för att spara datamängdsfilerna.
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 och välj sedan fliken Bläddra . Sök efter Microsoft.ML, välj önskat paket och välj sedan knappen Installera . Fortsätt med installationen genom att godkänna licensvillkoren för det paket du väljer.
Förbereda dina data
Anteckning
Datauppsättningarna för den här självstudien kommer från "Från grupp till enskilda etiketter med djupa funktioner", Kotzias et. Al. KDD 2015 och värdhanteras på UCI Machine Learning Repository - Dua, D. och Karra Taniskidou, E. (2017). UCI Machine Learning-lagringsplats [http://archive.ics.uci.edu/ml]. Irvine, CA: University of California, School of Information and Computer Science.
Ladda ned ZIP-filen med UCI Sentiment Labeled Sentences-datauppsättningen och packa upp.
yelp_labelled.txt
Kopiera filen till den datakatalog som du skapade.I Solution Explorer högerklickar du på
yelp_labeled.txt
filen 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 Microsoft.ML.Data; using SentimentAnalysis; using static Microsoft.ML.DataOperationsCatalog;
Lägg till följande kod på raden precis under
using
-instruktionerna för att skapa ett fält som innehåller sökvägen till den nyligen nedladdade datauppsättningsfilen:string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "yelp_labelled.txt");
Skapa sedan 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 SentimentData.cs. Välj sedan knappen Lägg till .
Filen SentimentData.cs öppnas i kodredigeraren. Lägg till följande
using
-instruktion överst i SentimentData.cs:using Microsoft.ML.Data;
Ta bort den befintliga klassdefinitionen och lägg till följande kod, som har två klasser
SentimentData
ochSentimentPrediction
, i filen 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; } }
Hur data förbereddes
Indatamängdsklassen, SentimentData
, har ett string
för användarkommenterar (SentimentText
) och ett bool
(Sentiment
) värde på antingen 1 (positiv) eller 0 (negativ) för sentiment. Båda fälten har LoadColumn-attribut kopplade till sig, som beskriver datafilordningen för varje fält. Dessutom Sentiment
har egenskapen ett ColumnName-attribut som anger det som Label
fält. Följande exempelfil har ingen rubrikrad och ser ut så här:
SentimentText | Sentiment (etikett) |
---|---|
Servitrisen var lite långsam i tjänsten. | 0 |
Skorpan är inte bra. | 0 |
Wow... Älskade det här stället. | 1 |
Tjänsten var mycket snabb. | 1 |
SentimentPrediction
är förutsägelseklassen som används efter modellträningen. Den ärver från SentimentData
så att indata SentimentText
kan visas tillsammans med utdataförutsägelsen. Det Prediction
booleska värdet är det värde som modellen förutsäger när den levereras med nya indata SentimentText
.
Utdataklassen SentimentPrediction
innehåller två andra egenskaper som beräknas av modellen: Score
- den råpoäng som beräknas av modellen och Probability
- poängen kalibrerad för sannolikheten för att texten har positiv attityd.
I den här självstudien är Prediction
den viktigaste egenskapen .
Läsa in data
Data i ML.NET representeras som ett IDataView-gränssnitt. IDataView
är ett flexibelt och effektivt sätt att beskriva tabelldata (numeriska data och text). Data kan läsas in från en textfil eller i realtid (till exempel SQL-databas eller loggfiler) till ett IDataView
objekt.
KLASSEN MLContext är en startpunkt för alla ML.NET åtgärder. När du initierar mlContext
skapas en ny ML.NET miljö som kan delas mellan arbetsflödesobjekten för modellskapande. Det liknar begreppsmässigt DBContext
i Entity Framework.
Du förbereder appen och läser sedan in data:
Console.WriteLine("Hello World!")
Ersätt raden med följande kod för att deklarera och initiera variabeln mlContext:MLContext mlContext = new MLContext();
Lägg till följande som nästa kodrad:
TrainTestData splitDataView = LoadData(mlContext);
Skapa en
LoadData()
metod längst ned iProgram.cs
filen med hjälp av följande kod:TrainTestData LoadData(MLContext mlContext) { }
Metoden
LoadData()
kör följande uppgifter:- Läser in data.
- Delar upp den inlästa datamängden i tränings- och testdatauppsättningar.
- Returnerar datauppsättningarna split train och test.
Lägg till följande kod som den första raden i
LoadData()
metoden:IDataView dataView = mlContext.Data.LoadFromTextFile<SentimentData>(_dataPath, hasHeader: false);
Metoden LoadFromTextFile() definierar dataschemat och läser i filen. Den tar in datasökvägsvariablerna och returnerar en
IDataView
.
Dela upp datauppsättningen för modellträning och testning
När du förbereder en modell använder du en del av datamängden för att träna den och en del av datauppsättningen för att testa modellens noggrannhet.
Om du vill dela upp inlästa data i de datauppsättningar som behövs lägger du till följande kod som nästa rad i
LoadData()
metoden :TrainTestData splitDataView = mlContext.Data.TrainTestSplit(dataView, testFraction: 0.2);
Den tidigare koden använder metoden TrainTestSplit() för att dela upp den inlästa datamängden i tränings- och testdatauppsättningar och returnera dem i DataOperationsCatalog.TrainTestData klassen . Ange testuppsättningens procentandel av data med parametern
testFraction
. Standardvärdet är 10 %, i det här fallet använder du 20 % för att utvärdera mer data.splitDataView
Returnera i slutet avLoadData()
metoden:return splitDataView;
Skapa och träna modellen
Lägg till följande anrop till
BuildAndTrainModel
metoden under anropetLoadData
till metoden :ITransformer model = BuildAndTrainModel(mlContext, splitDataView.TrainSet);
Metoden
BuildAndTrainModel()
kör följande uppgifter:- Extraherar och transformerar data.
- Tränar modellen.
- Förutsäger sentiment baserat på testdata.
- Returnerar modellen.
BuildAndTrainModel()
Skapa metoden underLoadData()
metoden med hjälp av följande kod:ITransformer BuildAndTrainModel(MLContext mlContext, IDataView splitTrainSet) { }
Extrahera och transformera data
Anropa
FeaturizeText
som nästa kodrad:var estimator = mlContext.Transforms.Text.FeaturizeText(outputColumnName: "Features", inputColumnName: nameof(SentimentData.SentimentText))
Metoden
FeaturizeText()
i föregående kod konverterar textkolumnen (SentimentText
) till en kolumn av numerisk nyckeltypFeatures
som används av maskininlärningsalgoritmen och lägger till den som en ny datauppsättningskolumn:SentimentText Sentiment Funktioner Servitrisen var lite långsam i tjänsten. 0 [0.76, 0.65, 0.44, ...] Skorpan är inte bra. 0 [0.98, 0.43, 0.54, ...] Wow... Älskade det här stället. 1 [0.35, 0.73, 0.46, ...] Tjänsten var mycket snabb. 1 [0.39, 0, 0.75, ...]
Lägga till en inlärningsalgoritm
Den här appen använder en klassificeringsalgoritm som kategoriserar objekt eller rader med data. Appen kategoriserar webbplatskommentarna som antingen positiva eller negativa, så använd den binära klassificeringsuppgiften.
Lägg till maskininlärningsaktiviteten i definitionerna för datatransformering genom att lägga till följande som nästa kodrad i BuildAndTrainModel()
:
.Append(mlContext.BinaryClassification.Trainers.SdcaLogisticRegression(labelColumnName: "Label", featureColumnName: "Features"));
SdcaLogisticRegressionBinaryTrainer är din klassificeringsträningsalgoritm. Detta läggs till estimator
i och accepterar de funktionaliserade SentimentText
(Features
) och indataparametrarna Label
för att lära sig 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 :
Console.WriteLine("=============== Create and Train the Model ===============");
var model = estimator.Fit(splitTrainSet);
Console.WriteLine("=============== End of training ===============");
Console.WriteLine();
Metoden Fit() tränar din modell genom att transformera datauppsättningen och tillämpa träningen.
Returnera den modell som tränats att använda för utvärdering
Returnera modellen i slutet av BuildAndTrainModel()
metoden:
return model;
Utvärdera modellen
När modellen har tränats använder du dina testdata för att verifiera modellens prestanda.
Evaluate()
Skapa -metoden, strax efterBuildAndTrainModel()
, med följande kod:void Evaluate(MLContext mlContext, ITransformer model, IDataView splitTestSet) { }
Metoden
Evaluate()
kör följande uppgifter:- Läser in testdatamängden.
- Skapar utvärderaren BinaryClassification.
- Utvärderar modellen och skapar mått.
- Visar måtten.
Lägg till ett anrop till den nya metoden under metodanropet
BuildAndTrainModel
med hjälp av följande kod:Evaluate(mlContext, model, splitDataView.TestSet);
Transformera
splitTestSet
data genom att lägga till följande kod iEvaluate()
:Console.WriteLine("=============== Evaluating Model accuracy with Test data==============="); IDataView predictions = model.Transform(splitTestSet);
I föregående kod används metoden Transform() för att göra förutsägelser för flera angivna indatarader i en testdatauppsättning.
Utvärdera modellen genom att lägga till följande som nästa kodrad i
Evaluate()
metoden :CalibratedBinaryClassificationMetrics metrics = mlContext.BinaryClassification.Evaluate(predictions, "Label");
När du har prediktionsuppsättningen (predictions
) utvärderar metoden Evaluate() modellen, som jämför de förutsagda värdena med det faktiska Labels
i testdatauppsättningen och returnerar ett CalibratedBinaryClassificationMetrics-objekt om hur modellen fungerar.
Visa mått för modellvalidering
Använd följande kod för att visa måtten:
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 ===============");
Måttet
Accuracy
hämtar noggrannheten för en modell, vilket är andelen korrekta förutsägelser i testuppsättningen.Måttet
AreaUnderRocCurve
anger hur säker modellen klassificerar de positiva och negativa klasserna korrekt. Du vill att skaAreaUnderRocCurve
vara så nära en som möjligt.Måttet
F1Score
hämtar modellens F1-poäng, vilket är ett mått på balansen mellan precision och träffsäkerhet. Du vill att skaF1Score
vara så nära en som möjligt.
Förutsäga testdataresultatet
UseModelWithSingleItem()
Skapa -metoden, precis efterEvaluate()
-metoden, med hjälp av följande kod:void UseModelWithSingleItem(MLContext mlContext, ITransformer model) { }
Metoden
UseModelWithSingleItem()
kör följande uppgifter:- Skapar en enskild kommentar med testdata.
- Förutsäger sentiment baserat på testdata.
- Kombinerar testdata och förutsägelser för rapportering.
- Visar de förutsagda resultaten.
Lägg till ett anrop till den nya metoden direkt under metodanropet
Evaluate()
med hjälp av följande kod:UseModelWithSingleItem(mlContext, model);
Lägg till följande kod för att skapa som den första raden i
UseModelWithSingleItem()
metoden :PredictionEngine<SentimentData, SentimentPrediction> predictionFunction = mlContext.Model.CreatePredictionEngine<SentimentData, SentimentPrediction>(model);
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 duPredictionEnginePool
tjänsten, som skapar enObjectPool
avPredictionEngine
objekt som ska användas i hela programmet. Se den här guiden om hur du använderPredictionEnginePool
i ett ASP.NET Core webb-API.Anteckning
PredictionEnginePool
tjänsttillägget är för närvarande i förhandsversion.Lägg till en kommentar för att testa den tränade modellens förutsägelse i
UseModelWithSingleItem()
metoden genom att skapa en instans avSentimentData
:SentimentData sampleStatement = new SentimentData { SentimentText = "This was a very bad steak" };
Skicka testkommentardata till genom att lägga till
PredictionEngine
följande som nästa kodrader iUseModelWithSingleItem()
metoden :var resultPrediction = predictionFunction.Predict(sampleStatement);
Funktionen Predict() gör en förutsägelse på en enda rad med data.
Visa
SentimentText
och motsvarande attitydförutsägelse med hjälp av följande kod: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();
Använda modellen för förutsägelse
Distribuera och förutsäga batchobjekt
UseModelWithBatchItems()
Skapa -metoden, precis efterUseModelWithSingleItem()
-metoden, med hjälp av följande kod:void UseModelWithBatchItems(MLContext mlContext, ITransformer model) { }
Metoden
UseModelWithBatchItems()
kör följande uppgifter:- Skapar batchtestdata.
- Förutsäger sentiment baserat på testdata.
- Kombinerar testdata och förutsägelser för rapportering.
- Visar de förutsagda resultaten.
Lägg till ett anrop till den nya metoden direkt under metodanropet
UseModelWithSingleItem()
med hjälp av följande kod:UseModelWithBatchItems(mlContext, model);
Lägg till några kommentarer för att testa den tränade modellens förutsägelser i
UseModelWithBatchItems()
metoden :IEnumerable<SentimentData> sentiments = new[] { new SentimentData { SentimentText = "This was a horrible meal" }, new SentimentData { SentimentText = "I love this spaghetti." } };
Förutsäga kommentarssentiment
Använd modellen för att förutsäga kommentarsdatasentimentet med hjälp av metoden 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);
Kombinera och visa förutsägelserna
Skapa en rubrik för förutsägelserna med hjälp av följande kod:
Console.WriteLine();
Console.WriteLine("=============== Prediction Test of loaded model with multiple samples ===============");
Eftersom SentimentPrediction
ärvs från SentimentData
Transform()
fylls metoden i med de förutsagda SentimentText
fälten. När ML.NET processer lägger varje komponent till kolumner, vilket gör det enkelt att visa resultatet:
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 ===============");
Resultat
Resultatet bör se ut ungefär så här. Under bearbetningen visas meddelanden. Du kan se varningar eller bearbeta meddelanden. Dessa har tagits bort från följande resultat för tydlighetens skull.
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 . . .
Grattis! Nu har du skapat en maskininlärningsmodell för att klassificera och förutsäga meddelandens sentiment.
Att skapa lyckade modeller är en iterativ process. Den här modellen har initial lägre kvalitet eftersom självstudien använder små datamängder för att tillhandahålla snabb modellträning. Om du inte är nöjd med modellkvaliteten kan du försöka förbättra den genom att tillhandahålla större träningsdatamängder eller genom att välja olika träningsalgoritmer med olika hyperparametrar för varje algoritm.
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:
- Skapa ett konsolprogram
- Förbereda data
- Läsa in data
- Skapa och träna modellen
- Utvärdera modellen
- Använda modellen för att göra en förutsägelse
- Visa resultaten
Gå vidare till nästa självstudie om du vill veta mer