Tutoriel : Analyser les sentiments dans les commentaires des sites web à l’aide d’une classification binaire dans ML.NET
Ce tutoriel vous montre comment créer une application console .NET Core qui classifie les sentiments analysés dans les commentaires des sites web et qui exécute l’action appropriée. Le classifieur binaire de sentiments utilise C# dans Visual Studio 2022.
Dans ce tutoriel, vous allez apprendre à :
- Création d’une application console
- Préparer les données
- Chargement des données
- Générer et entraîner le modèle
- Évaluer le modèle
- Utiliser le modèle pour effectuer une prédiction
- Afficher les résultats
Vous trouverez le code source de ce tutoriel dans le référentiel dotnet/samples.
Prérequis
Création d’une application console
Créez une application console C# appelée « SentimentAnalysis ». Cliquez sur le bouton Suivant.
Choisissez .NET 6 comme infrastructure à utiliser. Cliquez sur le bouton Créer.
Créez un répertoire nommé Data dans votre projet pour enregistrer les fichiers du jeu de données.
Installez le package NuGet Microsoft.ML :
Notes
Cet exemple utilise la dernière version stable des packages NuGet mentionnés, sauf indication contraire.
Dans l'Explorateur de solutions, cliquez avec le bouton droit sur votre projet, puis sélectionnez Gérer les packages NuGet. Choisissez « nuget.org » comme source du package, sélectionnez l’onglet Parcourir. Recherchez Microsoft.ML, sélectionnez le package souhaité, puis sélectionnez le bouton Installer. Poursuivez l’installation en acceptant les termes du contrat de licence pour le package choisi.
Préparer vos données
Notes
Les jeux de données utilisés dans ce tutoriel proviennent de 'From Group to Individual Labels using Deep Features' (Kotzias et. al,. KDD 2015), hébergé dans le référentiel UCI Machine Learning (Dua, D. et Karra Taniskidou, E. (2017). Référentiel UCI Machine Learning [http://archive.ics.uci.edu/ml]. Irvine, CA: University of California, School of Information and Computer Science.
Téléchargez le fichier zip du jeu de données UCI Sentiment Labeled Sentences, puis décompressez-le.
Copiez le fichier
yelp_labelled.txt
dans le répertoire Données que vous avez créé.Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le fichier
yelp_labeled.txt
et sélectionnez Propriétés. Sous Avancé, définissez la valeur Copier dans le répertoire de sortie sur Copier si plus récent.
Créer des classes et définir des chemins
Ajoutez les instructions
using
supplémentaires suivantes en haut du fichier Program.cs :using Microsoft.ML; using Microsoft.ML.Data; using SentimentAnalysis; using static Microsoft.ML.DataOperationsCatalog;
Ajoutez le code suivant à la ligne située juste sous les instructions
using
pour créer un champ contenant le chemin d’accès du fichier de jeu de données récemment téléchargé :string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "yelp_labelled.txt");
Créez ensuite des classes pour les données d’entrée et les prédictions. Ajoutez une nouvelle classe à votre projet :
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet, puis sélectionnez Ajouter>Nouvel élément.
Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez Classe, puis remplacez la valeur du champ Nom par SentimentData.cs. Ensuite, sélectionnez le bouton Ajouter.
Le fichier SentimentData.cs s’ouvre dans l’éditeur de code. Ajoutez l'instruction suivante
using
en haut du fichier SentimentData.cs :using Microsoft.ML.Data;
Supprimez la définition de classe existante et ajoutez le code suivant, qui contient deux classes,
SentimentData
etSentimentPrediction
, au fichier 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; } }
Comment les données ont-elles été préparées ?
La classe du jeu de données d’entrée, SentimentData
, a une valeur string
pour les commentaires utilisateur (SentimentText
) et une valeur bool
(Sentiment
) égale à 1 (sentiment positif) ou 0 (sentiment négatif). Les deux champs ont des attributs LoadColumn associés, qui spécifient l’ordre du fichier de données de chaque champ. Par ailleurs, la propriété Sentiment
a un attribut ColumnName qui la désigne comme champ Label
. L’exemple de fichier suivant ne possède pas de ligne d’en-tête :
SentimentText | Sentiment (Label) |
---|---|
La serveuse était un peu lente durant le service. | 0 |
La pâte n’est pas bonne. | 0 |
Waouh... J’ai adoré cet endroit. | 1 |
Le service a été très rapide. | 1 |
SentimentPrediction
est la classe de prédiction utilisée après l’entraînement du modèle. Elle hérite de SentimentData
afin que l’entrée SentimentText
puisse être affichée en même temps que la prédiction de sortie. La valeur booléenne Prediction
est la valeur que le modèle prédit quand la nouvelle entrée SentimentText
lui est fournie.
La classe de sortie SentimentPrediction
contient deux autres propriétés calculées par le modèle : Score
, le score brut calculé par le modèle, et Probability
, le score étalonné à la probabilité que le texte ait un sentiment positif.
Pour ce tutoriel, la propriété la plus importante est Prediction
.
Chargement des données
Les données dans ML.NET sont représentées en tant qu’interface IDataView. IDataView
est un moyen flexible et efficace de décrire des données tabulaires (numériques et texte). Les données peuvent être chargées à partir d’un fichier texte ou en temps réel (par exemple, fichiers journaux ou de base de données SQL) dans un objet IDataView
.
La classe MLContext constitue un point de départ pour toutes les opérations ML.NET. L’initialisation de mlContext
crée un environnement ML.NET qui peut être partagé par les objets du workflow de création de modèle. Sur le plan conceptuel, elle est similaire à DBContext
dans Entity Framework.
Vous préparez l’application et chargez ensuite les données :
Remplacez la ligne
Console.WriteLine("Hello World!")
par le code suivant pour déclarer et initialiser la variable mlContext :MLContext mlContext = new MLContext();
Ajoutez le code suivant comme prochaine ligne de code :
TrainTestData splitDataView = LoadData(mlContext);
Créez une méthode
LoadData()
en bas du fichierProgram.cs
à l’aide du code suivant :TrainTestData LoadData(MLContext mlContext) { }
La méthode
LoadData()
exécute les tâches suivantes :- Charge les données.
- Fractionne le jeu de données chargé en jeux de données d’apprentissage et de test.
- Retourne les jeux de données d’apprentissage et de test fractionnés.
Ajoutez le code suivant comme première ligne de la méthode
LoadData()
:IDataView dataView = mlContext.Data.LoadFromTextFile<SentimentData>(_dataPath, hasHeader: false);
La méthode LoadFromTextFile() définit le schéma de données et lit le fichier. Elle prend les variables de chemin de données et retourne un
IDataView
.
Fractionner le jeu de données pour l’apprentissage et le test du modèle
Quand vous préparez un modèle, vous utilisez une partie du jeu de données pour entraîner le modèle et une partie du jeu de données pour tester la précision du modèle.
Pour fractionner les données chargées dans les jeux de données nécessaires, ajoutez le code suivant sur la ligne suivant la méthode
LoadData()
:TrainTestData splitDataView = mlContext.Data.TrainTestSplit(dataView, testFraction: 0.2);
Le code précédent utilise la méthode TrainTestSplit() pour diviser le jeu de données chargé en deux jeux de données d’apprentissage et de test, et les retourner dans la classe DataOperationsCatalog.TrainTestData. Spécifiez le pourcentage de données du jeu de test avec le paramètre
testFraction
. La valeur par défaut est 10 %, mais dans cet exemple, vous spécifiez 20 % pour évaluer davantage de données.Retournez
splitDataView
à la fin de la méthodeLoadData()
:return splitDataView;
Générer et entraîner le modèle
Ajoutez l’appel suivant à la méthode
BuildAndTrainModel
sous l’appel à la méthodeLoadData
:ITransformer model = BuildAndTrainModel(mlContext, splitDataView.TrainSet);
La méthode
BuildAndTrainModel()
exécute les tâches suivantes :- Extrait et transforme les données.
- Effectue l’apprentissage du modèle.
- Prédit les sentiments en fonction des données de test.
- Retourne le modèle.
Créez la méthode
BuildAndTrainModel()
sous la méthodeLoadData()
, en utilisant le code suivant :ITransformer BuildAndTrainModel(MLContext mlContext, IDataView splitTrainSet) { }
Extraire et transformer les données
Appelez
FeaturizeText
sur la ligne de code suivante :var estimator = mlContext.Transforms.Text.FeaturizeText(outputColumnName: "Features", inputColumnName: nameof(SentimentData.SentimentText))
La méthode
FeaturizeText()
dans le code précédent convertit la colonne de texte (SentimentText
) en une colonneFeatures
de type clé numérique, qui est utilisée par l’algorithme de machine learning, et l’ajoute comme nouvelle colonne au jeu de données :SentimentText Sentiments Fonctionnalités La serveuse était un peu lente durant le service. 0 [0.76, 0.65, 0.44, …] La pâte n’est pas bonne. 0 [0.98, 0.43, 0.54, …] Waouh... J’ai adoré cet endroit. 1 [0.35, 0.73, 0.46, …] Le service a été très rapide. 1 [0.39, 0, 0.75, …]
Ajouter un algorithme d’apprentissage
Cette application utilise un algorithme de classification qui classe les éléments ou lignes de données. Elle classe les commentaires des sites web comme positifs ou négatifs. Vous devez donc utiliser la tâche de classification binaire.
Ajoutez la tâche de machine learning aux définitions de transformations des données en ajoutant la ligne de code suivante dans BuildAndTrainModel()
:
.Append(mlContext.BinaryClassification.Trainers.SdcaLogisticRegression(labelColumnName: "Label", featureColumnName: "Features"));
SdcaLogisticRegressionBinaryTrainer est votre algorithme d’entraînement de classification. Il est ajouté à estimator
et accepte les caractéristiques SentimentText
(Features
) ainsi que les paramètres d’entrée Label
pour apprendre à partir des données d’historique.
Entraîner le modèle
Ajustez le modèle aux données splitTrainSet
et retournez le modèle entraîné en ajoutant la ligne de code suivante dans la méthode BuildAndTrainModel()
:
Console.WriteLine("=============== Create and Train the Model ===============");
var model = estimator.Fit(splitTrainSet);
Console.WriteLine("=============== End of training ===============");
Console.WriteLine();
La méthode Fit() entraîne votre modèle en transformant le jeu de données et en appliquant l’entraînement.
Retourner le modèle entraîné à utiliser pour l’évaluation
Retournez le modèle à la fin de la méthode BuildAndTrainModel()
:
return model;
Évaluer le modèle
Une fois que votre modèle est formé, vérifiez ses performances avec vos données de test.
Créez la méthode
Evaluate()
juste aprèsBuildAndTrainModel()
, en utilisant le code suivant :void Evaluate(MLContext mlContext, ITransformer model, IDataView splitTestSet) { }
La méthode
Evaluate()
exécute les tâches suivantes :- Charge le jeu de données de test.
- Crée l’évaluateur BinaryClassification.
- Évalue le modèle et crée des métriques.
- Affiche les métriques.
Ajoutez un appel à la nouvelle méthode sous l’appel de la méthode
BuildAndTrainModel
, en utilisant le code suivant :Evaluate(mlContext, model, splitDataView.TestSet);
Transformez les données
splitTestSet
en ajoutant le code suivant àEvaluate()
:Console.WriteLine("=============== Evaluating Model accuracy with Test data==============="); IDataView predictions = model.Transform(splitTestSet);
Le code précédent utilise la méthode Transform() pour prédire plusieurs lignes d’entrée d’un jeu de données de test.
Évaluez le modèle en ajoutant la ligne de code suivante dans la méthode
Evaluate()
:CalibratedBinaryClassificationMetrics metrics = mlContext.BinaryClassification.Evaluate(predictions, "Label");
Une fois que vous avez le jeu de prédiction (predictions
), la méthode Evaluate() évalue le modèle : elle compare les valeurs prédites aux valeurs Labels
réelles dans le jeu de données de test et retourne un objet CalibratedBinaryClassificationMetrics contenant les métriques relatives aux performances du modèle.
Affichage des métriques pour la validation du modèle
Utilisez le code suivant pour afficher les métriques :
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 ===============");
La métrique
Accuracy
donne la précision du modèle, qui correspond à la proportion de prédictions correctes dans le jeu de test.La métrique
AreaUnderRocCurve
indique le degré de confiance conféré aux résultats de la classification des classes positif/négatif. Vous voulez que la métriqueAreaUnderRocCurve
soit le plus proche possible de la valeur 1.La métrique
F1Score
donne le score F1 du modèle, qui mesure l’équilibre entre la précision et le rappel. Vous voulez que la métriqueF1Score
soit le plus proche possible de la valeur 1.
Prédire les résultats des données de test
Créez la méthode
UseModelWithSingleItem()
juste après la méthodeEvaluate()
, en utilisant le code suivant :void UseModelWithSingleItem(MLContext mlContext, ITransformer model) { }
La méthode
UseModelWithSingleItem()
exécute les tâches suivantes :- Crée un commentaire unique de données de test.
- Prédit les sentiments en fonction des données de test.
- Combine les données de test et les prédictions pour générer des rapports.
- Affiche les résultats prédits.
Ajoutez un appel à la nouvelle méthode juste en dessous de l’appel de la méthode
Evaluate()
, en utilisant le code suivant :UseModelWithSingleItem(mlContext, model);
Ajoutez le code suivant comme première ligne dans la méthode
UseModelWithSingleItem()
:PredictionEngine<SentimentData, SentimentPrediction> predictionFunction = mlContext.Model.CreatePredictionEngine<SentimentData, SentimentPrediction>(model);
PredictionEngine est une API pratique qui vous permet d’effectuer une prédiction sur une seule instance de données.
PredictionEngine
n’est pas thread-safe. Il est acceptable de l’utiliser dans des environnements monothreads ou de prototype. Pour améliorer les performances et la sécurité des threads dans les environnements de production, utilisez le servicePredictionEnginePool
, qui crée unObjectPool
d’objetsPredictionEngine
à utiliser dans votre application. Consultez ce guide sur l’utilisation dePredictionEnginePool
dans une API web ASP.NET Core.Notes
L’extension de service
PredictionEnginePool
est disponible en préversion.Ajoutez un commentaire pour tester la prédiction du modèle formé dans la méthode
UseModelWithSingleItem()
en créant une instance deSentimentData
:SentimentData sampleStatement = new SentimentData { SentimentText = "This was a very bad steak" };
Passez les données de commentaire de test à
PredictionEngine
en ajoutant les lignes de code suivantes dans la méthodeUseModelWithSingleItem()
:var resultPrediction = predictionFunction.Predict(sampleStatement);
La fonction Predict() effectue une prédiction sur une seule ligne de données.
Affichez
SentimentText
et la prédiction de sentiment correspondante en utilisant le code suivant :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();
Utiliser le modèle pour la prédiction
Déployer et prédire des éléments par lots
Créez la méthode
UseModelWithBatchItems()
juste après la méthodeUseModelWithSingleItem()
, en utilisant le code suivant :void UseModelWithBatchItems(MLContext mlContext, ITransformer model) { }
La méthode
UseModelWithBatchItems()
exécute les tâches suivantes :- Crée les données de test par lots.
- Prédit les sentiments en fonction des données de test.
- Combine les données de test et les prédictions pour générer des rapports.
- Affiche les résultats prédits.
Ajoutez un appel à la nouvelle méthode juste en dessous de l’appel de la méthode
UseModelWithSingleItem()
, en utilisant le code suivant :UseModelWithBatchItems(mlContext, model);
Ajoutez des commentaires pour tester les prédictions du modèle formé dans la méthode
UseModelWithBatchItems()
:IEnumerable<SentimentData> sentiments = new[] { new SentimentData { SentimentText = "This was a horrible meal" }, new SentimentData { SentimentText = "I love this spaghetti." } };
Prédire le sentiment de commentaire
Utilisez le modèle pour prédire le sentiment de données de commentaire à l’aide de la méthode 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);
Combiner et afficher les prédictions
Créez un en-tête des prédictions à l’aide du code suivant :
Console.WriteLine();
Console.WriteLine("=============== Prediction Test of loaded model with multiple samples ===============");
Comme SentimentPrediction
est hérité de SentimentData
, la méthode Transform()
a rempli SentimentText
avec les champs prédits. À mesure que le processus ML.NET progresse, chaque composant ajoute des colonnes, ce qui rend l’affichage des résultats plus facile :
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 ===============");
Résultats
Vos résultats doivent être similaires à ce qui suit. Durant le processus, des messages sont affichés. Vous pouvez voir des avertissements ou des messages de traitement. Ils ont été supprimés des résultats ci-dessous par souci de clarté.
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 . . .
Félicitations ! Vous venez de créer un modèle d’apprentissage automatique pour la classification et la prédiction des sentiments de messages.
La création de modèles efficaces est un processus itératif. Celui-ci présente une qualité initiale médiocre, car le tutoriel utilise de petits jeux de données pour permettre un apprentissage rapide du modèle. Si vous n’êtes pas satisfait de la qualité du modèle, essayez de l’améliorer en fournissant de plus gros jeux de données d’entraînement ou en choisissant d’autres algorithmes d’entraînement avec des hyperparamètres différents pour chacun.
Vous trouverez le code source de ce tutoriel dans le référentiel dotnet/samples.
Étapes suivantes
Dans ce didacticiel, vous avez appris à :
- Création d’une application console
- Préparer les données
- Chargement des données
- Générer et entraîner le modèle
- Évaluer le modèle
- Utiliser le modèle pour effectuer une prédiction
- Afficher les résultats
Passer au tutoriel suivant pour en savoir plus