Tutoriel : Prédire des prix en utilisant la régression avec ML.NET
Ce tutoriel montre comment créer un modèle de régression avec ML.NET pour prédire des prix, plus précisément, des courses de taxi à New York.
Dans ce tutoriel, vous allez apprendre à :
- Préparer et comprendre les données
- Charger et transformer les données
- Choisir un algorithme d’apprentissage
- Effectuer l’apprentissage du modèle
- Évaluer le modèle
- Utiliser le modèle pour les prévisions
Prérequis
- Visual Studio 2022 avec la charge de travail « Développement .NET Desktop » installée.
Création d’une application console
Créez une application console C# appelée « TaxiFarePrediction ».
Choisissez .NET 6 comme framework à utiliser. Cliquez sur le bouton Créer.
Créez un répertoire nommé Data (Données) dans votre projet pour y stocker les fichiers du jeu de données et du modèle.
Installez les packages NuGet Microsoft.ML et Microsoft.ML.FastTree :
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 le 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 dans la liste, puis sélectionnez le bouton Installer. Cliquez sur le bouton OK dans la boîte de dialogue Aperçu des modifications, puis sur le bouton J’accepte dans la boîte de dialogue Acceptation de la licence si vous acceptez les termes du contrat de licence pour les packages répertoriés. Faites de même pour le package NuGet Microsoft.ML.FastTree.
Préparer et comprendre les données
Téléchargez les jeux de données taxi-fare-train.csv et taxi-fare-test.csv, puis enregistrez-les dans le dossier Données créé à l’étape précédente. Nous utilisons ces jeux de données pour le modèle Machine Learning et pour évaluer la précision du modèle. Ces jeux de données proviennent du jeu de données NYC TLC Taxi Trip.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur chacun des fichiers .csv, puis sélectionnez Propriétés. Sous Avancé, définissez la valeur Copier dans le répertoire de sortie sur Copier si plus récent.
Ouvrez le jeu de données taxi-fare-train.csv et examinez les en-têtes de colonne dans la première ligne. Examinons chacune des colonnes. Analysez les données et identifiez les colonnes qui sont des fonctionnalités et celle qui est l’étiquette.
label
est la colonne à prédire. Les valeurs Features
identifiées sont les entrées que vous fournissez au modèle pour prédire l’étiquette (Label
).
Le jeu de données fourni contient les colonnes suivantes :
- vendor_id : l’ID du taxi est une fonctionnalité.
- rate_code : le type de tarif de la course de taxi est une fonctionnalité.
- passenger_count : le nombre de passagers embarqués est une fonctionnalité.
- trip_time_in_secs : durée totale de la course. Vous voulez prédire le prix de la course avant de l’effectuer. À ce stade, vous ne connaissez pas la durée de la course. Par conséquent, la durée de la course n’est pas une fonctionnalité et vous devez exclure cette colonne du modèle.
- trip_distance : la distance de la course est une fonctionnalité.
- payment_type : le mode de paiement (espèces ou carte de crédit) est une fonctionnalité.
- fare_amount : le prix total payé pour la course est l’étiquette.
Créer des classes de données
Créez des classes pour les données d’entrée et les prédictions :
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 TaxiTrip.cs. Ensuite, sélectionnez le bouton Ajouter.
Ajoutez les directives
using
suivantes au nouveau fichier :using Microsoft.ML.Data;
Supprimez la définition de classe existante et ajoutez le code suivant, qui contient deux classes, TaxiTrip
et TaxiTripFarePrediction
, au fichier TaxiTrip.cs :
public class TaxiTrip
{
[LoadColumn(0)]
public string? VendorId;
[LoadColumn(1)]
public string? RateCode;
[LoadColumn(2)]
public float PassengerCount;
[LoadColumn(3)]
public float TripTime;
[LoadColumn(4)]
public float TripDistance;
[LoadColumn(5)]
public string? PaymentType;
[LoadColumn(6)]
public float FareAmount;
}
public class TaxiTripFarePrediction
{
[ColumnName("Score")]
public float FareAmount;
}
TaxiTrip
est la classe des données d’entrée et a des définitions pour chacune des colonnes du jeu de données. Utilisez l’attribut LoadColumnAttribute pour spécifier les index des colonnes sources dans le jeu de données.
La classe TaxiTripFarePrediction
représente les résultats prédits. Elle comporte un seul champ float, FareAmount
, avec un attribut Score
ColumnNameAttribute appliqué. Dans le cas de la tâche de régression, la colonne Score contient les valeurs d’étiquette prédites.
Notes
Utilisez le type float
pour représenter les valeurs à virgule flottante dans les classes de données d’entrée et de prédiction.
Définir des chemins de données et de modèle
Ajoutez les instructions using
supplémentaires suivantes en haut du fichier Program.cs :
using Microsoft.ML;
using TaxiFarePrediction;
Il faut créer trois champs qui contiendront les chemins des fichiers comportant des jeux de données et le fichier permettant d’enregistrer le modèle :
_trainDataPath
contient le chemin du fichier avec le jeu de données utilisé pour l’apprentissage du modèle._testDataPath
contient le chemin du fichier avec le jeu de données utilisé pour l’évaluation du modèle._modelPath
contient le chemin du fichier où le modèle formé est stocké.
Ajoutez le code suivant juste en dessous de la section usings pour spécifier ces chemins et pour la variable _textLoader
:
string _trainDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "taxi-fare-train.csv");
string _testDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "taxi-fare-test.csv");
string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "Model.zip");
Toutes les opérations de ML.NET commencent dans la classe MLContext. 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.
Initialiser les variables
Remplacez la ligne Console.WriteLine("Hello World!")
par le code suivant pour déclarer et initialiser la variable mlContext
:
MLContext mlContext = new MLContext(seed: 0);
Ajoutez ceci à la ligne suivante pour appeler la méthode Train
:
var model = Train(mlContext, _trainDataPath);
La méthode Train()
exécute les tâches suivantes :
- Charge les données.
- Extrait et transforme les données.
- Effectue l’apprentissage du modèle.
- Retourne le modèle.
La méthode Train
effectue l’apprentissage du modèle. Créez cette méthode juste en dessous en utilisant le code suivant :
ITransformer Train(MLContext mlContext, string dataPath)
{
}
Charger et transformer les données
ML.NET utilise l’interface IDataView comme un moyen flexible et efficace de décrire des données tabulaires numériques ou texte. IDataView
peut charger des fichiers texte ou en temps réel (par exemple, une base de données SQL ou des fichiers journaux). Ajoutez le code suivant comme première ligne de la méthode Train()
:
IDataView dataView = mlContext.Data.LoadFromTextFile<TaxiTrip>(dataPath, hasHeader: true, separatorChar: ',');
Comme vous voulez prédire le prix de la course de taxi, la colonne FareAmount
est la Label
que vous allez prédire (la sortie du modèle). Utilisez la classe de transformation CopyColumnsEstimator
pour copier FareAmount
et ajoutez le code suivant :
var pipeline = mlContext.Transforms.CopyColumns(outputColumnName: "Label", inputColumnName:"FareAmount")
L’algorithme qui effectue l’apprentissage du modèle exige des fonctionnalités numériques. Il faut donc transformer les données catégoriques (VendorId
, RateCode
et PaymentType
) en nombres (VendorIdEncoded
, RateCodeEncoded
et PaymentTypeEncoded
). Pour cela, utilisez la classe de transformation OneHotEncodingTransformer, qui assigne différentes valeurs de clé numérique aux différentes valeurs de chaque colonne, puis ajoutez le code suivant :
.Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "VendorIdEncoded", inputColumnName:"VendorId"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "RateCodeEncoded", inputColumnName: "RateCode"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "PaymentTypeEncoded", inputColumnName: "PaymentType"))
La dernière étape de préparation des données regroupe toutes les colonnes de fonctionnalités dans la colonne Fonctionnalités à l’aide de la classe de transformation mlContext.Transforms.Concatenate
. Par défaut, un algorithme d’apprentissage traite uniquement les caractéristiques issues de la colonne Features. Ajoutez le code suivant :
.Append(mlContext.Transforms.Concatenate("Features", "VendorIdEncoded", "RateCodeEncoded", "PassengerCount", "TripDistance", "PaymentTypeEncoded"))
Choisir un algorithme d’apprentissage
Ce problème consiste à prédire le prix d’une course de taxi à New York. À première vue, ce prix semble dépendre simplement de la distance parcourue. Mais les chauffeurs de taxi à New York appliquent différents tarifs selon des facteurs comme le nombre de passagers supplémentaires ou le paiement par carte de crédit plutôt que par espèces. Vous souhaitez prédire le prix, qui est une valeur réelle, en fonction des autres facteurs du jeu de données. Pour ce faire, choisissez une tâche de machine learning par régression.
Ajoutez la tâche de machine learning FastTreeRegressionTrainer aux définitions de transformation des données en ajoutant la ligne de code suivante dans Train()
:
.Append(mlContext.Regression.Trainers.FastTree());
Entraîner le modèle
Ajustez le modèle aux données d’entraînement dataview
et retournez le modèle entraîné en ajoutant la ligne de code suivante à la méthode Train()
:
var model = pipeline.Fit(dataView);
La méthode Fit() entraîne votre modèle en transformant le jeu de données et en appliquant l’entraînement.
Retournez le modèle entraîné avec la ligne suivante de code dans la méthode Train()
:
return model;
Évaluer le modèle
Ensuite, évaluez les performances de votre modèle avec vos données de test à des fins d’assurance qualité et de validation. Créez la méthode Evaluate()
juste après Train()
, en utilisant le code suivant :
void Evaluate(MLContext mlContext, ITransformer model)
{
}
La méthode Evaluate
exécute les tâches suivantes :
- Charge le jeu de données de test.
- Crée l’évaluateur de régression.
- Évalue le modèle et crée des métriques.
- Affiche les métriques.
Ajoutez un appel à la nouvelle méthode juste en dessous de l’appel de la méthode Train
, en utilisant le code suivant :
Evaluate(mlContext, model);
Chargez le jeu de données de test à l’aide de la méthode LoadFromTextFile(). Évaluez le modèle avec ce jeu de données afin d’en contrôler la qualité, en ajoutant le code suivant à la méthode Evaluate
:
IDataView dataView = mlContext.Data.LoadFromTextFile<TaxiTrip>(_testDataPath, hasHeader: true, separatorChar: ',');
Transformez ensuite les données Test
en ajoutant le code suivant à Evaluate()
:
var predictions = model.Transform(dataView);
La méthode Transform() établit des prédictions pour les lignes d’entrée du jeu de données de test.
La méthode RegressionContext.Evaluate
calcule les métriques de qualité pour PredictionModel
à l’aide du jeu de données spécifié. Elle retourne un objet RegressionMetrics qui contient les métriques globales calculées par les évaluateurs de régression.
Pour afficher ces informations afin d’évaluer la qualité du modèle, vous devez d’abord obtenir les métriques. Ajoutez le code suivant comme première ligne de la méthode Evaluate
:
var metrics = mlContext.Regression.Evaluate(predictions, "Label", "Score");
Une fois que vous avez le jeu de prédiction, la méthode Evaluate() évalue le modèle (elle compare les valeurs prédites aux Labels
réelles dans le jeu de données de test et retourne des métriques relatives aux performances du modèle).
Ajoutez le code suivant pour évaluer le modèle et produire les métriques d’évaluation :
Console.WriteLine();
Console.WriteLine($"*************************************************");
Console.WriteLine($"* Model quality metrics evaluation ");
Console.WriteLine($"*------------------------------------------------");
RSquared est une autre métrique d’évaluation des modèles de régression. RSquared prend des valeurs entre 0 et 1. Plus sa valeur est proche de 1, plus le modèle est bon. Ajoutez le code suivant dans la méthode Evaluate
pour afficher la valeur RSquared :
Console.WriteLine($"* RSquared Score: {metrics.RSquared:0.##}");
RMS est une des métriques d’évaluation du modèle de régression. Plus sa valeur est faible, plus le modèle est bon. Ajoutez le code suivant dans la méthode Evaluate
pour afficher la valeur RMS :
Console.WriteLine($"* Root Mean Squared Error: {metrics.RootMeanSquaredError:#.##}");
Utiliser le modèle pour les prévisions
Créez la méthode TestSinglePrediction
juste après la méthode Evaluate
, en utilisant le code suivant :
void TestSinglePrediction(MLContext mlContext, ITransformer model)
{
}
La méthode TestSinglePrediction
exécute les tâches suivantes :
- Crée un commentaire unique de données de test.
- Prédit le prix de la course 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 :
TestSinglePrediction(mlContext, model);
Utilisez PredictionEngine
pour prédire le prix de la course en ajoutant le code suivant à TestSinglePrediction()
:
var predictionFunction = mlContext.Model.CreatePredictionEngine<TaxiTrip, TaxiTripFarePrediction>(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 service PredictionEnginePool
, qui crée un ObjectPool
d’objets PredictionEngine
à utiliser dans votre application. Consultez ce guide sur l’utilisation de PredictionEnginePool
dans une API web ASP.NET Core.
Notes
L’extension de service PredictionEnginePool
est disponible en préversion.
Ce tutoriel utilise une course test au sein de cette classe. Par la suite, vous pouvez ajouter d’autres scénarios à tester avec le modèle. Ajoutez une course pour tester la prédiction de coût du modèle formé dans la méthode TestSinglePrediction()
en créant une instance de TaxiTrip
:
var taxiTripSample = new TaxiTrip()
{
VendorId = "VTS",
RateCode = "1",
PassengerCount = 1,
TripTime = 1140,
TripDistance = 3.75f,
PaymentType = "CRD",
FareAmount = 0 // To predict. Actual/Observed = 15.5
};
Ensuite, prédisez le prix basé sur une instance unique des données d’une course de taxi et passez le résultat à PredictionEngine
en ajoutant les lignes de code suivantes à la méthode TestSinglePrediction()
:
var prediction = predictionFunction.Predict(taxiTripSample);
La fonction Predict() établit une prédiction sur une instance unique de données.
Pour afficher le prix prédit de la course spécifiée, ajoutez le code suivant à la méthode TestSinglePrediction
:
Console.WriteLine($"**********************************************************************");
Console.WriteLine($"Predicted fare: {prediction.FareAmount:0.####}, actual fare: 15.5");
Console.WriteLine($"**********************************************************************");
Exécutez le programme afin d’afficher le prix prédit de la course pour votre cas de test.
Félicitations ! Vous avez créé un modèle Machine Learning pour prédire le prix des courses de taxi, avez évalué sa précision et l’avez utilisé pour faire des prédictions. Vous trouverez le code source de ce tutoriel dans le dépôt GitHub dotnet/samples.
Étapes suivantes
Dans ce didacticiel, vous avez appris à :
- Préparer et comprendre les données
- Créer un pipeline d’apprentissage
- Charger et transformer les données
- Choisir un algorithme d’apprentissage
- Effectuer l’apprentissage du modèle
- Évaluer le modèle
- Utiliser le modèle pour les prévisions
Passez au tutoriel suivant pour en savoir plus.