ML-4 : Evaluation des modèles

Navigation : Index | << ML-3 Entrainement&AutoML | Suivant >> ML-5 TimeSeries

Objectifs d’apprentissage

A la fin de ce notebook, vous saurez : 1. Evaluer un modèle avec les métriques adaptées (R², MAE, RMSE, accuracy) 2. Mettre en œuvre la validation croisée (K-fold) 3. Analyser l’importance des features avec PFI (Permutation Feature Importance) 4. Interpréter une matrice de confusion pour la classification

Repères bibliographiques. Deux techniques centrales de ce notebook reposent sur des méthodes canoniques : - la validation croisée (cross-validation, K-fold) formalisée par M. Stone, Cross-Validatory Choice and Assessment of Statistical Predictions, Journal of the Royal Statistical Society. Series B, 36(2), 1974 ; - l’importance des caractéristiques par permutation (PFI) introduite par L. Breiman, Random Forests, Machine Learning, 45(1), 2001 — la méthode de référence dont s’inspire PermutationFeatureImportance de ML.NET.

Prérequis

  • ML-3-Entrainement&AutoML complété
  • Notions de régression et classification

Durée estimée : 40-50 minutes


Évaluation du modèle

Dans ce notebook, vous apprendrez :

  • Qu’est-ce que l’évaluation d’un modèle ?
  • Comment évaluer un modèle dans ML.NET
  • Entraîner et évaluer des modèles avec la validation croisée
  • Explicabilité du modèle
  • Comment améliorer votre modèle

Qu’est-ce que l’évaluation d’un modèle ?

L’entraînement est le processus d’application d’algorithmes à des données historiques afin de créer un modèle qui représente fidèlement ces données. Ce modèle est ensuite utilisé sur de nouvelles données pour faire des prédictions.

L’évaluation du modèle est le processus d’utilisation de métriques pour quantifier l’efficacité avec laquelle votre modèle a appris les motifs dans vos données et applique ces apprentissages à des données nouvelles et inconnues.

Comment évaluer un modèle dans ML.NET

Importation du package Nuget ML.NET

#i "nuget:https://pkgs.dev.azure.com/dnceng/public/_packaging/MachineLearning/nuget/v3/index.json"

#r "nuget: Microsoft.ML, 5.0.0"
#r "nuget: Microsoft.ML.AutoML, 0.23.0"
#r "nuget: Microsoft.CodeAnalysis.CSharp, 4.13.0"
#r "nuget: Microsoft.Data.Analysis, 0.23.0"
Restore sources
  • https://pkgs.dev.azure.com/dnceng/public/_packaging/MachineLearning/nuget/v3/index.json
Installing Packages
  • Microsoft.CodeAnalysis.CSharp
  • Microsoft.Data.Analysis
  • Microsoft.ML
  • Microsoft.ML.AutoML

Référencer les packages avec des instructions using

using System.Text.Json;
using Microsoft.Data.Analysis;
using Microsoft.ML;
using Microsoft.ML.AutoML;
using Microsoft.ML.Data;
using Microsoft.ML.Trainers.FastTree;
using static Microsoft.ML.Transforms.OneHotEncodingEstimator;

Télécharger ou localiser les données

Le code suivant essaie de localiser le fichier de données à quelques emplacements connus ou le télécharge à partir de l’emplacement GitHub connu.

using System;
using System.IO;
using System.Net;

// Passage en culture anglaise pour les nombres à virgule
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");

string EnsureDataSetDownloaded(string fileName)
{
    var filePath = Path.Combine(Directory.GetCurrentDirectory(), "data", fileName);

    if (!File.Exists(filePath))
    {
        filePath = Path.Combine(Directory.GetCurrentDirectory(), fileName);
    }

    if (!File.Exists(filePath))
    {
        using (var client = new WebClient())
        {
            client.DownloadFile($"https://raw.githubusercontent.com/dotnet/csharp-notebooks/main/machine-learning/data/{fileName}", filePath);
        }
        Console.WriteLine($"Downloaded {Path.GetFileName(filePath)} into the notebook data folder");
    }
    else
    {
        Console.WriteLine($"{fileName} found in the notebook data folder");
    }

    return filePath;
}

var trainDataPath = EnsureDataSetDownloaded("taxi-fare.csv");
var df = DataFrame.LoadCsv(trainDataPath);
taxi-fare.csv found in the notebook data folder

Une fois les données chargées, utilisez la méthode Head pour prévisualiser les cinq premières lignes.

df.Head(5)
index vendor_id rate_code passenger_count trip_time_in_secs trip_distance payment_type fare_amount
0
CMT
1
1
1271
3.8
CRD
17.5
1
CMT
1
1
474
1.5
CRD
8
2
CMT
1
1
637
1.4
CRD
8.5
3
CMT
1
1
181
0.6
CSH
4.5
4
CMT
1
1
661
1.1
CRD
8.5

Initialiser MLContext

Toutes les opérations ML.NET commencent par la classe MLContext. Initialiser mlContext crée un nouvel environnement ML.NET qui peut être partagé entre les objets du workflow de création de modèles. C’est similaire, conceptuellement, à DBContext dans Entity Framework.

var mlContext = new MLContext();

Diviser les données en ensembles d’entraînement, de validation et de test

L’ensemble de données original est divisé en trois sous-ensembles : entraînement, validation et test. L’ensemble d’entraînement est utilisé pour apprendre les motifs de vos données. L’ensemble de validation est utilisé pour optimiser les hyperparamètres du modèle. L’ensemble de test est utilisé pour évaluer les performances de votre modèle à l’aide de métriques d’évaluation pour la tâche de régression.

Pourquoi ne pas utiliser l’ensemble de données complet ?

Bien que fournir plus d’exemples à votre entraîneur soit généralement recommandé, vous ne voulez pas d’un modèle qui ne performe bien que sur des données historiques. Au lieu de cela, vous cherchez un modèle qui peut apprendre de ces données historiques et généraliser ou faire des prédictions précises sur de nouvelles données inconnues.

Certains problèmes courants rencontrés pendant l’entraînement sont le surapprentissage et le sous-apprentissage. Le sous-apprentissage signifie que l’entraîneur sélectionné n’est pas assez puissant pour ajuster l’ensemble de données d’entraînement et se traduit généralement par une perte élevée pendant l’entraînement et une faible métrique sur l’ensemble de test. Pour résoudre cela, vous devez soit sélectionner un modèle plus puissant, soit effectuer plus d’ingénierie des caractéristiques. Le surapprentissage est l’opposé, et se produit lorsque le modèle apprend trop bien les données d’entraînement. Cela se traduit généralement par une faible perte métrique pendant l’entraînement, mais une perte élevée sur l’ensemble de test.

