Comment calculer les intervalles de confiance pour les métriques de performances dans Machine Learning à l'aide d'une méthode d'amorçage automatique

Nœud source: 1178501

Comment calculer les intervalles de confiance pour les métriques de performances dans Machine Learning à l'aide d'une méthode d'amorçage automatique

Les mesures de performance de votre modèle sont-elles très précises en raison d'un « grand » jeu de test, ou très incertaines en raison d'un « petit » jeu de test ou déséquilibré ?


By David B. Rosen (PhD), Scientifique principal des données pour l'approbation de crédit automatisée chez IBM Global Financing



La ligne orange indique 89.7 % comme limite inférieure de l'intervalle de confiance de la précision équilibrée, le vert pour la précision équilibrée originale observée = 92.4 % (estimation ponctuelle) et le rouge pour la limite supérieure de 94.7 %. (Ceci et toutes les images sont de l'auteur, sauf indication contraire.)

Introduction

 
 
Si vous signalez les performances de votre classificateur comme ayant Précision = 94.8 % et F1 = 92.3 % sur un ensemble de test, cela ne signifie pas grand-chose sans savoir quelque chose sur la taille et la composition de l'ensemble de test. La marge d'erreur de ces mesures de performances variera beaucoup en fonction de la taille de l'ensemble de test ou, pour un ensemble de données déséquilibré, principalement en fonction du nombre d'instances indépendantes du minorité classe qu'il contient (plus de copies des mêmes instances provenant du suréchantillonnage n'aident pas à cette fin).

Si vous pouviez collecter un autre ensemble de tests indépendant d'origine similaire, il est peu probable que la précision et la F1 de votre modèle sur cet ensemble de données soient les mêmes, mais à quel point pourraient-elles être différentes ? Une question similaire à celle-ci trouve une réponse dans les statistiques, car le Intervalle de confiance de la mesure.

Si nous devions tirer de nombreux ensembles de données d'échantillons indépendants de la population sous-jacente, alors pour 95 % de ces ensembles de données, la véritable valeur de la population sous-jacente de la métrique se situerait dans l'intervalle de confiance à 95 % que nous calculerions pour cet ensemble de données d'échantillon particulier.

Dans cet article, nous allons vous montrer comment calculer des intervalles de confiance pour n'importe quel nombre de mesures de performances d'apprentissage automatique à la fois, avec une méthode d'amorçage qui automatiquement  détermine le nombre d'échantillons de jeux de données de démarrage à générer par défaut.

Si vous voulez juste voir comment invoquer ce code pour calculer les intervalles de confiance, passez à la section "Calculez les résultats !» en bas.

La méthodologie bootstrap

 
 
Si nous pouvions tirer des ensembles de données de test supplémentaires à partir de la vraie distribution sous-jacente aux données, nous serions en mesure de voir la distribution de la ou des mesures de performance d'intérêt dans ces ensembles de données. (Lors du dessin de ces ensembles de données, nous ne ferions rien pour empêcher de dessiner plusieurs fois une instance identique ou similaire, bien que cela ne se produise que rarement.)

Puisque nous ne pouvons pas faire cela, la meilleure chose à faire est de tirer des ensembles de données supplémentaires à partir du distribution empirique de cet ensemble de données de test, ce qui signifie échantillonner, avec remplacement, à partir de ses instances pour générer de nouveaux exemples d'ensembles de données bootstrap. L'échantillonnage avec remplacement signifie qu'une fois que nous avons dessiné une instance particulière, nous la remettons afin de pouvoir la redessiner pour le même ensemble de données d'échantillon. Par conséquent, chacun de ces ensembles de données possède généralement plusieurs copies de certaines des instances et n'inclut pas toutes les instances qui se trouvent dans l'ensemble de test de base.

Si nous avons échantillonné sans remplacement, alors nous obtiendrions simplement une copie identique de l'ensemble de données d'origine à chaque fois, mélangé dans un ordre aléatoire différent, ce qui ne serait d'aucune utilité.

La centile La méthodologie bootstrap pour estimer l'intervalle de confiance est la suivante :

  1. Générer nboots ensembles de données « échantillon bootstrap », chacun de la même taille que l'ensemble de test d'origine. Chaque ensemble de données d'échantillon est obtenu en tirant des instances au hasard à partir de l'ensemble de test avec remplacement.
  2. Sur chacun des exemples d'ensembles de données, calculez la métrique et enregistrez-la.
  3. L'intervalle de confiance à 95 % est donné par le 2.5th au 97.5th centile parmi les nboots valeurs calculées de la métrique. Si nboots=1001 et vous avez trié les valeurs dans une série/tableau/liste X de longueur 1001, le 0th le centile est X[0] et les 100th le centile est X[1000], donc l'intervalle de confiance serait donné par X[25] à X[975].

