Tutoriel : Analyser les sentiments des critiques de films en utilisant un modèle TensorFlow préentraîné dans ML.NET
Ce tutoriel vous montre comment utiliser un modèle TensorFlow préentraîné pour classifier les sentiments dans les commentaires d’un site web. Le classifieur de sentiments binaires est une application console C# développée en utilisant Visual Studio.
Le modèle TensorFlow utilisé dans ce tutoriel a été entraîné en utilisant des évaluations de films provenant de la base de données IMDB. Une fois que vous avez terminé le développement de l’application, vous pourrez fournir un texte d’évaluation d’un film et l’application vous indiquera si cette évaluation a un sentiment positif ou négatif.
Dans ce tutoriel, vous allez apprendre à :
- Charger un modèle TensorFlow préentraîné
- Transformer le texte des commentaires d’un site web en caractéristiques convenant au modèle
- Utiliser le modèle pour effectuer une prédiction
Vous trouverez le code source de ce tutoriel dans le référentiel dotnet/samples.
Prérequis
- Visual Studio 2022 avec la charge de travail « Développement .NET Desktop » installée.
Programme d’installation
Création de l'application
Créez une application console C# appelée « TextClassificationTF ». Cliquez sur le bouton Suivant.
Choisissez .NET 6 comme framework à 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. Répétez ces étapes pour Microsoft.ML.TensorFlow, Microsoft.ML.SampleUtils et SciSharp.TensorFlow.Redist.
Ajouter le modèle TensorFlow au projet
Notes
Le modèle pour ce tutoriel provient du dépôt GitHub dotnet/machinelearning-testdata. Le modèle est au format TensorFlow SavedModel.
Téléchargez le fichier zip sentiment_model, puis décompressez-le.
Le fichier .zip contient :
saved_model.pb
: le modèle TensorFlow lui-même. Le modèle prend un tableau d’entiers de longueur fixe (taille de 600) de caractéristiques représentant le texte dans une chaîne d’évaluation IMDB et génère deux probabilités dont la somme est égale à 1 : la probabilité que l’évaluation en entrée ait un sentiment positif et la probabilité que l’évaluation en entrée ait un sentiment négatif.imdb_word_index.csv
: un mappage de mots individuels à une valeur entière. Le mappage est utilisé pour générer les caractéristiques d’entrée pour le modèle TensorFlow.
Copiez le contenu du répertoire
sentiment_model
le plus interne dans le répertoiresentiment_model
de votre projet TextClassificationTF. Ce répertoire contient le modèle et les fichiers d’aide supplémentaires nécessaires à ce tutoriel, comme le montre l’image suivante :Dans l’Explorateur de solutions, cliquez avec le bouton droit sur chacun des fichiers du répertoire
sentiment_model
et des sous-répertoires, 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.
Ajouter des instructions using et des variables globales
Ajoutez les instructions
using
supplémentaires suivantes en haut du fichier Program.cs :using Microsoft.ML; using Microsoft.ML.Data; using Microsoft.ML.Transforms;
Créez une variable globale juste après les instructions using pour y placer le chemin du fichier de modèle enregistré.
string _modelPath = Path.Combine(Environment.CurrentDirectory, "sentiment_model");
_modelPath
est le chemin du fichier du modèle entraîné.
Modéliser les données
Les évaluations des films sont du texte de forme libre. Votre application convertit le texte au format d’entrée attendu par le modèle au cours de plusieurs étapes discrètes.
La première consiste à diviser le texte en mots distincts et à utiliser le fichier de mappage fourni pour mapper chaque mot à un code représenté par un entier. Le résultat de cette transformation est un tableau d’entiers de longueur variable, dont la longueur correspond au nombre de mots de la phrase.
Propriété | Valeur | Type |
---|---|---|
ReviewText | ce film est vraiment bon | string |
VariableLengthFeatures | 14,22,9,66,78,... | int[] |
Le tableau de caractéristiques de longueur variable est ensuite redimensionné avec une longueur fixe de 600. C’est la longueur attendue par le modèle TensorFlow.
Propriété | Valeur | Type |
---|---|---|
ReviewText | ce film est vraiment bon | string |
VariableLengthFeatures | 14,22,9,66,78,... | int[] |
Fonctionnalités | 14,22,9,66,78,... | int[600] |
Créez une classe pour vos données d’entrée dans le bas du fichier Program.cs :
/// <summary> /// Class to hold original sentiment data. /// </summary> public class MovieReview { public string? ReviewText { get; set; } }
La classe de données d’entrée,
MovieReview
, a unestring
pour les commentaires de l’utilisateur (ReviewText
).Créez une classe pour les caractéristiques de longueur variable après la classe
MovieReview
:/// <summary> /// Class to hold the variable length feature vector. Used to define the /// column names used as input to the custom mapping action. /// </summary> public class VariableLength { /// <summary> /// This is a variable length vector designated by VectorType attribute. /// Variable length vectors are produced by applying operations such as 'TokenizeWords' on strings /// resulting in vectors of tokens of variable lengths. /// </summary> [VectorType] public int[]? VariableLengthFeatures { get; set; } }
La propriété
VariableLengthFeatures
a un attribut VectorType pour la désigner comme vecteur. Tous les éléments du vecteur doivent être du même type. Dans les jeux de données comportant un grand nombre de colonnes, le chargement de plusieurs colonnes sous forme de vecteur unique réduit le nombre de passes dans les données quand vous appliquez des transformations de données.Cette classe est utilisée dans l’action
ResizeFeatures
. Les noms de ses propriétés (une seule dans le cas présent) sont utilisés pour indiquer les colonnes de la DataView qui peuvent être utilisées comme entrée dans l’action de mappage personnalisé.Créez une classe pour les caractéristiques de longueur fixe, après la classe
VariableLength
:/// <summary> /// Class to hold the fixed length feature vector. Used to define the /// column names used as output from the custom mapping action, /// </summary> public class FixedLength { /// <summary> /// This is a fixed length vector designated by VectorType attribute. /// </summary> [VectorType(Config.FeatureLength)] public int[]? Features { get; set; } }
Cette classe est utilisée dans l’action
ResizeFeatures
. Les noms de ses propriétés (une seule dans le cas présent) sont utilisés pour indiquer les colonnes de la DataView qui peuvent être utilisées comme sortie dans l’action de mappage personnalisé.Notez que le nom de la propriété
Features
est déterminé par le modèle TensorFlow. Vous ne pouvez pas changer le nom de cette propriété.Créez une classe pour la prédiction après la classe
FixedLength
:/// <summary> /// Class to contain the output values from the transformation. /// </summary> public class MovieReviewSentimentPrediction { [VectorType(2)] public float[]? Prediction { get; set; } }
MovieReviewSentimentPrediction
est la classe de prédiction utilisée après l’entraînement du modèle.MovieReviewSentimentPrediction
a un seul tableaufloat
(Prediction
) et un attributVectorType
.Créez une autre classe destinées à contenir des valeurs de configuration, comme la longueur du vecteur de caractéristiques :
static class Config { public const int FeatureLength = 600; }
Créer le MLContext, le dictionnaire de recherche et l’action pour redimensionner les caractéristiques
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.
Remplacez la ligne
Console.WriteLine("Hello World!")
par le code suivant pour déclarer et initialiser la variable mlContext :MLContext mlContext = new MLContext();
Créez un dictionnaire pour coder les mots sous forme d’entiers en utilisant la méthode
LoadFromTextFile
pour charger les données de mappage à partir d’un fichier, comme indiqué dans le tableau suivant :Word Index kids 362 vouloir 181 wrong (mauvais) 355 effects 302 feeling (sentiment) 547 Ajoutez le code ci-dessous pour créer le mappage de recherche :
var lookupMap = mlContext.Data.LoadFromTextFile(Path.Combine(_modelPath, "imdb_word_index.csv"), columns: new[] { new TextLoader.Column("Words", DataKind.String, 0), new TextLoader.Column("Ids", DataKind.Int32, 1), }, separatorChar: ',' );
Ajoutez une
Action
pour redimensionner le tableau d’entiers de longueur variable (représentant des mots) en un tableau d’entiers de taille fixe, avec les lignes de code suivantes :Action<VariableLength, FixedLength> ResizeFeaturesAction = (s, f) => { var features = s.VariableLengthFeatures; Array.Resize(ref features, Config.FeatureLength); f.Features = features; };
Charger le modèle TensorFlow préentraîné
Ajoutez du code pour charger le modèle TensorFlow :
TensorFlowModel tensorFlowModel = mlContext.Model.LoadTensorFlowModel(_modelPath);
Une fois le modèle chargé, vous pouvez extraire son schéma d’entrée et de sortie. Les schémas sont affichés seulement à titre d’information pour vous permettre de les découvrir. Vous n’avez pas besoin de ce code pour que l’application finale fonctionne :
DataViewSchema schema = tensorFlowModel.GetModelSchema(); Console.WriteLine(" =============== TensorFlow Model Schema =============== "); var featuresType = (VectorDataViewType)schema["Features"].Type; Console.WriteLine($"Name: Features, Type: {featuresType.ItemType.RawType}, Size: ({featuresType.Dimensions[0]})"); var predictionType = (VectorDataViewType)schema["Prediction/Softmax"].Type; Console.WriteLine($"Name: Prediction/Softmax, Type: {predictionType.ItemType.RawType}, Size: ({predictionType.Dimensions[0]})");
Le schéma d’entrée est le tableau de longueur fixe de mots codés en entiers. Le schéma de sortie est un tableau de nombres à virgule flottante de probabilités indiquant si le sentiment d’une évaluation est négatif ou positif. La somme de ces valeurs est égale à 1, car la probabilité que le sentiment soit positif est le complément de la probabilité que le sentiment soit négatif.
Créer le pipeline ML.NET
Créez le pipeline et fractionnez le texte d’entrée en mots en utilisant la transformation TokenizeIntoWords pour décomposer le texte en mots dans la ligne de code suivante :
IEstimator<ITransformer> pipeline = // Split the text into individual words mlContext.Transforms.Text.TokenizeIntoWords("TokenizedWords", "ReviewText")
La transformation TokenizeIntoWords utilise les espaces pour analyser le texte/la chaîne en mots. Il crée une colonne et fractionne chaque chaîne d’entrée en un vecteur de sous-chaînes en fonction du séparateur défini par l’utilisateur.
Mappez les mots à leur code sous forme d’entier en utilisant la table de recherche que vous avez déclarée plus haut :
// Map each word to an integer value. The array of integer makes up the input features. .Append(mlContext.Transforms.Conversion.MapValue("VariableLengthFeatures", lookupMap, lookupMap.Schema["Words"], lookupMap.Schema["Ids"], "TokenizedWords"))
Redimensionnez les codes sous forme d’entiers de longueur variable en un tableau de longueur fixe, qui est requis par le modèle :
// Resize variable length vector to fixed length vector. .Append(mlContext.Transforms.CustomMapping(ResizeFeaturesAction, "Resize"))
Classifiez l’entrée avec le modèle TensorFlow chargé :
// Passes the data to TensorFlow for scoring .Append(tensorFlowModel.ScoreTensorFlowModel("Prediction/Softmax", "Features"))
La sortie du modèle TensorFlow est appelée
Prediction/Softmax
. Notez que le nomPrediction/Softmax
est déterminé par le modèle TensorFlow. Vous ne pouvez pas changer ce nom.Créez une colonne pour la prédiction en sortie :
// Retrieves the 'Prediction' from TensorFlow and copies to a column .Append(mlContext.Transforms.CopyColumns("Prediction", "Prediction/Softmax"));
Vous devez copier la colonne
Prediction/Softmax
dans une colonne avec un nom qui peut être utilisé comme propriété dans une classe C# :Prediction
. Le caractère/
n’est pas autorisé dans un nom de propriété C#.
Créer le modèle ML.NET à partir du pipeline
Ajoutez le code pour créer le modèle à partir du pipeline :
// Create an executable model from the estimator pipeline IDataView dataView = mlContext.Data.LoadFromEnumerable(new List<MovieReview>()); ITransformer model = pipeline.Fit(dataView);
Un modèle ML.NET est créé à partir de la chaîne d’estimateurs dans le pipeline en appelant la méthode
Fit
. Dans le cas présent, nous n’ajustons aucune donnée pour créer le modèle, car le modèle TensorFlow a déjà été entraîné précédemment. Nous fournissons un objet de vue de données vide pour répondre aux exigences de la méthodeFit
.
Utiliser le modèle pour effectuer une prédiction
Ajoutez la méthode
PredictSentiment
au-dessus de la classeMovieReview
:void PredictSentiment(MLContext mlContext, ITransformer model) { }
Ajoutez le code suivant pour créer le
PredictionEngine
comme première ligne de la méthodePredictSentiment()
:var engine = mlContext.Model.CreatePredictionEngine<MovieReview, MovieReviewSentimentPrediction>(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
Predict()
en créant une instance deMovieReview
:var review = new MovieReview() { ReviewText = "this film is really good" };
Passez les données des commentaires de test à
Prediction Engine
en ajoutant les lignes de code suivantes dans la méthodePredictSentiment()
:var sentimentPrediction = engine.Predict(review);
La fonction Predict() fait une prédiction sur une seule ligne de données :
Propriété Valeur Type Prédiction [0,5459937, 0,454006255] float[] Affichez la prédiction du sentiment en utilisant le code suivant :
Console.WriteLine($"Number of classes: {sentimentPrediction.Prediction?.Length}"); Console.WriteLine($"Is sentiment/review positive? {(sentimentPrediction.Prediction?[1] > 0.5 ? "Yes." : "No.")}");
Ajoutez un appel à
PredictSentiment
après avoir appelé la méthodeFit()
:PredictSentiment(mlContext, model);
Résultats
Créez et exécutez votre application.
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. Ces messages ont été supprimés des résultats suivants par souci de clarté.
Number of classes: 2
Is sentiment/review positive ? Yes
Félicitations ! Vous venez de créer un modèle Machine Learning pour la classification et la prédiction des sentiments de messages en réutilisant un modèle TensorFlow
dans ML.NET.
Vous trouverez le code source de ce tutoriel dans le référentiel dotnet/samples.
Dans ce didacticiel, vous avez appris à :
- Charger un modèle TensorFlow préentraîné
- Transformer le texte des commentaires d’un site web en caractéristiques convenant au modèle
- Utiliser le modèle pour effectuer une prédiction