Une bonne analogie pour ces concepts est de réviser pour un examen. Disons que vous connaissez les questions et réponses à l’avance. Après avoir révisé, vous passez l’examen et obtenez un score parfait. Bonne nouvelle ! Cependant, lorsque vous repassez l’examen avec les questions réorganisées et légèrement reformulées, vous obtenez un score plus bas. Cela suggère que vous avez mémorisé les réponses et n’avez pas vraiment appris les concepts testés. C’est un exemple de surapprentissage. Le sous-apprentissage est le contraire, où les matériaux d’étude que vous avez reçus ne représentent pas fidèlement ce sur quoi vous êtes évalué lors de l’examen. En conséquence, vous devez deviner les réponses car vous n’avez pas assez de connaissances pour répondre correctement.

var trainTestData = mlContext.Data.TrainTestSplit(df, testFraction: 0.2);
var validationTestData = mlContext.Data.TrainTestSplit(trainTestData.TestSet, testFraction: 0.5);

var trainSet = trainTestData.TrainSet;
var validationSet = validationTestData.TrainSet;
var testSet = validationTestData.TestSet;

Créer le pipeline d’entraînement

Pour cet ensemble de données, les transformations suivantes sont appliquées :

  • OneHotEncoding pour convertir les valeurs catégorielles en valeurs numériques
  • ReplaceMissingValues pour remplacer les valeurs manquantes
  • Concatenate prend toutes les caractéristiques et crée un vecteur de caractéristiques

AutoML est utilisé pour définir une expérience de régression en utilisant la colonne fare_amount comme colonne à prédire ou colonne d’étiquette.

var pipeline = 
    mlContext.Transforms.Categorical.OneHotEncoding(new[] { new InputOutputColumnPair("vendor_id", "vendor_id"), new InputOutputColumnPair("payment_type", "payment_type") }, outputKind: OutputKind.Binary)
        .Append(mlContext.Transforms.ReplaceMissingValues(new[] { new InputOutputColumnPair("rate_code", "rate_code"), new InputOutputColumnPair("passenger_count", "passenger_count"), new InputOutputColumnPair("trip_time_in_secs", "trip_time_in_secs"), new InputOutputColumnPair("trip_distance", "trip_distance") }))
        .Append(mlContext.Transforms.Concatenate("Features", new[] { "vendor_id", "payment_type", "rate_code", "passenger_count", "trip_time_in_secs", "trip_distance" }))
        .Append(mlContext.Auto().Regression(labelColumnName: "fare_amount"));

Configurer l’expérience

Utilisez AutoML pour configurer notre expérience pour entraîner pendant 60 secondes en utilisant le pipeline que vous venez de définir.

Par défaut, AutoML évalue les modèles qu’il entraîne en utilisant la métrique d’évaluation que vous souhaitez optimiser. Dans ce cas, il s’agit du R-carré, qui est calculé en comparant la valeur réelle fare_amount avec la valeur prédite Score.

Les métriques d’évaluation dépendent fortement de la tâche. Pour la régression, certaines métriques courantes incluent :

  • Erreur absolue moyenne (MAE)
  • Erreur quadratique moyenne (MSE)
  • Racine de l’erreur quadratique moyenne (RMSE)
  • R-carré

Votre ensemble de données et ce que vous essayez d’atteindre influencent fortement votre sélection de métrique. Si vous avez des valeurs aberrantes dans votre ensemble de données, elles peuvent fausser vos prédictions. MAE, MSE et RMSE calculent la distance entre les points de données prédits et réels. Toutes ces mesures sont sensibles aux valeurs aberrantes, donc si vous avez des valeurs aberrantes dans votre ensemble de données, elles apparaîtront dans vos métriques. Le R-carré calcule la corrélation entre les valeurs réelles et préd ites. Cependant, à mesure que vous ajoutez plus de points de données, votre R-carré peut continuer à augmenter, donnant l’impression erronée qu’un modèle avec une valeur de R-carré élevée a de bonnes capacités prédictives. Le résultat d’une valeur élevée de R-carré peut parfois indiquer un surapprentissage.

var experiment = 
    mlContext.Auto().CreateExperiment()
        .SetPipeline(pipeline)
        .SetTrainingTimeInSeconds(60)
        .SetDataset(trainSet, validationSet)
        .SetRegressionMetric(RegressionMetric.RSquared, "fare_amount", "Score");

Exécuter l’expérience

var result = await experiment.RunAsync();

Voir les métriques d’évaluation du meilleur modèle

$"R-Squared: {result.Metric}"
R-Squared: 0,9412334003654281

Notez que pendant l’entraînement, les métriques d’évaluation ont été calculées en utilisant l’ensemble de validation. Pour voir comment votre modèle performe sur de nouvelles données, évaluez ses performances par rapport à l’ensemble de test.

Commencez par obtenir le meilleur modèle en utilisant la propriété Model des résultats d’entraînement. Ensuite, utilisez la méthode Transform pour utiliser le modèle afin de faire des prédictions sur l’ensemble de test.

ITransformer bestModel = result.Model;
var predictions = bestModel.Transform(testSet);

Inspectez les premières prédictions (colonne Score) et comparez-les avec la valeur réelle (colonne fare_amount). Ensuite, calculez la différence entre elles.

var actual = predictions.GetColumn<float>("fare_amount");
var predicted = predictions.GetColumn<float>("Score");

var compare = 
    actual
        .Zip(predicted, (actual, pred) => new { Actual = actual, Predicted = pred, Difference = actual - pred })
        .Take(5);

compare
index value
0
{ Actual = 24,5, Predicted = 26,07155, Difference = -1,5715504 }
Actual
24.5
Predicted
26.07155
Difference
-1.5715504
1
{ Actual = 9,5, Predicted = 9,243894, Difference = 0,25610638 }
Actual
9.5
Predicted
9.243894
Difference
0.25610638
2
{ Actual = 4,5, Predicted = 4,781055, Difference = -0,28105497 }
Actual
4.5
Predicted
4.781055
Difference
-0.28105497
3
{ Actual = 8, Predicted = 8,59637, Difference = -0,59636974 }
Actual
8
Predicted
8.59637
Difference
-0.59636974
4
{ Actual = 52, Predicted = 53,123466, Difference = -1,1234665 }
Actual
52
Predicted
53.123466
Difference
-1.1234665

Rien qu’en comparant rapidement les premières valeurs, vous pouvez voir que les prédictions sont généralement à quelques centimes près de la valeur réelle.