Bien sûr, vous pouvez calculer autant de métriques que vous le souhaitez pour chaque exemple d'ensemble de données à l'étape 2, mais à l'étape 3, vous trouverez les centiles pour chaque métrique séparément.

Exemple d'ensemble de données et de résultats d'intervalle de confiance

 
 
Nous utiliserons les résultats de cet article précédent comme exemple : Comment gérer une classification déséquilibrée, sans rééquilibrer les donnéesAvant d'envisager de suréchantillonner vos données asymétriques, essayez d'ajuster votre seuil de décision de classification.

Dans cet article, nous avons utilisé le très- Kaggle déséquilibré à deux classes ensemble de données d'identification de fraude à la carte de crédit. Nous avons choisi d'utiliser un seuil de classification assez différent du seuil par défaut de 0.5 qui est implicite dans l'utilisation de la méthode predict(), ce qui rend inutile l'équilibrage des données. Cette approche est parfois qualifiée seuil mobile, dans lequel notre classificateur attribue la classe en appliquant le seuil choisi à la probabilité de classe prédite fournie par la prédiction_proba() méthode.

Nous limiterons la portée de cet article (et du code) à la classification binaire : classes 0 et 1, la classe 1 étant par convention la classe "positive" et plus précisément la classe minoritaire pour les données déséquilibrées, bien que le code devrait fonctionner pour la régression (single objectif continu) également.

Génération d'un exemple d'ensemble de données de démarrage

 
 
Bien que notre code d'intervalle de confiance puisse gérer différents nombres d'arguments de données à transmettre aux fonctions de métrique, nous nous concentrerons sur les métriques de style sklearn, qui acceptent toujours deux arguments de données, y_true et y_pred, où y_pred sera soit des prédictions de classe binaires (0 ou 1), ou des prédictions continues de probabilité de classe ou de fonction de décision, ou même des prédictions de régression continue si y_true est également continu. La fonction suivante génère un exemple de jeu de données de démarrage unique. Il accepte tous les data_args mais dans notre cas ces arguments seront ytest(notre test réel/vrai a défini des valeurs cibles dans le article précédent) et hardpredtst_tuned_thresh (la classe prédite). Les deux contiennent des zéros et des uns pour indiquer la classe vraie ou prédite pour chaque instance.

Métrique personnalisée specificity_score() et fonctions utilitaires

 
 
Nous définirons une fonction métrique personnalisée pour la Spécificité, qui est juste un autre nom pour le Rappel du négatif classe (classe 0). Également une fonction calc_metrics qui applique une séquence de métriques d'intérêt à nos données, et quelques fonctions utilitaires pour cela :

Ici, nous faisons notre liste de métriques et les appliquons aux données. Nous n'avons pas considéré l'exactitude comme une mesure pertinente, car un faux négatif (classification erronée d'une véritable fraude comme légitime) est beaucoup plus coûteux pour l'entreprise qu'un faux positif (classification erronée d'une véritable légitime comme fraude), alors qu'Accuracy traite les deux types d'erreur de classification. sont tout aussi mauvais et favorisent donc le classement correct de ceux dont la véritable classe est la classe majoritaire, car ils se produisent beaucoup plus souvent et contribuent donc beaucoup plus à la précision globale.

met=[ metrics.recall_score, specificity_score, metrics.balanced_accuracy_score ]
calc_metrics(met, ytest, hardpredtst_tuned_thresh)



Création de chaque jeu de données d'échantillon de démarrage et calcul des métriques pour celui-ci

 
 
Dans raw_metric_samples(), nous allons en fait générer plusieurs exemples de jeux de données un par un et enregistrer les métriques de chacun :

Vous donnez à raw_metric_samples() une liste de métriques (ou une seule métrique) d'intérêt ainsi que les données de classe vraies et prédites, et il obtient des exemples d'ensembles de données nboots et renvoie une trame de données avec uniquement les valeurs des métriques calculées à partir de chaque ensemble de données. Grâce à _boot_generator(), il invoque one_boot() un à la fois dans une expression de générateur plutôt que de stocker tous les ensembles de données à la fois en tant que potentiellement-majeur liste.

Examinez les métriques sur 7 exemples d'ensembles de données de démarrage

 
 
Nous faisons notre liste de fonctions métriques et invoquons raw_metric_samples() pour obtenir les résultats pour seulement 7 exemples de jeux de données. Nous invoquons ici raw_metric_samples() pour comprendre - il n'est pas nécessaire d'obtenir des intervalles de confiance en utilisant ci_auto() ci-dessous, bien qu'en spécifiant une liste de métriques (ou juste une métrique) pour ci_auto() is nécessaire.

np.random.seed(13)
raw_metric_samples(met, ytest, hardpredtst_tuned_thresh, nboots=7).style.format('{:.2%}') #optional #style



