Scikit-learn: Suggestion : Supprimez la prédiction de plot_confusion_matrix et transmettez simplement les étiquettes prédites

CrĂ©Ă© le 13 dĂ©c. 2019  Â·  61Commentaires  Â·  Source: scikit-learn/scikit-learn

La signature de plot_confusion_matrix est actuellement :

sklearn.metrics.plot_confusion_matrix(estimator, X, y_true, labels=None, sample_weight=None, normalize=None, display_labels=None, include_values=True, xticks_rotation='horizontal', values_format=None, cmap='viridis', ax=None)

La fonction prend un estimateur et des donnĂ©es brutes et ne peut pas ĂȘtre utilisĂ©e avec des Ă©tiquettes dĂ©jĂ  prĂ©dites. Cela a quelques inconvĂ©nients:

  • Si une matrice de confusion doit ĂȘtre tracĂ©e mais que les prĂ©dictions doivent Ă©galement ĂȘtre utilisĂ©es ailleurs (par exemple, le calcul de precision_score), l'estimation doit ĂȘtre effectuĂ©e plusieurs fois. Cela prend plus de temps et peut donner des valeurs diffĂ©rentes si l'estimateur est randomisĂ©.
  • Si aucun estimateur n'est disponible (par exemple des prĂ©dictions chargĂ©es Ă  partir d'un fichier), le tracĂ© ne peut pas du tout ĂȘtre utilisĂ©.

Suggestion : autorisez le passage des Ă©tiquettes prĂ©dites y_pred Ă  plot_confusion_matrix qui seront utilisĂ©es Ă  la place de estimator et X . À mon avis, la solution la plus propre serait de supprimer l'Ă©tape de prĂ©diction de la fonction et d'utiliser une signature similaire Ă  celle de accuracy_score , par exemple (y_true, y_pred, labels=None, sample_weight=None, ...) . Cependant, afin de maintenir la compatibilitĂ© descendante, y_pred peut ĂȘtre ajoutĂ© comme argument de mot-clĂ© facultatif.

model_selection

Tous les 61 commentaires

Nous devrions certainement rester rétrocompatibles, mais l'ajout d'un argument de mot-clé y_pred me semble raisonnable. Nous devrions générer une erreur si y_pred est passé mais que X ou l'estimateur sont également passés.

Souhaitez-vous soumettre un PR @jhennrich ?

J'ai soumis un PR, mais je pense qu'il y a actuellement un problÚme avec le CI donc il n'est pas encore passé.

Je suis d'accord que nous devrions prendre en charge plot_XXX(y_true, y_pred) pour éviter de calculer la prédiction plusieurs fois.
Nous avons Ă©galement des problĂšmes similaires dans plot_roc_curve et plot_precision_recall_curve.
L'ajout de y_pred semble acceptable, mais honnĂȘtement, je ne pense pas que ce soit une bonne solution.
Pour les fonctions qui acceptent **kwargs (par exemple, plot_precision_recall_curve), semble-t-il impossible de rester rétrocompatible ?

Pourquoi est-il impossible de conserver la rétrocompatibilité ? Il me semble que la proposition en #15883 est OK

Pourquoi est-il impossible de conserver la rétrocompatibilité ? Il me semble que la proposition en #15883 est OK

car nous ne prenons pas en charge **kwargs dans plot_confusion_matrix. @NicolasHug

Pourquoi kwargs est-il un problĂšme ?

Hmm, donc il y a une autre chose ennuyeuse, nous supportons **kwargs dans plot_roc_curve et plot_precision_recall_curve (et plot_partial_dependence), mais nous ne le supportons pas dans plot_confusion_matrix

Pourquoi kwargs est-il un problĂšme ?

si nous ajoutons le nouveau paramÚtre avant **kwargs, nous pouvons conserver la compatibilité descendante, n'est-ce pas ?

Les modifications apportĂ©es Ă  mon PR sont rĂ©trocompatibles et **kwargs peut toujours ĂȘtre ajoutĂ©. Mais je suis d'accord avec @qinhanmin2014 , une solution beaucoup plus propre serait de jeter estimator et X et d'utiliser des arguments positionnels (y_true, y_pred, ...) qui sont cohĂ©rents avec la plupart des d'autres trucs sklearn.