Avec ML.NET, vous n’avez pas besoin de calculer manuellement les métriques d’évaluation pour vos modèles. ML.NET fournit une méthode intégrée Evaluate pour chacune des tâches de machine learning qu’il prend en charge. Utilisez la méthode Evaluate pour la tâche de régression afin de calculer les métriques d’évaluation pour l’ensemble de test où la colonne fare_amount est la valeur réelle et la colonne Score est la valeur prédite.

var evaluationMetrics = mlContext.Regression.Evaluate(predictions, "fare_amount", "Score");

L’utilisation de la méthode Evaluate permet non seulement de calculer la métrique que vous avez optimisée pendant l’entraînement (R-carré), mais aussi toutes les métriques pour la tâche de régression.

evaluationMetrics
Microsoft.ML.Data.RegressionMetrics
MeanAbsoluteError
0.6125460022449494
MeanSquaredError
5.8628492823635465
RootMeanSquaredError
2.421332129709501
LossFunction
5.862849357626053
RSquared
0.9364978510303482

Utiliser le R-carré pour évaluer le modèle

Bien que vous ayez plusieurs métriques à choisir, lorsque vous avez entraîné le modèle, vous avez optimisé pour le R-carré. Le R-carré (R2), ou coefficient de détermination, représente la puissance prédictive du modèle avec une valeur comprise entre -inf et 1,00. 1,00 signifie qu’il y a un ajustement parfait, et l’ajustement peut être arbitrairement mauvais, donc les scores peuvent être négatifs. Un score de 0,00 signifie que le modèle devine la valeur attendue pour l’étiquette. Une valeur négative de R2 indique que l’ajustement ne suit pas la tendance des données et que le modèle performe moins bien que le hasard. Cela n’est possible qu’avec des modèles de régression non linéaire ou des régressions linéaires contraintes. Le R2 mesure à quel point les valeurs réelles des données de test sont proches des valeurs prédites.

Pour plus d’informations sur les autres métriques d’évaluation, consultez le guide sur comment évaluer votre modèle ML.NET avec des métriques.

Entraîner et évaluer des modèles en utilisant la validation croisée

Qu’est-ce que la validation croisée ?

La validation croisée est une technique d’entraînement et d’évaluation de modèle qui divise les données en plusieurs partitions et entraîne plusieurs modèles sur ces partitions. Cette technique améliore la robustesse du modèle en réservant des données du processus d’entraînement. En plus d’améliorer les performances sur des observations non vues, dans des environnements de données limitées, elle peut être un outil efficace pour entraîner des modèles avec un plus petit ensemble de données.

Entraîner un modèle en utilisant la validation croisée

Commencez par initialiser le MLContext.

var cvMLContext = new MLContext();

Ensuite, définissez votre pipeline. Dans ce cas, l’entraîneur réel est utilisé au lieu de SweepableEstimator d’AutoML.

var cvMLPipeline = 
    cvMLContext.Transforms.Categorical.OneHotEncoding(new[] { new InputOutputColumnPair("vendor_id", "vendor_id"), new InputOutputColumnPair("payment_type", "payment_type") }, outputKind: OutputKind.Binary)
        .Append(cvMLContext.Transforms.ReplaceMissingValues(new[] { new InputOutputColumnPair("rate_code", "rate_code"), new InputOutputColumnPair("passenger_count", "passenger_count"), new InputOutputColumnPair("trip_time_in_secs", "trip_time_in_secs"), new InputOutputColumnPair("trip_distance", "trip_distance") }))
        .Append(cvMLContext.Transforms.Concatenate("Features", new[] { "vendor_id", "payment_type", "rate_code", "passenger_count", "trip_time_in_secs", "trip_distance" }))
        .Append(cvMLContext.Regression.Trainers.FastForest(labelColumnName: "fare_amount"));

Utilisez la méthode CrossValidate pour démarrer l’entraînement et l’évaluation sur vos données en utilisant le pipeline défini. Par défaut, les données sont divisées en cinq sous-ensembles, mais vous pouvez définir cette valeur à n’importe quelle valeur de votre choix en utilisant le paramètre numberOfFolds.

var cvResults = cvMLContext.Regression.CrossValidate(trainSet, cvMLPipeline, labelColumnName: "fare_amount");

cvResults.Select(x => x.Metrics)
index value
0
Microsoft.ML.Data.RegressionMetrics
MeanAbsoluteError
1.3080861318665928
MeanSquaredError
10.437064100433819
RootMeanSquaredError
3.230644533283385
LossFunction
10.437063966978595
RSquared
0.8884018879298109
1
Microsoft.ML.Data.RegressionMetrics
MeanAbsoluteError
1.360165666717988
MeanSquaredError
10.798742155503342
RootMeanSquaredError
3.2861439645127146
LossFunction
10.798742212339462
RSquared
0.8850517190709868
2
Microsoft.ML.Data.RegressionMetrics
MeanAbsoluteError
1.2518280553341605
MeanSquaredError
8.216770508755435
RootMeanSquaredError
2.8664909748253935
LossFunction
8.216770540499184
RSquared
0.9086191464533752
3
Microsoft.ML.Data.RegressionMetrics
MeanAbsoluteError
1.3420262660438258
MeanSquaredError
10.229870802662239
RootMeanSquaredError
3.1984169213319014
LossFunction
10.229870780300226
RSquared
0.8886983637741152
4
Microsoft.ML.Data.RegressionMetrics
MeanAbsoluteError
1.5430782453416307
MeanSquaredError
10.122911443078698
RootMeanSquaredError
3.1816523133552317
LossFunction
10.122911478082717
RSquared
0.88835065401792

Calculer les métriques d’évaluation de l’ensemble de test

Comme dans l’exemple précédent, utilisez la méthode Evaluate sur l’ensemble complet de test pour évaluer les performances des modèles entraînés en utilisant la validation croisée.

var cvTestEvalMetrics = 
    cvResults
        .Select(fold => fold.Model.Transform(trainTestData.TestSet))
        .Select(predictions => cvMLContext.Regression.Evaluate(predictions, "fare_amount", "Score"));
        