Chaque colonne ci-dessus contient les métriques calculées à partir d'un ensemble de données d'échantillon de démarrage (numéroté de 0 à 6), de sorte que les valeurs de métrique calculées varient en raison de l'échantillonnage aléatoire.

Nombre d'ensembles de données de démarrage, avec valeur par défaut calculée

 
 
Dans notre implémentation, par défaut, le nombre de jeux de données de démarrage nboots sera calculé automatiquement à partir du niveau de confiance souhaité (par exemple 95%) afin de répondre à la recommandation en Nord, Curtis et Sham pour avoir un nombre minimum de résultats de démarrage dans chaque queue de la distribution. (En fait, cette recommandation s'applique aux p-valeurs et donc test d'hypothèse régions d'acceptation, mais intervalles de confiance sont suffisamment similaires à ceux pour l'utiliser comme règle générale.) Bien que ces auteurs recommandent un minimum de 10 résultats de démarrage dans la queue, Davidson et MacKinnon recommandons au moins 399 bottes pour une confiance de 95 %, ce qui nécessite 11 bottes dans la queue, nous utilisons donc cette recommandation plus conservatrice.

Nous spécifions alpha qui est 1 – niveau de confiance. Par exemple, une confiance de 95 % devient 0.95 et alpha = 0.05. Si vous spécifiez un nombre explicite de démarrages (peut-être un plus petit nboots parce que vous voulez des résultats plus rapides) mais ce n'est pas suffisant pour votre alpha demandé, un alpha plus élevé sera choisi automatiquement afin d'obtenir un intervalle de confiance précis pour ce nombre de démarrages. Un minimum de 51 bottes sera utilisé parce que moins ne peut calculer avec précision que des niveaux de confiance bizarrement petits (comme une confiance de 40 % qui donne un intervalle entre les 30th centile au 70th centile, qui a 40 % à l'intérieur de l'intervalle mais 60 % à l'extérieur) et il n'est pas clair que la recommandation de bottes minimales ait même envisagé un tel cas.

La fonction get_alpha_nboots() définit les nboots par défaut ou modifie les alpha et nboots demandés comme ci-dessus :

Montrons les nboots par défaut pour différentes valeurs d'alpha :

g = get_alpha_nboots pd.DataFrame( [ g(0.40), g(0.20, None), g(0.10), g(), g(alpha=0.02), g(alpha=0.01, nboots=None), g(0.005, nboots=None) ], columns=['alpha', 'default nboots'] ).set_index('alpha')



Voici ce qui se passe si nous demandons un nboots explicite :

req=[(0.01,3000), (0.01,401), (0.01,2)]
out=[get_alpha_nboots(*args) for args in req]
mydf = lambda x: pd.DataFrame(x, columns=['alpha', 'nboots'])
pd.concat([mydf(req),mydf(out)],axis=1, keys=('Requested','Using'))



Les petites valeurs nboots ont augmenté alpha à 0.05 et 0.40, et nboots=2 est changé au minimum de 51.

Histogramme des ensembles de données d'échantillons bootstrap montrant l'intervalle de confiance uniquement pour la précision équilibrée

 
 
Encore une fois, nous n'avons pas besoin de le faire pour obtenir les intervalles de confiance ci-dessous en appelant ci_auto().

np.random.seed(13)
metric_boot_histogram (metrics.balanced_accuracy_score, ytest, hardpredtst_tuned_thresh)



La ligne orange indique 89.7 % comme limite inférieure de l'intervalle de confiance de la précision équilibrée, le vert pour la précision équilibrée originale observée = 92.4 % (estimation ponctuelle) et le rouge pour la limite supérieure de 94.7 %. (La même image apparaît en haut de cet article.)

Comment calculer tous les intervalles de confiance pour la liste des métriques

 
 
Voici la fonction principale qui invoque ce qui précède et calcule les intervalles de confiance à partir des centiles des résultats de la métrique, et insère les estimations ponctuelles dans la première colonne de sa base de données de résultats de sortie.

Calculez les résultats !

 
 
C'est tout ce que nous avions vraiment besoin de faire : invoquez ci_auto() comme suit avec une liste de métriques (met ci-dessus) pour obtenir leurs intervalles de confiance. Le formatage en pourcentage est facultatif :

np.random.seed(13)
ci_auto( met, ytest, hardpredtst_tuned_thresh ).style.format('{:.2%}')



Discussion des intervalles de confiance résultants

 
 
Voici la matrice de confusion de la article original. La classe 0 correspond aux négatifs (classe majoritaire) et la classe 1 correspond aux positifs (classe très rare)



Le rappel (taux de vrais positifs) de 134/(134+14) a l'intervalle de confiance le plus large car il s'agit d'une proportion binomiale impliquant de petits nombres.

La spécificité (vrai taux négatif) est de 80,388 80,388/(4,907 XNUMX+XNUMX XNUMX), ce qui implique beaucoup compte plus, donc il a un intervalle de confiance extrêmement étroit de seulement [94.11% à 94.40%].

Étant donné que la précision équilibrée est calculée comme une simple moyenne du rappel et de la spécificité, la largeur de son intervalle de confiance est intermédiaire entre la leur.

Imprécision de mesure métrique due aux variations des données de test, par rapport aux variations des données de train

 
 
Ici, nous n'avons pas considéré la variabilité de la modèle basé sur le caractère aléatoire de notre Formation données (bien que cela puisse également être intéressant à certaines fins, par exemple si vous avez automatisé des réentraînements répétés et que vous voulez savoir dans quelle mesure les performances des futurs modèles pourraient varier), mais plutôt uniquement la variabilité de la mesure des performances de ces particulier modèle (créé à partir de certaines données d'entraînement particulières) en raison du caractère aléatoire de notre tester revendre.