si nous ajoutons le nouveau paramÚtre avant **kwargs, nous pouvons conserver la compatibilité descendante, n'est-ce pas ?

Oui

une solution beaucoup plus propre....

Malheureusement, cela nécessiterait un cycle de dépréciation (à moins que nous ne le rendions trÚs rapide dans la version de correction de bogues, mais j'en doute...)

@thomasjpfan , une raison de passer l'estimateur en entrée au lieu des prédictions ?

Merci, ajoutons d'abord y_pred, **kwags est un autre problĂšme.

Malheureusement, cela nécessiterait un cycle de dépréciation (à moins que nous ne le rendions trÚs rapide dans la version de correction de bogues, mais j'en doute...)

Cela semble impossible, soupir

@thomasjpfan , une raison de passer l'estimateur en entrée au lieu des prédictions ?

Je suis d'accord que nous devons reconsidérer la conception de notre API. essaie aussi de ping @amueller

Si un utilisateur souhaite fournir sa propre partie de traçage et fournir sa propre matrice de confusion :

from sklearn.metrics import ConfusionMatrixDisplay
confusion_matrix = confusion_matrix(...)
display_labels = [...]

disp = ConfusionMatrixDisplay(confusion_matrix=confusion_matrix,
                              display_labels=display_labels)
disp.plot(...)

Cela peut ĂȘtre fait de la mĂȘme maniĂšre pour les autres fonctions de traçage mĂ©trique.

Le plot_confusion_matrix est en quelque sorte conçu comme les scoreurs qui sont capables de gérer correctement la sortie des estimateurs. En d'autres termes, il s'agit d'un wrapper pratique pour interagir avec ConfusionMatrixDisplay et l'estimateur.

En acceptant d'abord l'estimateur, il existe une interface uniforme pour les fonctions de tracĂ©. Par exemple, le plot_partial_dependence effectue tous les calculs nĂ©cessaires Ă  la crĂ©ation des tracĂ©s de dĂ©pendance partielle et les transmet Ă  PartialDependenceDisplay . Un utilisateur peut toujours crĂ©er le PartialDependenceDisplay mĂȘme, mais dans ce cas, il serait plus impliquĂ©.

Bien que je sois ouvert Ă  avoir un "chemin rapide", permettant Ă  y_pred d'ĂȘtre transmis aux fonctions de traçage liĂ©es aux mĂ©triques, qui seront directement transmises Ă  confusion_matrix et le laissera s'occuper de la validation.

Le calcul des prédictions nécessaires pour construire un PDP est assez complexe. De plus, ces prédictions sont généralement inutilisables dans, par exemple, un marqueur ou une métrique. Ils ne sont utiles que pour tracer le PDP. Il est donc logique dans ce cas de n'accepter que l'estimateur dans plot_partial_dependence.

OTOH pour matrice de confusion, les prédictions ne sont en réalité que est.predict(X) .

Je ne pense pas que nous voulions une interface uniforme ici. Ce sont 2 cas d'utilisation d'entrée trÚs différents

EDIT : De plus, les PDP basĂ©s sur des arbres n'ont mĂȘme pas besoin de prĂ©dictions du tout

Il y a d'autres choses que nous rencontrerons sans l'estimateur. Par exemple, si plot_precision_recall_curve accepte y_pred , il aura besoin de pos_label car il ne peut plus ĂȘtre dĂ©duit. Dans ce cas, je prĂ©fĂ©rerais utiliser directement PrecisionRecallDisplay et demander Ă  l'utilisateur de calculer les paramĂštres nĂ©cessaires pour reconstruire le tracĂ©.

Cela revient à quel genre de question nous répondons avec cette API. L'interface actuelle tourne autour de l'évaluation d'un estimateur, utilisant ainsi l'estimateur comme argument. Il est motivé par la réponse « comment ce modÚle entraßné se comporte-t-il avec ces données d'entrée ? »

Si nous acceptons y_pred, y_true , la question devient alors "comment cette mĂ©trique se comporte-t-elle avec ces donnĂ©es ?" Ces donnĂ©es peuvent ou non ĂȘtre gĂ©nĂ©rĂ©es par un modĂšle.

Il est vrai que dans ce cas précis, @jhennrich vous pourriez directement utiliser le ConfusionMatrixDisplay.

Un inconvénient est que vous devez spécifier display_labels car il n'a pas de valeur par défaut.

@thomasjpfan pensez -vous que nous pourrions en général fournir des valeurs par défaut sensées pour les objets d'affichage, rendant ainsi toujours pratique l'utilisation directe des objets d'affichage ?

Pour certains paramĂštres, comme display_labels , il existe une valeur par dĂ©faut raisonnable. Les autres paramĂštres de l'objet Display peuvent Ă©galement avoir des valeurs par dĂ©faut raisonnables. Certains paramĂštres doivent cependant ĂȘtre fournis. Par exemple, confusion_matrix doit ĂȘtre fourni pour ConfusionMatrixDisplay ou precision et recall pour PrecisionRecallDisplay .

Un modÚle classique pour ce genre de chose définit :

ConfusionMatrixDisplay.from_estimator(...)
ConfusionMatrixDisplay.from_predictions(...)

mais ce n'est pas trĂšs idiomatique Ă  scikit-learn.

Je commence Ă  ĂȘtre confus. L'objectif de l'API actuelle est d'Ă©viter de calculer plusieurs fois si les utilisateurs souhaitent tracer plusieurs fois, mais si nous acceptons y_true et y_pred, les utilisateurs n'ont toujours pas besoin de calculer plusieurs fois ? (Je sais que les choses sont diffĂ©rentes dans PDP)

@jnothman Cette API est plutÎt jolie !

@qinhanmin2014 Passer un estimator, X, y ou y_true, y_pred fonctionne en satisfaisant l'API "ne pas calculer plusieurs fois". Dans les deux cas, la matrice de confusion est calculée et stockée dans l'objet Display .

La diffĂ©rence entre eux est l'endroit oĂč commence le calcul de la matrice de confusion. On peut considĂ©rer passer y_pred comme la valeur "prĂ©calculĂ©e" de l'estimateur.

Donc je pense que y_true, y_pred est meilleur que estimator, X, y (pas dans PDP bien sûr), parce que parfois (souvent ?) les utilisateurs veulent non seulement tracer les prédictions, mais aussi analyser les prédictions. Avec l'API actuelle, ils devront calculer les prédictions plusieurs fois.

Pour les métriques, je peux voir la préférence pour l'utilisation de y_true, y_pred sur estimator, X, y . Imaginez si le tracé des métriques ne prend en charge que y_true, y_pred

est = # fit estimator

plot_partial_dependence(est, X, ...)

# if plot_confusion_matrix accepts `y_true, y_pred`
y_pred = est.predict(X)
plot_confusion_matrix(y_true, y_pred, ...)

# if plot_roc_curve supports `y_true, y_score`
y_score = est.predict_proba(X)[: , 1]
plot_roc_curve(y_true, y_score, ...)
plot_precision_recall_curve(y_true, y_score, ...)

Actuellement, l'API ressemble à :

est = # fit estimator
plot_partial_dependence(est, X, ...)
plot_confusion_matrix(est, X, y, ...)
plot_roc_curve(est, X, y, ...)

# this will call `predict_proba` again
plot_precision_recall_curve(est, X, y, ...)

Je préférerais avoir une API qui prend en charge les deux options (d'une maniÚre ou d'une autre).

Pour les métriques, je peux voir la préférence pour l'utilisation de y_true, y_pred par rapport à l'estimateur, X, y. Imaginez si le tracé des métriques ne prend en charge que y_true, y_pred

Oui, c'est ce que je veux dire.

Je préférerais avoir une API qui prend en charge les deux options (d'une maniÚre ou d'une autre).

Je pense que c'est une solution pratique. Une chose ennuyeuse est que nous ne pouvons ajouter y_pred qu'Ă  la fin (c'est-Ă -dire plot_confusion_matrix(estimator, X, y_true, ..., y_pred))

Oui, ce sera à la fin et l'API ressemblera à ceci :

plot_confusion_matrix(y_true=y_true, y_pred=y_pred, ...)

avec lequel je pense que je suis d'accord. Il s'agit essentiellement du PR https://github.com/scikit-learn/scikit-learn/pull/15883

Oui ce sera Ă  la fin et l'API ressemblerait Ă  ceci plot_confusion_matrix(y_true=y_true, y_pred=y_pred, ...)

Je suppose que vous voulez dire que nous devrions ajouter y_true et supprimer est & X, n'est-ce pas ? Je suppose que c'est impossible ? (car on ne peut ajouter y_pred qu'à la fin)

Voulons-nous rĂ©soudre cela en 0.22.1 ? @NicolasHug @thomasjfox Je pense que cela vaut la peine de mettre cela dans 0.22.1, mais en mĂȘme temps, il semble que ce soit une nouvelle fonctionnalitĂ©.

Non, ne le mettez pas en 0.22.1. c'est une violation claire de sever

@qinhanmin2014 Ajouter y_pred Ă  la fin ou supprimer est, X semble ĂȘtre une nouvelle fonctionnalitĂ© qui appartient Ă  la prochaine version.

Je suppose que vous voulez dire que nous devrions ajouter y_true et supprimer est & X, n'est-ce pas ? Je suppose que c'est impossible ?

En fin de compte, je préférerais prendre en charge les deux interfaces, car elles ont des cas d'utilisation légÚrement différents.

  1. est, X est plus facile à faire une analyse rapide, car la fonction gÚre le choix de la fonction de réponse, le découpage du résultat et sa transmission à la métrique.
  2. y_true, y_pred est destiné aux utilisateurs qui comprennent comment utiliser la métrique sous-jacente et qui ont déjà enregistré les prédictions.

Quel est le problĂšme avec https://github.com/scikit-learn/scikit-learn/issues/15880#issuecomment -565489619 ?

Je n'ai pas lu tout ce fil mais si nous autorisons l'interface ici, nous devons Ă©galement le faire pour plot_roc_curve oĂč l'interface sera assez diffĂ©rente entre fournir des prĂ©dictions et fournir l'estimateur (l'un a besoin de pos_label l'autre ne 't).
Je pense donc qu'autoriser les deux dans la mĂȘme interface est une mauvaise idĂ©e (quelqu'un passera pos_label lors du passage d'un estimateur et obtiendra un rĂ©sultat auquel il ne s'attend pas).

ConfusionMatrixDisplay.from_estimator(...)
ConfusionMatrixDisplay.from_predictions(...)

Cela pourrait fonctionner, mais cela rendrait le plot_confusion_matrix redondant, et donc nous supprimerions à nouveau les fonctions et modifierions les responsabilités entre la classe et la fonction (nous avons dit que la classe ne fait pas le calcul).

Si nous voulons ajouter un from_predictions à plot_roc_curve il doit essentiellement refléter parfaitement l'interface roc_curve . Donc, je ne pense pas qu'il soit trop mauvais de demander à l'utilisateur d'appeler directement la fonction roc_curve , puis de transmettre les résultats à l'objet Display.

Tout le but de la conception des objets d'affichage était de permettre le cas d'utilisation mentionné par @jhennrich et pourquoi nous avons séparé le calcul de la fonction. Je n'ai pas encore vu d'argument expliquant pourquoi nous devrions revenir sur cette décision.

@amueller Techniquement, vous avez raison, la solution actuelle Ă  mon problĂšme consiste simplement Ă  utiliser ConfusionMatrixDisplay . Cependant il est vraiment maladroit Ă  utiliser :

  • vous devez passer les Ă©tiquettes explicitement
  • vous devez d'abord calculer la matrice de confusion
  • vous devez crĂ©er un objet de la classe et ensuite appeler la mĂ©thode plot

Pour toutes les applications, je peux penser Ă  une signature plot_confusion_matrix avec (y_true, y_pred, ...) serait beaucoup plus pratique que ce que nous avons actuellement. À mon avis, il existe beaucoup plus de cas d'utilisation dans lesquels vous souhaitez calculer explicitement les prĂ©dictions (bien que je sois sĂ»r que mon point de vue est biaisĂ©).

Si vous avez une signature plot_confusion_matrix(y_true, y_pred) et que vous voulez réellement l'utiliser sur des données estimator , x , y , il n'y a que trÚs peu de code supplémentaire à écrire : plot_confusion_matrix(y, estimator.predict(x)) .
En comparaison, si vous avez la signature actuelle et que vous souhaitez tracer Ă  partir de y_true et y_pred , vous devez Ă©crire beaucoup plus de code.

À mon avis, la signature plot_confusion_matrix(y_true, y_pred) devrait ĂȘtre par dĂ©faut et une autre fonction qui prend estimator , x , y devrait ĂȘtre construite par dessus.

Enfin, honnĂȘtement, je ne comprends pas vraiment l'idĂ©e derriĂšre la classe ConfusionMatrixDisplay . La fonction n'a qu'un seul constructeur et exactement une mĂ©thode, donc chaque fois que vous l'utilisez, vous finissez par crĂ©er une instance et appeler la fonction plot . Je ne vois pas pourquoi cela devrait ĂȘtre une classe et pas seulement une fonction. Il existe Ă©galement d'autres classes *Display (PrecisionRecall, ROC, ...), mais leurs signatures constructeur et plot() sont complĂštement diffĂ©rentes, elles ne peuvent donc pas ĂȘtre Ă©changĂ©es de toute façon.
Peut-ĂȘtre que cela dĂ©passe le cadre de ce problĂšme.

@jhennrich

Si vous avez une signature plot_confusion_matrix(y_true, y_pred) et que vous souhaitez réellement l'utiliser sur l'estimateur, les données x, y, il n'y a que trÚs peu de code supplémentaire à écrire : plot_confusion_matrix(y, estimator.predict(x)).

Pour le cas de la matrice de confusion, il est simple de passer estimator.predict si on avait une interface y_true, y_pred . D'un autre cÎté, pour plot_roc_auc , l'utilisateur aurait besoin de faire du slicing :

y_pred = est.predict_proba(X)
plot_roc_curve(y_true, y_pred[:, 1])

# or
y_pred = est.decision_function(X)
plot_roc_curve(y_true, y_pred[:, 1])

Enfin, honnĂȘtement, je ne comprends pas vraiment l'idĂ©e derriĂšre la classe ConfusionMatrixDisplay. La fonction n'a qu'un seul constructeur et exactement une mĂ©thode, donc chaque fois que vous l'utilisez, vous finissez par crĂ©er une instance et appeler la fonction plot. Je ne vois pas pourquoi cela devrait ĂȘtre une classe et pas seulement une fonction.

Le but des objets Display est de stocker les valeurs calculĂ©es permettant aux utilisateurs d'appeler plot plusieurs fois sans recalculer. Cela peut ĂȘtre vu en utilisant plot_partial_dependence :

# Does expensive computation
disp = plot_partial_dependence(est, ...)

# change line color without needing to recompute partial dependence
disp.plot(line_kw={"c": "red"})

HonnĂȘtement, je suis sur la clĂŽture sur cette question. Je suis +0,1 pour me dĂ©placer vers la copie de l'interface des mĂ©triques pour le traçage des mĂ©triques et la suppression de l'interface est, X, y . :/

Pour le cas de la matrice de confusion, il est simple de passer dans estimateur.predict si on avait une interface y_true, y_pred. En revanche, pour plot_roc_auc, l'utilisateur aurait besoin de faire du slicing :

Oui, mais ce faisant, nous évitons de calculer la prédiction plusieurs fois (bien que la prédiction ne soit souvent pas si chÚre)

Peut-ĂȘtre qu'une solution pratique consiste Ă  prendre en charge y_true, y_pred dans plot_XXX (le cas Ă©chĂ©ant) en 0.23.

@jhennrich Comment allez-vous faire cela sans passer explicitement les Ă©tiquettes? Si les Ă©tiquettes peuvent ĂȘtre dĂ©duites de ce qui est donnĂ©, confusion_matrix fera pour vous.

Mais effectivement tu as raison, c'est trois lignes au lieu d'une.

Dans le cas de confusion_matrix, j'ai tendance Ă  convenir que le cas le plus courant pourrait ĂȘtre le passage de y_true et y_pred .
La raison pour laquelle l'interface est actuellement telle qu'elle est est d'ĂȘtre cohĂ©rente avec les autres fonctions de traçage mĂ©trique. Comme l'a dit @thomasjpfan , la courbe roc est moins Ă©vidente Ă  tracer.

À l'heure actuelle, le code pour tracer une matrice de confusion et tracer une courbe roc est le mĂȘme. Avec la modification que vous suggĂ©rez, ils ne seront plus les mĂȘmes et il n'y aura pas de moyen facile de les rendre identiques.

La question est de savoir si dans ce cas il est préférable d'avoir des interfaces cohérentes ou d'avoir une interface simple.
@jhennrich Pour moi, la vraie question est de savoir quelle est la bonne interface pour plot_roc_curve . Avez-vous des idées là-dessus?

@thomasjpfan penchez -vous Ă©galement pour prendre y_store pour tracer roc auc?

Il y a certainement des avantages et des inconvénients à utiliser l'interface de score au lieu d'utiliser l'interface métrique. Mais pour des choses plus complexes, il est beaucoup plus sûr d'utiliser l'interface de score.

@qinhanmin2014
Je pense que ce serait bien d'ajouter y_pred à plot_confusion_matrix . La question est de savoir si nous voulons ajouter y_score à plot_roc_curve et plot_precision_recall_curve . Si nous le faisons, nous devons également ajouter pos_label comme je l'ai dit plus haut, et les choses deviendront plus compliquées.

Je vois trois façons de s'en sortir :
a) Ajoutez seulement y_pred à plot_confusion_matrix , mais n'ajoutez pas y_score à plot_roc_curve etc. Inconvénient : le problÚme d'appeler predict_proba plusieurs fois continue d'exister pour ces métriques.
b) Facilitez l'utilisation directe de l'objet Display (bien que je ne sache pas vraiment comment).
c) Ajoutez une autre méthode ou fonction qui reflÚte l'interface métrique. Inconvénient : plus grande surface API.

Je ne pense pas que le fait que la fonction plot_X reflÚte à la fois l'interface de score et l'interface métrique soit une bonne idée en général.

Je pense que ce serait formidable de rĂ©soudre ce problĂšme d'une maniĂšre ou d'une autre @adrinjalali voulez-vous en discuter lors de la prochaine rĂ©union peut-ĂȘtre ?

J'ai parfois des cauchemars Ă  ce sujet. Peut-ĂȘtre pouvons-nous ajouter une mĂ©thode statique qui prend directement la sortie de la mĂ©trique :

result = confusion_matrix(...)
ConfusionMatrixDisplay.from_metric(result).plot()

Pour la courbe roc :

result = roc_curve(...)
RocCurveDisplay.from_metric(*result).plot()

En passant, en regardant les bases de code, je pense que plus d'utilisateurs sont familiers avec l'interface de métriques que l'interface de score.

J'ai parfois des cauchemars Ă  ce sujet.

Oh non :(

En passant, en regardant les bases de code, je pense que plus d'utilisateurs sont familiers avec l'interface de métriques que l'interface de score.

Je pense que c'est certainement vrai. Mais je suis également tout à fait certain que les gens utilisent y_pred alors qu'ils devraient utiliser y_score et obtiennent de mauvais résultats parce que l'interface ne vous dit pas que vous devez faire quelque chose de différent et non- on lit jamais les docs.

Je ne sais pas en quoi la mĂ©thode statique que vous proposez est diffĂ©rente du constructeur, mais j'oublie peut-ĂȘtre quelque chose.

Salut, je viens de voter pour le problÚme - en tant qu'utilisateur de longue date de sklearn, j'ai trouvé l'API actuelle pour plot_confusion_matrix trÚs... eh bien, déroutante. J'aime beaucoup son ajout (moins de copier-coller), mais les fonctions de métriques ont toujours utilisé le schéma (y_true, y_pred) qui est juste plus flexible et auquel j'ai déjà été habitué.

Dans mon cas, cela n'a pas de sens de transmettre un estimateur, car c'est un modĂšle trĂšs lent et je prĂ©fĂšre charger les prĂ©dictions Ă  partir d'un fichier que de le rĂ©exĂ©cuter chaque fois que je veux analyser les rĂ©sultats. Je suis heureux d'avoir dĂ©couvert dans ce fil qu'il existe une solution de contournement Ă  l'aide de l'objet * Display, mais sa capacitĂ© de dĂ©couverte n'est pas excellente - je suggĂ©rerais au moins de l'ajouter Ă  la documentation plot_confusion_matrix ou peut-ĂȘtre au guide de l'utilisateur de la matrice de confusion ?

Dans mon cas, cela n'a pas de sens de passer un estimateur, car c'est un modÚle trÚs lent et je préfÚre charger les prédictions

Merci pour votre contribution. Si l'API actuelle prĂȘte Ă  confusion, il serait de plus en plus logique de passer Ă  une interface de type API de mĂ©triques et de traverser un cycle de dĂ©prĂ©ciation douloureux.

La plus grande préoccupation que nous avons avec l'utilisation de l'interface des métriques est :

Mais je suis également certain que les gens utilisent y_pred alors qu'ils devraient utiliser y_score et obtiennent de mauvais résultats parce que l'interface ne vous dit pas que vous devez faire quelque chose de différent et que personne ne lit jamais les documents.

@pzelasko Que

@thomasjpfan Je comprends le problĂšme, c'est un problĂšme difficile. Peut-ĂȘtre qu'un compromis raisonnable serait de n'autoriser que les arguments de mot-clĂ© pour cette fonction (maintenant que vous n'avez plus besoin de prendre en charge Python 2) ? Comme : def plot_confusion_matrix(*, y_true, y_pred, ...) . C'est toujours diffĂ©rent du reste des mĂ©triques, mais 1) il a une bonne raison pour cela, 2) il utilise au moins le mĂȘme type d'entrĂ©es que les autres fonctions.

Quoi qu'il en soit, je sais pourquoi vous hésitez à apporter des modifications à l'API, c'est pourquoi j'ai suggéré de mentionner au moins la solution de contournement dans la documentation. (En fait, je les ai lus plusieurs fois et je les apprécie vraiment !)

La façon actuelle d'utiliser y_true et y_pred est indiquée ici : https://scikit-learn.org/stable/auto_examples/miscellaneous/plot_display_object_visualization.html#create -confusionmatrixdisplay

Je sais que je m'étire ici, mais qu'en est-il de ceci :

plot_confusion_matrix(estimator='precomputed', y_true, y_pred, ...)

oĂč la deuxiĂšme position accepte y_true comme prĂ©dictions si estimator='precomputed .

si vous voulez vous étirer encore plus, je préférerais plot_confusion_matrix((estimator, X, y), ...) ou plot_confusion_matrix((y_true, y_pred), ...) mais je ne suis pas sûr que cela résolve les problÚmes soulevés par

Il existe quelques nouveaux utilitaires de traçage oĂč autoriser une API metric aurait vraiment du sens :

Je comprends le problÚme mentionné par @amueller concernant la nécessité de transmettre pos_label etc., mais ce n'est un problÚme pour aucune des fonctions susmentionnées.

Sommes-nous d'accord pour prendre en charge à la fois l'API des marqueurs et des métriques pour ces deux ? Nous n'avons pas à nous soucier de la compatibilité descendante là-bas.

Je suis toujours pour ma suggestion d'utiliser precomputed , que nous utilisons couramment dans nos estimateurs. Dans ce cas, la signature serait :

plot_confusion_matrix(estimator='precomputed', y_true, y_pred, ..., metric_kwargs=None)

Je vais mettre en place des relations publiques pour voir Ă  quoi cela ressemble.

Je ne parle pas encore vraiment de l'API, je demande seulement si nous sommes d'accord pour prendre en charge les deux options pour les nouveaux PR.

(Mais en ce qui concerne l'API, je ne pense pas que 'prĂ©calculĂ©' aide beaucoup: que faisons-nous Ă  propos de X ? Je pense que nous devrions simplement garder (y_pred) et (estimateur, X) mutuellement exclusifs, en faisant correctement une erreur . Qu'est-ce que cela signifie Ă©galement pour un estimateur d'ĂȘtre prĂ©calculé ?)

Ou estimator='none' , estimator='predictions' , estimator='precomputed_predictions' , puis X devient y_pred ou y_score . C'est presque comme la façon dont nous gérons les distances précalculées avec X dans les estimateurs.

Sommes-nous d'accord pour prendre en charge à la fois l'API des marqueurs et des métriques pour ces deux ?

Comment allons-nous soutenir les deux options? Avec deux fonctions ?

j'aurais aimé aussi :

CalibrationDisplay.from_estimator(...)
CalibrationDisplay.from_predictions(...)

ce qui serait deux méthodes.

La suggestion de Guillaume d'utiliser des tuples https://github.com/scikit-learn/scikit-learn/issues/15880#issuecomment -670590882 est une option. Je pense que cela aurait été la meilleure option si nous étions partis de là depuis le début. Mais je crains que l'utilisation de tuples ne rompe la cohérence avec les utilitaires existants.

plot_XYZ(estimator=None, X=None, y=None, y_pred=None) avec exclusion mutuelle est une autre option, et c'est celle que je défends, pour l'instant.

J'aime CalibrationDisplay.from_estimator(...) , mais comme Andy l'a notĂ©, nous devrions alors supprimer les fonctions plot_XYZ . Cela vaut peut-ĂȘtre le coup d'y rĂ©flĂ©chir.

Je pense que nous pouvons passer aux tuples et déprécier le comportement actuel. (Tant que nous acceptons d'utiliser des tuples)

Cela ressemble donc à une discussion sur les espaces de noms, n'est-ce pas ?
Que nous ayons une fonction et un constructeur, ou deux mĂ©thodes de classe, ou deux fonctions, c'est exactement la mĂȘme fonctionnalitĂ© et fondamentalement le mĂȘme code.

@pzelasko @jhennrich que

Et si vous prĂ©fĂ©rez deux fonctions ou deux mĂ©thodes de classe, voyez-vous un avantage malgrĂ© la dĂ©couvrabilitĂ© ? La dĂ©couvrabilitĂ© pourrait ĂȘtre une raison suffisante pour faire des classmethods, je ne vois pas d'argument solide pour avoir deux fonctions.

Pourrions-nous ajouter l'Ă©tiquette de bloqueur ici ? Il semble que cela empĂȘche de progresser sur les #18020 et #17443 (cc @cmarmo)

L'Ă©tiquette de bloqueur est pour les bloqueurs de version (choses qui doivent absolument ĂȘtre corrigĂ©es avant une version), pas pour les bloqueurs de relations publiques

Ahh bon Ă  savoir.

@pzelasko @jhennrich que

Et si vous prĂ©fĂ©rez deux fonctions ou deux mĂ©thodes de classe, voyez-vous un avantage malgrĂ© la dĂ©couvrabilitĂ© ? La dĂ©couvrabilitĂ© pourrait ĂȘtre une raison suffisante pour faire des classmethods, je ne vois pas d'argument solide pour avoir deux fonctions.

J'aime le plus l'approche à deux classes, en particulier le modÚle from_xxx - quelque chose comme @thomasjpfan proposé :

CalibrationDisplay.from_estimator(...)
CalibrationDisplay.from_predictions(...)

On dirait qu'il n'y a pas de forte opposition à l'utilisation de méthodes de classe 2, alors faisons-le. Nous devrons :

  • PrĂ©sentez les mĂ©thodes de classe pour les parcelles actuellement existantes :

    • ConfusionMatrixDisplay
    • PrecisionRecallDisplay
    • RocCurveDisplay
    • DetCurveDisplay
    • PartialDependenceDisplay . Pour celui-ci, nous ne voulons pas introduire la mĂ©thode from_predictions classe from_estimator .
  • Pour tous les Ă©crans rĂ©pertoriĂ©s ci-dessus, dĂ©sapprouvez leur fonction plot_... correspondante. Nous n'avons pas besoin de dĂ©prĂ©cier plot_det_curve car il n'a pas encore Ă©tĂ© publiĂ©, nous pouvons simplement le supprimer.

  • pour les nouveaux PR comme #17443 et #18020, nous pouvons implĂ©menter les mĂ©thodes de classe immĂ©diatement au lieu d'introduire une fonction plot .

C'est un peu de travail mais je pense que nous pouvons le faire avant 0.24 afin que #17443 et #18020 puissent déjà avancer.

Une objection @thomasjpfan @jnothman @amueller @glemaitre ?

@jhennrich @pzelasko , seriez-vous intéressé à soumettre un PR pour introduire les méthodes de classe dans l'un des objets Display ?

Merci d'avoir pris la décision @NicolasHug ! Je vais passer au #17443 (aprÚs avoir attendu les objections)

Je n'ai aucune objection.

Aucune objection non plus.

Je m'occuperai alors des autres classes et avancerai mon RP bloqué.
@lucyleeow au cas oĂč je n'aurais pas fait tout cela et que vous recherchez des

J'adorerais contribuer mais je suis engagé dans trop de projets en ce moment. Merci d'avoir écouté les suggestions!

Ça a l'air bien :)

Cette page vous a été utile?
0 / 5 - 0 notes