cvTestEvalMetrics
index value
0
Microsoft.ML.Data.RegressionMetrics
MeanAbsoluteError
1.2946164063640293
MeanSquaredError
9.741100529118015
RootMeanSquaredError
3.1210736180228134
LossFunction
9.741100436339362
RSquared
0.8944318265394658
1
Microsoft.ML.Data.RegressionMetrics
MeanAbsoluteError
1.3517783571125017
MeanSquaredError
10.697284288708751
RootMeanSquaredError
3.270670311833455
LossFunction
10.697284293348838
RSquared
0.8840692835505208
2
Microsoft.ML.Data.RegressionMetrics
MeanAbsoluteError
1.258738437439045
MeanSquaredError
10.056973626481687
RootMeanSquaredError
3.1712731869836897
LossFunction
10.056973680972417
RSquared
0.8910085843878911
3
Microsoft.ML.Data.RegressionMetrics
MeanAbsoluteError
1.3321059289142654
MeanSquaredError
10.119475327642087
RootMeanSquaredError
3.1811122783771855
LossFunction
10.119475305281489
RSquared
0.8903312286404623
4
Microsoft.ML.Data.RegressionMetrics
MeanAbsoluteError
1.5373861941022984
MeanSquaredError
11.21522705311926
RootMeanSquaredError
3.3489143096112897
LossFunction
11.215227048598013
RSquared
0.878456132199452

Lecture de la validation croisée : un estimateur plus honnête qu’un seul découpage

La sortie ci-dessus mérite une interprétation soigneuse, car elle porte le point pédagogique central de l’évaluation en machine learning. Mettons en regard les deux estimations obtenues sur le même jeu de test :

  • Découpage unique (cellule Evaluate sur un seul partage train/test, plus haut) : R² = 0,937, MAE = 0,61, RMSE = 2,42.
  • Validation croisée 5-fold ci-dessus (chaque modèle entraîné sur 4/5 des données d’entraînement, puis évalué sur le jeu de test) : en moyenne R² ≈ 0,888, MAE ≈ 1,35, RMSE ≈ 3,22, avec une dispersion non négligeable d’un fold à l’autre (R² de 0,878 à 0,894 ; MAE de 1,26 à 1,54).

L’écart est parlant : le découpage unique était optimiste d’environ 5 points de R² (0,94 vs 0,89) et sous-estimait l’erreur d’un facteur d’environ 2 sur le MAE (0,61 vs 1,35). Ce n’est pas que le modèle soit mauvais — il généralise correctement — mais le partage unique est tombé sur une partition favorable : un jeu de test « facile » et un sous-ensemble d’entraînement chanceux. La validation croisée, en moyennant sur cinq partitions distinctes de l’entraînement, lisse cet effet de chance : elle révèle la performance typique du modèle (R²≈0,89) et sa variance d’un fold à l’autre (le fold à MAE 1,54 correspond à la partition d’entraînement la plus défavorable).

C’est précisément la leçon : un seul découpage train/test est un estimateur à haute variance — il peut atterrir loin de la véritable performance de généralisation, tantôt optimiste, tantôt pessimiste, selon le tirage. La validation croisée ne change pas le modèle ; elle fournit un estimateur plus fiable de cette performance, en exposant à la fois la tendance centrale et la dispersion. C’est pourquoi on ne conclut jamais sur la qualité d’un modèle à partir d’un unique Evaluate.

Explicabilité du modèle

Les métriques d’évaluation sont un bon moyen de quantifier la précision avec laquelle votre modèle fait des prédictions sur de nouvelles données. Cependant, une bonne métrique d’évaluation ne doit pas être le seul facteur à considérer lors de l’évaluation de votre modèle. Pour renforcer la confiance autour de votre modèle et des décisions qu’il prend, il est important de comprendre comment et pourquoi il prend ces décisions.

Les modèles deviennent de plus en plus courants dans la société et affectent la vie des individus. Par exemple, imaginons qu’un modèle de machine learning soit utilisé pour établir un diagnostic médical. Il est probable que le modèle ait raison dans son diagnostic, mais les enjeux d’un mauvais diagnostic sont élevés en raison des effets sur la santé d’un individu. Il est donc important pour tous les intervenants (patients, médecins, régulateurs) de comprendre ce qui a poussé un modèle à établir ce diagnostic afin de se sentir confiants dans sa décision.

Explications globales et locales

Lors de l’explication des modèles de machine learning, vous pouvez le faire au niveau global et local.

Les explications globales sont des généralisations au niveau agrégé. Par exemple, disons que vous construisez un modèle pour prédire les tarifs de taxi. En expliquant pourquoi certains tarifs sont plus chers que d’autres, vous trouverez probablement que les trajets qui parcourent une distance plus longue ou qui durent plus longtemps sont probablement plus chers. Bien que cela ne vous dise pas exactement pourquoi un trajet particulier était plus cher qu’un autre, à un niveau agrégé, vous pouvez voir quelles caractéristiques sont importantes pour le modèle lorsqu’il prend ses décisions.

Si vous avez besoin de plus de granularité pour expliquer les décisions de votre modèle, c’est là que les explications locales entrent en jeu. Les explications locales vous permettent de voir pour une prédiction donnée quelles caractéristiques ont contribué à la décision du modèle. Par exemple, disons qu’un modèle est utilisé pour déterminer le risque de crédit pour des prêts personnels. Étant donné deux clients avec des montants de dette, des revenus et des historiques de paiement différents, le modèle détermine lequel des clients est le plus susceptible de rembourser le prêt. En utilisant des techniques d’explicabilité locale, vous pouvez inspecter au niveau individuel quelles caractéristiques ont contribué à la décision de refuser un prêt.

Techniques d’explicabilité dans ML.NET

ML.NET fournit deux techniques pour expliquer les modèles :

  • Importance des caractéristiques par permutation (PFI)
  • Calcul de la contribution des caractéristiques (FCC)

Importance des caractéristiques par permutation (PFI)

L’importance des caractéristiques par permutation est une technique d’explicabilité globale. À un haut niveau, elle mélange aléatoirement les données une caractéristique à la fois pour l’ensemble de données complet et calcule dans quelle mesure la métrique de performance d’intérêt diminue. Plus le changement est important, plus la caractéristique est importante. Pour plus d’informations, consultez Interpréter les prédictions de modèle en utilisant l’importance des caractéristiques par permutation.

Calcul de la contribution des caractéristiques (FCC)

Le calcul de la contribution des caractéristiques est une technique d’explicabilité locale. Cette technique calcule une liste spécifique au modèle des contributions par caractéristique à chacune des prédictions. Ces contributions peuvent être positives (elles augmentent la métrique d’évaluation) ou négatives (elles diminuent la métrique d’évaluation).

Expliquer les modèles avec l’importance des caractéristiques par permutation (PFI)

Initialiser MLContext

var pfiMLContext = new MLContext();

Définir le pipeline de préparation des données