Si nous disposions de suffisamment de données de test indépendantes, nous pourrions mesurer très précisément les performances de ce modèle particulier sur la population sous-jacente, et nous saurions comment il fonctionnera si ce modèle est déployé, quelle que soit la manière dont nous avons construit le modèle et si nous pourrions obtenir un modèle meilleur ou pire avec un ensemble de données d'échantillon d'apprentissage différent.

Indépendance des instances individuelles

 
 
La méthode bootstrap suppose que chacune de vos instances (cas, observations) est tirée indépendamment d'une population sous-jacente. Si votre jeu de test comporte des groupes de lignes qui ne sont pas indépendants les uns des autres, par exemple des observations répétées de la même entité qui sont susceptibles d'être corrélées les unes avec les autres, ou des instances qui sont suréchantillonnées/répliquées/générées à partir d'autres instances de votre test défini, les résultats peuvent ne pas être valides. Vous devrez peut-être utiliser groupé l'échantillonnage, où vous rassemblez des groupes entiers au hasard plutôt que des lignes individuelles, tout en évitant de diviser un groupe ou d'en utiliser une partie.

Vous voulez également vous assurer que vous n'avez pas de groupes répartis entre l'ensemble d'entraînement et de test, car alors l'ensemble de test n'est pas nécessairement indépendant et vous pourriez obtenir un surajustement non détecté. Par exemple, si vous utilisez le suréchantillonnage, vous ne devriez généralement faire que après il a été séparé de l'ensemble de test, pas avant. Et normalement, vous suréchantillonnerez l'ensemble d'apprentissage mais pas l'ensemble de test, car l'ensemble de test doit rester représentatif des instances que le modèle verra lors d'un déploiement futur. Et pour la validation croisée, vous voudriez utiliser scikit-learn model_selection.GroupKFold().

Conclusion

 
 
Vous pouvez toujours calculer des intervalles de confiance pour vos métriques d'évaluation pour voir avec quelle précision vos données de test vous permettent de mesurer les performances de votre modèle. Je prévois un autre article pour démontrer les intervalles de confiance pour les métriques qui évaluent les prédictions de probabilité (ou les scores de confiance - sans rapport avec la confiance statistique), c'est-à-dire la classification douce, telle que Log Loss ou ROC AUC, plutôt que les métriques que nous avons utilisées ici qui évaluent le choix discret de la classe par le modèle (classification dure). Le même code fonctionne pour les deux, ainsi que pour la régression (prédire une variable cible continue) - il vous suffit de lui transmettre un type de prédiction différent (et un type différent de vraies cibles dans le cas d'une régression).

Ce notebook jupyter est disponible sur github : bootConfIntAutoV1o_standalone.ipynb

Cet article était-il informatif et/ou utile ? Veuillez poster un commentaire ci-dessous si vous avez des commentaires ou des questions sur cet article ou sur les intervalles de confiance, le bootstrap, le nombre de démarrages, cette implémentation, l'ensemble de données, le modèle, le déplacement du seuil ou les résultats.

En plus de ce qui précède article précédent, vous pourriez également être intéressé par mon Comment détecter automatiquement les colonnes Date/Datetime et définir leur type de données lors de la lecture d'un fichier CSV dans Pandas, bien qu'il ne soit pas directement lié au présent article.

Certains droits réservés

 
Bio: David B. Rosen (PhD) est responsable des données scientifiques pour l'approbation de crédit automatisée chez IBM Global Financing. Pour en savoir plus sur les écrits de David, rendez-vous sur dabruro.medium.com.

ORIGINALE. Republié avec permission.

Connexe:

Source : https://www.kdnuggets.com/2021/10/calculate-confidence-intervals-performance-metrics-machine-learning.html

Horodatage:

Plus de KDnuggetsGenericName