Dela via


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

  1. Skapa ett C# -konsolprogram med namnet "SentimentAnalysis". Klicka på knappen Nästa.

  2. Välj .NET 6 som ramverk att använda. Klicka på knappen Skapa.

  3. Skapa en katalog med namnet Data i projektet för att spara datamängdsfilerna.

  4. 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.

  1. Ladda ned ZIP-filen med UCI Sentiment Labeled Sentences-datauppsättningen och packa upp.

  2. yelp_labelled.txt Kopiera filen till den datakatalog som du skapade.

  3. 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

  1. 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;
    
  2. 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");
    
  3. 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 .

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

    using Microsoft.ML.Data;
    
  5. Ta bort den befintliga klassdefinitionen och lägg till följande kod, som har två klasser SentimentData och SentimentPrediction, 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 Predictionden 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:

  1. Console.WriteLine("Hello World!") Ersätt raden med följande kod för att deklarera och initiera variabeln mlContext:

    MLContext mlContext = new MLContext();
    
  2. Lägg till följande som nästa kodrad:

    TrainTestData splitDataView = LoadData(mlContext);
    
  3. Skapa en LoadData() metod längst ned i Program.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.
  4. 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.

  1. 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.

  2. splitDataView Returnera i slutet av LoadData() metoden:

    return splitDataView;
    

Skapa och träna modellen

  1. Lägg till följande anrop till BuildAndTrainModelmetoden under anropet LoadData 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.
  2. BuildAndTrainModel() Skapa metoden under LoadData() metoden med hjälp av följande kod:

    ITransformer BuildAndTrainModel(MLContext mlContext, IDataView splitTrainSet)
    {
    
    }
    

Extrahera och transformera data

  1. 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 nyckeltyp Features 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.

  1. Evaluate() Skapa -metoden, strax efter BuildAndTrainModel(), 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.
  2. Lägg till ett anrop till den nya metoden under metodanropet BuildAndTrainModel med hjälp av följande kod:

    Evaluate(mlContext, model, splitDataView.TestSet);
    
  3. Transformera splitTestSet data genom att lägga till följande kod i Evaluate():

    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.

  4. 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 ska AreaUnderRocCurve 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 ska F1Score vara så nära en som möjligt.

Förutsäga testdataresultatet

  1. UseModelWithSingleItem() Skapa -metoden, precis efter Evaluate() -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.
  2. Lägg till ett anrop till den nya metoden direkt under metodanropet Evaluate() med hjälp av följande kod:

    UseModelWithSingleItem(mlContext, model);
    
  3. 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 du PredictionEnginePool tjänsten, som skapar en ObjectPool av PredictionEngine objekt som ska användas 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.

  4. Lägg till en kommentar för att testa den tränade modellens förutsägelse i UseModelWithSingleItem() metoden genom att skapa en instans av SentimentData:

    SentimentData sampleStatement = new SentimentData
    {
        SentimentText = "This was a very bad steak"
    };
    
  5. Skicka testkommentardata till genom att lägga till PredictionEngine följande som nästa kodrader i UseModelWithSingleItem() metoden :

    var resultPrediction = predictionFunction.Predict(sampleStatement);
    

    Funktionen Predict() gör en förutsägelse på en enda rad med data.

  6. 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

  1. UseModelWithBatchItems() Skapa -metoden, precis efter UseModelWithSingleItem() -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.
  2. Lägg till ett anrop till den nya metoden direkt under metodanropet UseModelWithSingleItem() med hjälp av följande kod:

    UseModelWithBatchItems(mlContext, model);
    
  3. 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 SentimentDataTransform() 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