var pfiDataPipeline = 
    pfiMLContext.Transforms.Categorical.OneHotEncoding(new[] { new InputOutputColumnPair("vendor_id", "vendor_id"), new InputOutputColumnPair("payment_type", "payment_type") }, outputKind: OutputKind.Binary)
        .Append(pfiMLContext.Transforms.ReplaceMissingValues(new[] { new InputOutputColumnPair("rate_code", "rate_code"), new InputOutputColumnPair("passenger_count", "passenger_count"), new InputOutputColumnPair("trip_time_in_secs", "trip_time_in_secs"), new InputOutputColumnPair("trip_distance", "trip_distance") }))
        .Append(pfiMLContext.Transforms.Concatenate("Features", new[] { "vendor_id", "payment_type", "rate_code", "passenger_count", "trip_time_in_secs", "trip_distance" }));

Appliquer les transformations de données aux données d’entraînement

var pfiPreprocessedData = 
    pfiDataPipeline
        .Fit(trainSet)
        .Transform(trainSet);

Définir votre entraîneur

var pfiTrainer = pfiMLContext.Regression.Trainers.FastForest(labelColumnName: "fare_amount");

Ajuster l’entraîneur à vos données prétraitées

var pfiModel = pfiTrainer.Fit(pfiPreprocessedData);

Calculer l’importance des caractéristiques par permutation (PFI)

La PFI (Permutation Feature Importance) est une méthode d’explicabilité agnostic du modèle : elle mesure la dégradation d’une métrique d’évaluation lorsque l’on permute aléatoirement les valeurs d’une caractéristique, brisant ainsi sa relation avec l’étiquette. Formalisée par L. Breiman (Random Forests, Machine Learning, 45(1), 2001) dans le contexte des forêts aléatoires, elle a ensuite été généralisée à tout modèle prédictif.

var permutationFeatureImportance =
    mlContext
        .Regression
        .PermutationFeatureImportance(pfiModel, pfiPreprocessedData, permutationCount: 20, labelColumnName: "fare_amount");

Extraire la métrique du R-carré

var pfiMetrics = 
    permutationFeatureImportance
        .Select((metric, idx) => new { idx, metric.RSquared })
        .OrderByDescending(x => Math.Abs(x.RSquared.Mean));

Obtenir la liste des noms de caractéristiques

var featureContributionColumn = pfiPreprocessedData.Schema.GetColumnOrNull("Features");
var slotNames = new VBuffer<ReadOnlyMemory<char>>();
featureContributionColumn.Value.GetSlotNames(ref slotNames);
var slotNameValues = slotNames.DenseValues();

Mapper les métriques PFI aux noms des caractéristiques

// Joint par idx : pfiMetrics est trie (OrderByDescending en c50), le Zip positionnel
// apparierait le k-ieme score TRIE avec le k-ieme nom du SCHEMA -- des noms meles.
var featureImportance =
    pfiMetrics
        .Select(a => new { Slot = slotNameValues.ElementAt(a.idx).ToString(), a.RSquared.Mean, a.RSquared.StandardError })
        .ToList();

// Classement PFI : la moyenne ET sa dispersion sur les permutations (Breiman 2001).
// L'ecart entre deux slots n'est lisible que rapporte a l'erreur standard.
Console.WriteLine($"{"Slot",-26} {"R2.Mean",12} {"StdErr",12} {"|Mean|/StdErr",13}");
Console.WriteLine(new string('-', 66));
foreach (var f in featureImportance)
    Console.WriteLine($"{f.Slot,-26} {f.Mean,12:0.000000} {f.StandardError,12:0.000000} {(Math.Abs(f.Mean) / Math.Max(f.StandardError, 1e-12)),13:0.0}");

featureImportance
Slot                            R2.Mean       StdErr |Mean|/StdErr
------------------------------------------------------------------
trip_distance                 -0,510078     0,000127        4018,3
trip_time_in_secs             -0,209370     0,000047        4449,5
rate_code                     -0,204760     0,000148        1387,8
payment_type.Bit0             -0,001403     0,000020          70,6
payment_type.Bit1             -0,000537     0,000002         215,9
vendor_id.Bit0                -0,000154     0,000003          50,8
passenger_count               -0,000069     0,000002          36,3
payment_type.Bit2             -0,000001     0,000000          37,7
vendor_id.Bit2                 0,000000     0,000000           0,0
vendor_id.Bit1                 0,000000     0,000000           0,0
payment_type.Bit3              0,000000     0,000000           0,0
index value
0
{ Slot = trip_distance, Mean = -0,510078003362387, StandardError = 0,0001269395830693302 }
Slot
trip_distance
Mean
-0.510078003362387
StandardError
0.0001269395830693302
1
{ Slot = trip_time_in_secs, Mean = -0,20937023279296077, StandardError = 4,70542881538896E-05 }
Slot
trip_time_in_secs
Mean
-0.20937023279296077
StandardError
4.70542881538896E-05
2
{ Slot = rate_code, Mean = -0,20475968464384237, StandardError = 0,00014754590827290503 }
Slot
rate_code
Mean
-0.20475968464384237
StandardError
0.00014754590827290503
3
{ Slot = payment_type.Bit0, Mean = -0,0014033901158783725, StandardError = 1,9867808405877736E-05 }
Slot
payment_type.Bit0
Mean
-0.0014033901158783725
StandardError
1.9867808405877736E-05
4
{ Slot = payment_type.Bit1, Mean = -0,0005374743404188533, StandardError = 2,4891741107034915E-06 }
Slot
payment_type.Bit1
Mean
-0.0005374743404188533
StandardError
2.4891741107034915E-06
5
{ Slot = vendor_id.Bit0, Mean = -0,00015360048797533052, StandardError = 3,0241380990088454E-06 }
Slot
vendor_id.Bit0
Mean
-0.00015360048797533052
StandardError
3.0241380990088454E-06
6
{ Slot = passenger_count, Mean = -6,871624128715335E-05, StandardError = 1,89205076792664E-06 }
Slot
passenger_count
Mean
-6.871624128715335E-05
StandardError
1.89205076792664E-06
7
{ Slot = payment_type.Bit2, Mean = -5,183764425653604E-07, StandardError = 1,3733526869609418E-08 }
Slot
payment_type.Bit2
Mean
-5.183764425653604E-07
StandardError
1.3733526869609418E-08
8
{ Slot = vendor_id.Bit2, Mean = 0, StandardError = 0 }
Slot
vendor_id.Bit2
Mean
0
StandardError
0
9
{ Slot = vendor_id.Bit1, Mean = 0, StandardError = 0 }
Slot
vendor_id.Bit1
Mean
0
StandardError
0
10
{ Slot = payment_type.Bit3, Mean = 0, StandardError = 0 }
Slot
payment_type.Bit3
Mean
0
StandardError
0

Interprétation — lire les résultats de la PFI

L’exécution ci-dessus produit un classement de chaque slot par valeur absolue de RSquared.Mean décroissante, accompagné de son erreur standard. Deux observations méritent un commentaire :

  • Les variables catégorielles sont éclatées en bits. vendor_id et payment_type, encodées en One-Hot, apparaissent sous la forme vendor_id.Bit0, vendor_id.Bit1, etc. : chaque bit est évalué séparément. Les variables continues (trip_distance, trip_time_in_secs) et ordinales (passenger_count, rate_code) gardent leur nom d’origine.
  • Une valeur négative est attendue. Comme la PFI mesure la dégradation du R² lorsqu’on permute la caractéristique, RSquared.Mean est presque toujours négatif : plus elle est négative (en valeur absolue), plus la caractéristique est importante pour le modèle.

Avec permutationCount: 20 et la dispersion affichée, le classement se lit sans conjecture :

  • trip_distance domine nettement : permuter la distance dégrade le R² de 0,51, avec un rapport |moyenne| / erreur standard de l’ordre de 4 000 — cette importance n’est manifestement pas du bruit d’échantillonnage. trip_time_in_secs (0,21) et rate_code (0,20) suivent. L’intuition de départ — la distance parcourue est prédictive du tarif — est confirmée par la mesure.
  • Les zéros exacts sont une information, pas un arrondi : trois slots (vendor_id.Bit2, vendor_id.Bit1, payment_type.Bit3) donnent 0,000000 ± 0,000000 sur les 20 permutations — la forêt ne coupe jamais sur ces bits One-Hot. Sans erreur standard, « 0 » est illisible : distance de zéro à bruit ou variable réellement ignorée ? Avec, c’est tranché.
  • Le classement committé auparavant souffrait d’un défaut d’étiquetage, pas d’instabilité. L’extraction triait les métriques par importance décroissante puis les zippait positionnellement avec les noms de slots dans l’ordre du schéma : le score de trip_distance s’affichait sous le nom vendor_id.Bit2, et réciproquement. La preuve est dans les valeurs : l’ancien tableau attribuait -0,51 / -0,21 / -0,20 aux trois bits de vendor_id ; le tableau corrigé — join sur l’index capturé à l’extraction — montre que ces scores appartiennent à trip_distance, trip_time_in_secs et rate_code (les moyennes mesurées, elles, n’ont presque pas bougé entre 3 et 20 permutations : ce qui variait, c’était l’étiquette, pas la mesure).
  • Pourquoi quand même augmenter permutationCount : parce que l’erreur standard n’est estimée que sur permutationCount points — à 3, elle n’a guère de sens ; à 20, elle commence à être fiable. C’est la précaution de Breiman (2001) : une estimation par permutation n’a de sens qu’accompagnée de sa dispersion.

La question voisine — « la différence entre deux modèles est-elle réelle ? » — est celle que traite en entier le jumeau Python ML-4b-ModelComparison-Validity (bootstrap, tests-t, p-values). L’équivalent C# reste à écrire ; l’erreur standard de MetricStatistics exposée ici en est la première pierre.

Expliquer les modèles avec le calcul de la contribution des caractéristiques (FCC)

Initialiser MLContext

var fccMLContext = new MLContext();

Définir le pipeline de préparation des données

var fccDataPipeline = 
    fccMLContext.Transforms.Categorical.OneHotEncoding(new[] { new InputOutputColumnPair("vendor_id", "vendor_id"), new InputOutputColumnPair("payment_type", "payment_type") }, outputKind: OutputKind.Binary)
        .Append(fccMLContext.Transforms.ReplaceMissingValues(new[] { new InputOutputColumnPair("rate_code", "rate_code"), new InputOutputColumnPair("passenger_count", "passenger_count"), new InputOutputColumnPair("trip_time_in_secs", "trip_time_in_secs"), new InputOutputColumnPair("trip_distance", "trip_distance") }))
        .Append(fccMLContext.Transforms.Concatenate("Features", new[] { "vendor_id", "payment_type", "rate_code", "passenger_count", "trip_time_in_secs", "trip_distance" }));

Appliquer les transformations de données aux données d’entraînement

var fccPreprocessedData = 
    fccDataPipeline
        .Fit(trainSet)
        .Transform(trainSet);

Définir votre entraîneur

var fccTrainer = fccMLContext.Regression.Trainers.FastForest(labelColumnName: "fare_amount");

Ajuster l’entraîneur à vos données prétraitées

var fccModel = fccTrainer.Fit(fccPreprocessedData);

Calculer les contributions des caractéristiques

var featureContributionCalc = 
    fccMLContext.Transforms.CalculateFeatureContribution(fccModel, normalize: false)
        .Fit(fccPreprocessedData)
        .Transform(fccPreprocessedData);

Obtenir la liste des noms de caractéristiques

var featureContributionColumn = featureContributionCalc.Schema.GetColumnOrNull("FeatureContributions");
var slotNames = new VBuffer<ReadOnlyMemory<char>>();
featureContributionColumn.Value.GetSlotNames(ref slotNames);
var slotNameValues = slotNames.DenseValues();

Obtenir les valeurs de contribution des caractéristiques

var featureContributionValues = featureContributionCalc.GetColumn<float[]>("FeatureContributions");

Mapper les valeurs de contribution des caractéristiques aux noms des caractéristiques

var featureContributions = 
    featureContributionValues
        .Select(x => x.Zip(slotNameValues, (a, b) => new KeyValuePair<string, float>(b.ToString(), a)));

Afficher les contributions des caractéristiques pour la première prédiction

featureContributions.First()
index value
0
[vendor_id.Bit2, 0]
Key
vendor_id.Bit2
Value
0
1
[vendor_id.Bit1, 0]
Key
vendor_id.Bit1
Value
0
2
[vendor_id.Bit0, 6,46816]
Key
vendor_id.Bit0
Value
6.46816
3
[payment_type.Bit3, 0]
Key
payment_type.Bit3
Value
0
4
[payment_type.Bit2, -3,4585545]
Key
payment_type.Bit2
Value
-3.4585545
5
[payment_type.Bit1, 19,19871]
Key
payment_type.Bit1
Value
19.19871
6
[payment_type.Bit0, 10,600954]
Key
payment_type.Bit0
Value
10.600954
7
[rate_code, -1779,6366]
Key
rate_code
Value
-1779.6366
8
[passenger_count, -1,6658905]
Key
passenger_count
Value
-1.6658905
9
[trip_time_in_secs, 75,95777]
Key
trip_time_in_secs
Value
75.95777
10
[trip_distance, -803,3262]
Key
trip_distance
Value
-803.3262

Interprétation — lire une décomposition locale (FCC)

Contrairement à la PFI (qui moyennait l’effet d’une permutation sur tout le jeu), l’output ci-dessus décompose une prédiction unique — la première ligne du jeu prétraité. Chaque contribution indique dans quel sens et avec quelle intensité la caractéristique a tiré le Score de cette prédiction par rapport à la prédiction moyenne (la baseline du modèle) :

  • Une contribution positive pousse cette prédiction vers le haut (tarif prédit plus élevé que la baseline).
  • Une contribution négative la tire vers le bas.

Ici, rate_code (-1779,6) et trip_distance (-803,3) sont les contributeurs négatifs dominants : pour cette course, ces caractéristiques abaissent fortement le tarif prédit. À l’inverse, payment_type.Bit1 (+19,2) et payment_type.Bit0 (+10,6) le relèvent légèrement.

C’est le complément essentiel de la PFI : une caractéristique peut être globalement peu importante (PFI faible) tout en étant déterminante sur certaines prédictions (FCC élevée sur ces lignes). On audite donc typiquement une prédiction surprenante en lisant sa décomposition FCC, puis on hiérarchise les caractéristiques au niveau du modèle avec la PFI.

Comment puis-je améliorer mon modèle ?

L’évaluation du modèle est une étape importante dans le workflow de machine learning pour déterminer si un modèle est prêt à être déployé en production. Si votre modèle ne répond pas à vos critères pour être prêt pour la production, il y a plusieurs choses que vous pouvez essayer pour améliorer votre modèle. Celles-ci incluent :

  • Reformuler le problème - Essayez-vous de résoudre le bon problème ? Envisagez d’examiner le problème sous différents points de vue.
  • Fournir plus d’échantillons de données - L’expérience est le meilleur enseignant. Fournir plus d’exemples qui représentent votre espace de problème aide les entraîneurs à identifier plus de cas particuliers.
  • Ajouter des caractéristiques (plus de contexte) - Construire un contexte autour des points de données aide les algorithmes ainsi que les experts en la matière à mieux prendre des décisions.
  • Utiliser des données et des caractéristiques significatives - Plus de données et de caractéristiques peuvent aider à améliorer la précision, mais aussi introduire du bruit. Envisagez d’utiliser PFI et FCC pour déterminer les caractéristiques impactant vos prédictions.
  • Utiliser la validation croisée - La validation croisée peut être un outil efficace pour entraîner des modèles avec des ensembles de données plus petits.
  • Ajustement des hyperparamètres - Utilisez les espaces de recherche AutoML pour trouver les bons hyperparamètres pour votre algorithme.
  • Choisir un algorithme différent - Utilisez AutoML pour itérer à travers les différents algorithmes disponibles dans ML.NET.

Résumé

Ce notebook a couvert l’évaluation des modèles ML.NET :

Concept Description
R² (R-carré) Mesure la corrélation entre valeurs réelles et prédites (1.0 = parfait)
MAE Erreur absolue moyenne (robuste aux valeurs aberrantes)
RMSE Racine de l’erreur quadratique moyenne (pénalise les grosses erreurs)
Validation croisée Technique d’évaluation sur plusieurs sous-ensembles
PFI Importance des features par permutation (explicabilité globale)
FCC Contribution des features par calcul (explicabilité locale)

Points clés : - Ne jamais évaluer sur les données d’entraînement - utiliser un test set séparé - La validation croisée améliore la robustesse des estimations de performance - PFI et FCC permettent de comprendre quelles features influencent les prédictions - R² proche de 1.0 indique un bon ajustement, mais surveiller aussi le surapprentissage

Navigation : Index | << ML-3 Entrainement&AutoML | Suivant >> ML-5 TimeSeries

Exercices supplémentaires

Les exercices suivants approfondissent l’evaluation des modèles avec des techniques de classification binaire et des metriques avancees.

Exercice 1 : Courbe ROC et calcul de l’AUC

Entrainez un classifieur binaire, calculez les points de la courbe ROC en faisant varier le seuil de decision, tracez la courbe avec Plotly.NET et calculez l’AUC manuellement.

Objectifs : 1. Convertir le problème de regression taxi-fare en classification binaire (seuil sur fare_amount) 2. Entrainer un classifieur binaire avec SDCA Logistic Regression 3. Extraire les probabilites de prediction pour chaque observation 4. Calculer TPR (True Positive Rate) et FPR (False Positive Rate) pour plusieurs seuils 5. Tracer la courbe ROC avec Plotly.NET (Chart.Line) 6. Calculer l’AUC manuellement par la méthode des trapezes

Indice : Pour chaque seuil de 0.1 a 0.9 par pas de 0.1, classez comme positif si Probability >= seuil. Calculez TPR = TP/(TP+FN) et FPR = FP/(FP+TN). L’AUC est la somme des aires des trapezes entre points consecutifs : AUC += 0.5 * (FPR[i+1] - FPR[i]) * (TPR[i+1] + TPR[i]).

// Exercice 1 : Courbe ROC et calcul de l'AUC
// TODO etudiant : Entrainez un classifieur binaire et tracez la courbe ROC avec Plotly.NET
// Indice : utilisez les scores de probabilite pour faire varier le seuil de decision
// Étape 1 : convertissez le problème taxi-fare en classification binaire (fare > mediane = positif)
// Étape 2 : entrainez un classifieur SDCA Logistic Regression
// Étape 3 : recuperez les probabilites via predictions.GetColumn<float>("Probability")
// Étape 4 : pour plusieurs seuils (0.1 a 0.9), calculez TPR et FPR pour tracer la courbe ROC
// Étape 5 : calculez l'AUC par la méthode des trapezes (somme des aires sous la courbe)

Console.WriteLine("Exercice a completer : courbe ROC et AUC");
Exercice a completer : courbe ROC et AUC

Exercice 2 : Analyse manuelle de la matrice de confusion

Après avoir entraine un classifieur binaire, extrayez les predictions et calculez manuellement les metriques de classification (precision, recall, F1-score) pour chaque classe.

Objectifs : 1. Convertir le problème de regression taxi-fare en classification binaire (seuil sur fare_amount) 2. Entrainer un classifieur binaire (SDCA ou FastTree) 3. Comparer les predictions aux labels reels pour extraire TP, FP, TN, FN 4. Calculer precision, recall et F1-score manuellement pour les deux classes 5. Verifier vos résultats avec les metriques ML.NET

Indice : Parcourez predictions.GetColumn<bool>("PredictedLabel") et predictions.GetColumn<bool>("Label") simultanement. Comptez les 4 cas (TP, FP, TN, FN), puis appliquez les formules : Precision = TP/(TP+FP), Recall = TP/(TP+FN), F1 = 2 * Precision * Recall / (Precision + Recall).

// Exercice 2 : Analyse manuelle de la matrice de confusion
// TODO etudiant : Entrainez un classifieur binaire et calculez precision, recall, F1 manuellement
// Indice : comptez les TP, FP, TN, FN a partir des predictions et des labels reels
// Étape 1 : utilisez les données taxi-fare et convertissez le problème en classification binaire
//          (par ex. fare_amount > seuil = "cher", sinon "abordable")
// Étape 2 : entrainez un modèle FastTree ou SDCA en classification binaire
// Étape 3 : comparez les predictions avec les labels reels pour remplir la matrice de confusion
// Étape 4 : calculez precision = TP/(TP+FP), recall = TP/(TP+FN), F1 = 2*P*R/(P+R) pour chaque classe

Console.WriteLine("Exercice a completer : analyse de la matrice de confusion");
Exercice a completer : analyse de la matrice de confusion

Exercice : Analyse complète d’un modèle de prédiction

Créez un modèle pour prédire la durée d’un trajet taxi (trip_time_in_secs) au lieu du prix, puis analysez sa qualité.

Objectifs

  1. Définir un pipeline avec trip_time_in_secs comme label (au lieu de fare_amount)
  2. Entraîner avec validation croisée (3 folds minimum)
  3. Calculer et interpréter les métriques (R², RMSE, MAE)
  4. Identifier les 2 features les plus importantes avec PFI

Indices - Modifiez le paramètre labelColumnName dans le trainer - Utilisez CrossValidate avec numberOfFolds - Comparez les métriques entre les différents folds - PFI vous montre quelles features influencent le plus les prédictions

// Exercice : Prediction de duree de trajet avec analyse complete

// TODO: Créer un nouveau MLContext
MLContext durationContext = null;

// TODO: Définir le pipeline pour predire trip_time_in_secs
// Indice: changez labelColumnName de "fare_amount" a "trip_time_in_secs"
IEstimator<ITransformer> durationPipeline = null;

// TODO: Appliquer la validation croisee (3 folds minimum)
// Indice: var cvResults = durationContext.Regression.CrossValidate(data, pipeline, numFolds: 3);
object cvResults = null;  // TODO etudiant : remplacer par CrossValidate

if (cvResults != null)
{
    // TODO: Afficher les metriques de chaque fold
    Console.WriteLine("=== Résultats Validation Croisee ===");
    // Parcourez cvResults et affichez R2, RMSE, MAE pour chaque fold
}
else
{
    Console.WriteLine("Exercice a completer : implementez les TODO pour la validation croisee");
}

// TODO: Calculer les metriques moyennes
var avgRSquared = 0.0;
var avgRMSE = 0.0;
var avgMAE = 0.0;

Console.WriteLine($"Moyennes - R2: {avgRSquared:F4}, RMSE: {avgRMSE:F2}, MAE: {avgMAE:F2}");

// TODO: Analyser l'importance des features avec PFI
// Indice: utilisez PermutationFeatureImportance sur le meilleur modèle
// Indice: prenez permutationCount >= 10 (a 3, le classement est instable -- cf. la section PFI de ce notebook)
// Indice: lisez RSquared.StandardError a cote de RSquared.Mean -- un "top 2" sans sa
//         dispersion n'a pas de reponse bien definie si les erreurs standards se chevauchent

// TODO: Afficher les 2 features les plus importantes, avec leur incertitude (Mean ± StdErr)
Console.WriteLine("Top 2 Features (PFI, Mean ± StdErr) - a implementer");

// TODO: Interpretez les résultats - quelles features sont les plus pertinentes pour predire la duree ?
Exercice a completer : implementez les TODO pour la validation croisee
Moyennes - R2: 0,0000, RMSE: 0,00, MAE: 0,00
Top 2 Features (PFI, Mean ± StdErr) - a implementer

Conclusion — ce que nous avons appris

Ce notebook a démontré le workflow complet d’évaluation d’un modèle ML.NET :

  1. Séparer entraînement / validation / test. L’évaluation honnête exige que les métriques finales soient calculées sur un ensemble de test jamais vu — distinct de l’ensemble sur lequel AutoML a optimisé. Mélanger les deux revient à noter un élève sur les exercices déjà corrigés.

  2. Le R-carré (\(R^2\)) comme métrique pivot. Coefficient de détermination compris entre \(-\infty\) et \(1{,}0\), \(R^2\) résume en un seul nombre la part de variance expliquée par le modèle. AutoML l’optimise ; la méthode Evaluate le mesure sur le test set. Mais \(R^2\) seul ne dit pas pourquoi le modèle prédit ce qu’il prédit.

  3. Deux niveaux d’explicabilité complémentaires.

    • PFI (Permutation Feature Importance) = vue globale : on permute une caractéristique et on mesure la chute de \(R^2\) moyennée sur tout le jeu. Cela produit un classement des variables les plus déterministes. Subtilité vue plus haut : les variables catégorielles encodées en One-Hot apparaissent éclatées en bits (vendor_id.Bit0, vendor_id.Bit1…), qu’il faut regrouper mentalement.
    • FCC (Feature Contribution Calculation) = vue locale : elle décompose une prédiction unique en contributions par caractéristique (sens + intensité par rapport à la prédiction moyenne). La PFI dit « cette variable compte en moyenne » ; la FCC dit « pour cette prédiction, elle a tiré le score vers le haut ».

Et ensuite ?

Une fois le modèle évalué et expliqué, reste à l’améliorer (cf. section précédente) puis à le déployer. Le notebook suivant (ML-5 TimeSeries) aborde un régime particulier où l’ordre temporel des données change la façon d’évaluer (la validation croisée aléatoire y devient une fuite d’information).

Références

  1. L. Breiman, Random Forests, Machine Learning, 45(1):5-32, 2001. Origine de l’importance des caractéristiques par permutation (PFI).
  2. M. Stone, Cross-Validatory Choice and Assessment of Statistical Predictions, Journal of the Royal Statistical Society. Series B (Methodological), 36(2):111-147, 1974. Formalisation de la validation croisée (K-fold).
  3. T. Fawcett, An Introduction to ROC Analysis, Pattern Recognition Letters, 27(8):861-874, 2006. Courbe ROC et aire sous la courbe (AUC).
  4. T. Hastie, R. Tibshirani, J. Friedman, The Elements of Statistical Learning, Springer, 2009. Métriques d’évaluation et théorie de l’apprentissage statistique.
  5. A. R. Ahmed et al., Hands-On Machine Learning with ML.NET, Packt, 2019. Référence appliquée pour l’écosystème ML.NET (API Evaluate, PermutationFeatureImportance, CrossValidate).
Retour au sommet