Scikit-learn: Vorschlag: Entfernen Sie die Vorhersage aus plot_confusion_matrix und übergeben Sie einfach die vorhergesagten Labels

Erstellt am 13. Dez. 2019  ·  61Kommentare  ·  Quelle: scikit-learn/scikit-learn

Die Signatur von plot_confusion_matrix ist derzeit:

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)

Die Funktion verwendet einen Schätzer und Rohdaten und kann nicht mit bereits vorhergesagten Labels verwendet werden. Dies hat einige Nachteile:

  • Soll eine Konfusionsmatrix erstellt werden, die Vorhersagen aber auch an anderer Stelle verwendet werden (z. B. Accuracy_score berechnen), muss die Schätzung mehrmals durchgeführt werden. Das dauert länger und kann zu unterschiedlichen Werten führen, wenn der Schätzer randomisiert wird.
  • Wenn kein Schätzer verfügbar ist (zB Vorhersagen aus einer Datei geladen), kann der Plot überhaupt nicht verwendet werden.

Vorschlag: Übergeben Sie vorhergesagte Labels y_pred an plot_confusion_matrix , die anstelle von estimator und X . Meiner Meinung nach wäre die sauberste Lösung, den Vorhersageschritt aus der Funktion zu entfernen und eine Signatur ähnlich der von accuracy_score , zB (y_true, y_pred, labels=None, sample_weight=None, ...) . Um jedoch die Abwärtskompatibilität aufrechtzuerhalten, kann y_pred als optionales Schlüsselwortargument hinzugefügt werden.

model_selection

Alle 61 Kommentare

Wir sollten auf jeden Fall abwärtskompatibel bleiben, aber das Hinzufügen eines y_pred Schlüsselwortarguments klingt für mich vernünftig. Wir sollten einen Fehler ausgeben, wenn y_pred übergeben wird, aber auch X oder Schätzer übergeben werden.

Möchten Sie eine PR @jhennrich einreichen ?

Ich habe eine PR eingereicht, aber ich denke, es gibt derzeit ein Problem mit dem CI, daher ist es noch nicht bestanden.

Ich stimme zu, dass wir plot_XXX(y_true, y_pred) , um zu vermeiden, dass die Vorhersage mehrmals berechnet wird.
Ähnliche Probleme haben wir auch in plot_roc_curve und plot_precision_recall_curve.
Das Hinzufügen von y_pred scheint akzeptabel, aber ehrlich gesagt glaube ich nicht, dass es eine gute Lösung ist.
Für die Funktionen, die **kwargs akzeptieren (zB plot_precision_recall_curve), scheint es unmöglich zu sein, rückwärtskompatibel zu bleiben?

Warum ist es unmöglich, die Abwärtskompatibilität aufrechtzuerhalten? Mir scheint, der Vorschlag in #15883 ist in Ordnung

Warum ist es unmöglich, die Abwärtskompatibilität aufrechtzuerhalten? Mir scheint, der Vorschlag in #15883 ist in Ordnung

weil wir **kwargs in plot_confusion_matrix nicht unterstützen. @NicolasHug

Warum sind Kwargs ein Problem?

Hmm, es gibt noch eine andere nervige Sache, wir unterstützen **kwargs in plot_roc_curve und plot_precision_recall_curve (und plot_partial_dependence), aber wir unterstützen es nicht in plot_confusion_matrix

Warum sind Kwargs ein Problem?

Wenn wir den neuen Parameter vor **kwargs hinzufügen, können wir die Abwärtskompatibilität beibehalten, oder?

Die Änderungen in meinem PR sind abwärtskompatibel und **kwargs können noch hinzugefügt werden. Aber ich stimme @qinhanmin2014 zu , eine viel sauberere Lösung wäre es, estimator und X wegzulassen und Positionsargumente (y_true, y_pred, ...) zu verwenden, die mit den meisten übereinstimmen andere sklearn-Sachen.

Wenn wir den neuen Parameter vor **kwargs hinzufügen, können wir die Abwärtskompatibilität beibehalten, oder?

Jawohl

eine viel sauberere Lösung....

Leider würde dies einen Deprecation-Zyklus erfordern (es sei denn, wir machen es in der Bugfix-Version sehr schnell, aber ich bezweifle es ...)

@thomasjpfan , gibt es einen Grund, den Schätzer als Eingabe anstelle der Vorhersagen zu übergeben?

Danke, fügen wir zuerst y_pred hinzu, **kwags ist ein weiteres Problem.

Leider würde dies einen Deprecation-Zyklus erfordern (es sei denn, wir machen es in der Bugfix-Version sehr schnell, aber ich bezweifle es ...)

Das scheint unmöglich, seufz

@thomasjpfan , gibt es einen Grund, den Schätzer als Eingabe anstelle der Vorhersagen zu übergeben?

Ich stimme zu, dass wir unser API-Design überdenken müssen. Versuchen Sie auch, @amueller zu

Wenn ein Benutzer seinen eigenen Plotteil und seine eigene Verwirrungsmatrix bereitstellen möchte:

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

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

Dies kann ähnlich für die anderen metrischen Plotting-Funktionen durchgeführt werden.

Der plot_confusion_matrix ist wie die Scorer gestaltet, die mit der Ausgabe von Schätzern gut umgehen können. Mit anderen Worten, es ist ein praktischer Wrapper für die Interaktion mit ConfusionMatrixDisplay und dem Schätzer.

Indem zuerst der Schätzer akzeptiert wird, gibt es eine einheitliche Schnittstelle für die Plotfunktionen. Zum Beispiel führt plot_partial_dependence alle Berechnungen durch, die zum Erstellen der partiellen Abhängigkeitsdiagramme erforderlich sind, und übergibt sie an PartialDependenceDisplay . Ein Benutzer kann die PartialDependenceDisplay immer noch selbst erstellen, aber in diesem Fall wäre es komplizierter.

Ich bin jedoch offen für einen "schnellen Weg", der es ermöglicht, y_pred an die metrischen Plotting-Funktionen zu übergeben, die direkt an confusion_matrix und die Validierung übernehmen.

Die Berechnung der Vorhersagen, die zum Erstellen eines PDPs erforderlich sind, ist ziemlich komplex. Außerdem sind diese Vorhersagen in der Regel beispielsweise in einem Scorer oder einer Metrik unbrauchbar. Sie sind nur zum Plotten der PDP nützlich. Daher ist es in diesem Fall sinnvoll, den Schätzer nur in plot_partial_dependence zu akzeptieren.

OTOH für Verwirrungsmatrix, die Vorhersagen sind wirklich nur est.predict(X) .

Ich glaube nicht, dass wir hier eine einheitliche Schnittstelle wollen. Dies sind 2 sehr unterschiedliche Anwendungsfälle für die Eingabe

BEARBEITEN: Darüber hinaus benötigen die baumbasierten PDPs überhaupt keine Vorhersagen

Es gibt andere Dinge, auf die wir ohne den Schätzer stoßen werden. Wenn beispielsweise plot_precision_recall_curve y_pred akzeptieren würde, benötigt es pos_label da es nicht mehr abgeleitet werden kann. In diesem Fall würde ich es vorziehen, PrecisionRecallDisplay direkt zu verwenden und den Benutzer die Parameter berechnen zu lassen, die zum Rekonstruieren des Plots erforderlich sind.

Dies hängt davon ab, welche Art von Frage wir mit dieser API beantworten. Die aktuelle Schnittstelle dreht sich um die Auswertung eines Schätzers und verwendet daher den Schätzer als Argument. Es wird motiviert durch die Antwort "Wie verhält sich dieses trainierte Modell mit diesen Eingabedaten?"

Wenn wir y_pred, y_true akzeptieren, stellt sich nun die Frage: "Wie verhält sich dieser Messwert mit diesen Daten?" Diese Daten können von einem Modell generiert werden oder nicht.

Es stimmt, dass Sie in diesem speziellen Fall @jhennrich direkt das ConfusionMatrixDisplay verwenden könnten.

Ein Nachteil ist, dass Sie display_labels angeben müssen, da es keinen Standardwert hat.

@thomasjpfan denken Sie, wir könnten im Allgemeinen vernünftige Standardwerte für die Display-Objekte bereitstellen und so die direkte Verwendung der Display-Objekte immer noch praktikabel machen?

Für einige Parameter wie display_labels gibt es einen vernünftigen Standardwert. Die anderen Display Objektparameter können ebenfalls vernünftige Standardwerte haben. Einige Parameter müssen angegeben werden. Beispielsweise muss confusion_matrix für ConfusionMatrixDisplay oder precision und recall für PrecisionRecallDisplay .

Ein klassisches Muster für so etwas ist das Definieren:

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

aber das ist nicht sehr idiomatisch zu lernen.

Ich fange an verwirrt zu werden. Das Ziel der aktuellen API ist es zu vermeiden, mehrfach zu berechnen, wenn Benutzer mehrfach plotten möchten, aber wenn wir y_true und y_pred akzeptieren, müssen Benutzer immer noch nicht mehrfach rechnen? (Ich weiß, dass die Dinge bei PDP anders sind)

@jnothman Diese API

@qinhanmin2014 Das Übergeben von estimator, X, y oder y_true, y_pred erfüllt die API "nicht mehrmals berechnen". In beiden Fällen wird die Konfusionsmatrix berechnet und im Objekt Display gespeichert.

Der Unterschied zwischen ihnen besteht darin, wo die Berechnung der Konfusionsmatrix beginnt. Man kann sich y_pred als den "vorberechneten" Wert des Schätzers vorstellen.

Also denke ich, dass y_true, y_pred besser ist als estimator, X, y (natürlich nicht in PDP), weil Benutzer manchmal (oft?) die Vorhersagen nicht nur darstellen, sondern auch analysieren möchten. Mit der aktuellen API müssen sie die Vorhersagen mehrmals berechnen.

Bei Metriken kann ich die Präferenz für die Verwendung von y_true, y_pred gegenüber estimator, X, y . Stellen Sie sich vor, die Darstellung von Metriken unterstützt nur 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, ...)

Derzeit sieht die API so aus:

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, ...)

Ich würde es vorziehen, eine API zu haben, die beide Optionen (irgendwie) unterstützt.

Bei Metriken kann ich die Präferenz für die Verwendung von y_true, y_pred gegenüber Schätzer, X, y erkennen. Stellen Sie sich vor, die Darstellung von Metriken unterstützt nur y_true, y_pred

Ja, das meine ich.

Ich würde es vorziehen, eine API zu haben, die beide Optionen (irgendwie) unterstützt.

Ich denke, das ist eine praktische Lösung. Ärgerlich ist, dass wir y_pred nur am Ende hinzufügen können (dh plot_confusion_matrix(estimator, X, y_true, ..., y_pred))

Ja, es wird am Ende sein und die API würde so aussehen:

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

womit ich meiner Meinung nach in Ordnung bin. Dies ist im Wesentlichen die PR https://github.com/scikit-learn/scikit-learn/pull/15883

Ja, es wird am Ende sein und die API würde so aussehen plot_confusion_matrix(y_true=y_true, y_pred=y_pred, ...)

Ich denke, Sie meinen, wir sollten y_true hinzufügen und est & X entfernen, oder? Ich denke, es ist unmöglich? (weil wir y_pred nur am Ende hinzufügen können)

Wollen wir das in 0.22.1 lösen? @NicolasHug @thomasjfox Ich denke, es lohnt sich, dies in 0.22.1 zu setzen, aber gleichzeitig scheint dies eine neue Funktion zu sein.

Nein, geben Sie es nicht in 0.22.1 ein. es ist ein klarer Verstoß gegen semver

@qinhanmin2014 Das Hinzufügen von y_pred am Ende oder das Entfernen von est, X scheint eine neue Funktion zu sein, die in die nächste Version gehört.

Ich denke, Sie meinen, wir sollten y_true hinzufügen und est & X entfernen, oder? Ich denke, es ist unmöglich?

Am Ende würde ich es vorziehen, beide Schnittstellen zu unterstützen, da sie leicht unterschiedliche Anwendungsfälle haben.

  1. est, X ist einfacher, eine schnelle Analyse durchzuführen, da die Funktion die Auswahl der Antwortfunktion übernimmt, das Ergebnis in Slices zerlegt und an die Metrik übergibt.
  2. y_true, y_pred ist für Benutzer gedacht, die wissen, wie man mit der zugrunde liegenden Metrik arbeitet und die Vorhersagen bereits gespeichert haben.

Was ist das Problem bei https://github.com/scikit-learn/scikit-learn/issues/15880#issuecomment -565489619 ?

Ich habe diesen ganzen Thread nicht gelesen, aber wenn wir die Schnittstelle hier zulassen, müssen wir dies auch für plot_roc_curve tun, wobei die Schnittstelle zwischen der Bereitstellung von Vorhersagen und der Bereitstellung des Schätzers ziemlich unterschiedlich sein wird (einer benötigt pos_label, der andere nicht). 'T).
Daher halte ich es für eine schlechte Idee, beide in derselben Schnittstelle zuzulassen (jemand wird pos_label übergeben, wenn er einen Schätzer übergibt und ein Ergebnis erhält, das er nicht erwartet).

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

Könnte funktionieren, aber es würde plot_confusion_matrix im Grunde überflüssig machen, und so würden wir die Funktionen wieder entfernen und die Verantwortlichkeiten zwischen der Klasse und der Funktion ändern (wir sagten, dass die Klasse nicht die Berechnung übernimmt).

Wenn wir from_predictions zu plot_roc_curve hinzufügen möchten, muss es im Grunde die roc_curve Schnittstelle perfekt spiegeln. Daher finde ich es nicht so schlimm, wenn der Benutzer die Funktion roc_curve direkt aufruft und dann die Ergebnisse an das Display-Objekt übergibt.

Der ganze Zweck des Designs der Anzeigeobjekte bestand darin, den von @jhennrich erwähnten Anwendungsfall zu ermöglichen und warum wir die Berechnung von der Funktion getrennt haben. Ich habe noch kein Argument gesehen, warum wir von dieser Entscheidung zurücktreten sollten.

@amueller Technisch gesehen hast du Recht, die aktuelle Lösung für mein ConfusionMatrixDisplay . Allerdings ist die Bedienung wirklich umständlich:

  • du musst die etiketten explizit übergeben
  • du musst zuerst die Konfusionsmatrix berechnen
  • Sie müssen ein Objekt der Klasse erstellen und dann noch die Methode plot aufrufen

Für alle Anwendungen, die ich mir vorstellen kann, wäre eine plot_confusion_matrix Signatur mit (y_true, y_pred, ...) viel bequemer als das, was wir derzeit haben. Meiner Meinung nach gibt es viel mehr Anwendungsfälle, bei denen Sie die Vorhersagen explizit berechnen möchten (obwohl ich sicher bin, dass meine Ansicht voreingenommen ist).

Wenn Sie eine plot_confusion_matrix(y_true, y_pred) Signatur haben und sie tatsächlich für estimator , x , y Daten verwenden möchten, müssen Sie nur sehr wenig zusätzlichen Code schreiben : plot_confusion_matrix(y, estimator.predict(x)) .
Im Vergleich dazu, wenn Sie die aktuelle Signatur haben und aus y_true und y_pred plotten möchten, müssen Sie viel mehr Code schreiben.

Meiner Meinung nach sollte die Signatur plot_confusion_matrix(y_true, y_pred) Standard sein und eine weitere Funktion, die estimator , x , y sollte darauf aufbauen.

Zu guter Letzt verstehe ich die Idee hinter der Klasse ConfusionMatrixDisplay ehrlich gesagt nicht wirklich. Die Funktion hat nur einen einzigen Konstruktor und genau eine Methode, sodass Sie bei jeder Verwendung eine Instanz erstellen und die Funktion plot aufrufen. Ich verstehe nicht, warum dies eine Klasse und nicht nur eine Funktion sein sollte. Es gibt auch andere *Display Klassen (PrecisionRecall, ROC, ...), aber ihre Konstruktor- und plot() Signaturen sind völlig unterschiedlich, können also sowieso nicht ausgetauscht werden.
Vielleicht sprengt dies den Rahmen dieser Ausgabe.

@jhennrich

Wenn Sie eine plot_confusion_matrix(y_true, y_pred)-Signatur haben und sie tatsächlich für Schätzer-, x-, y-Daten verwenden möchten, müssen Sie nur sehr wenig zusätzlichen Code schreiben: plot_confusion_matrix(y, estimator.predict(x)).

Für den Fall der Verwirrungsmatrix ist es einfach, estimator.predict wenn wir eine y_true, y_pred Schnittstelle hätten. Auf der anderen Seite müsste der Benutzer für plot_roc_auc Slicing durchführen:

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])

Zu guter Letzt verstehe ich die Idee hinter der ConfusionMatrixDisplay-Klasse ehrlich gesagt nicht wirklich. Die Funktion hat nur einen einzigen Konstruktor und genau eine Methode, sodass Sie bei jeder Verwendung eine Instanz erstellen und die Plotfunktion aufrufen. Ich verstehe nicht, warum dies eine Klasse und nicht nur eine Funktion sein sollte.

Der Zweck der Display Objekte besteht darin, die berechneten Werte zu speichern, die es den Benutzern ermöglichen, plot ohne Neuberechnung mehrmals aufzurufen. Dies kann mit 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"})

Ehrlich gesagt bin ich bei diesem Thema am Zaun. Ich bin +0,1 dazu übergegangen, die Metrik-Schnittstelle zum Zeichnen von Metriken zu kopieren und die est, X, y Schnittstelle zu entfernen. :/

Für den Fall der Konfusionsmatrix ist es einfach, estimator.predict zu übergeben, wenn wir eine y_true-, y_pred-Schnittstelle hätten. Auf der anderen Seite müsste der Benutzer für plot_roc_auc das Slicing durchführen:

Ja, aber dadurch vermeiden wir, die Vorhersage mehrfach zu berechnen (obwohl die Vorhersage oft nicht so teuer ist)

Vielleicht ist es eine praktische Lösung, y_true, y_pred in plot_XXX (sofern zutreffend) in 0.23 zu unterstützen.

@jhennrich Wie machen Sie das, ohne die Labels explizit zu übergeben? Wenn die Labels aus dem Gegebenen abgeleitet werden können, wird confusion_matrix dies für Sie tun.

Aber in der Tat hast du recht, es sind drei Zeilen statt einer.

Im Fall von Confusion_matrix tendiere ich dazu, zuzustimmen, dass der häufigere Fall die Übergabe von y_true und y_pred .
Der Grund dafür, dass die Schnittstelle derzeit so ist, dass sie mit den anderen metrischen Plotting-Funktionen konsistent ist. Wie @thomasjpfan sagte, ist die roc-Kurve weniger offensichtlich zu zeichnen.

Im Moment ist der Code zum Zeichnen einer Konfusionsmatrix und zum Zeichnen einer Roc-Kurve derselbe. Mit Ihrer vorgeschlagenen Änderung werden sie nicht mehr dieselben sein, und es wird keine einfache Möglichkeit geben, sie gleich zu machen.

Die Frage ist, ob es in diesem Fall besser ist, konsistente Schnittstellen zu haben oder eine einfache Schnittstelle zu haben.
@jhennrich Für mich ist die eigentliche Frage, was die richtige Schnittstelle für plot_roc_curve ist. Hast du Gedanken dazu?

@thomasjpfan tendierst du dazu, y_store für das Plotten von Roc Auc zu nehmen?

Es gibt sicherlich Vor- und Nachteile für die Verwendung der Scorer-Schnittstelle anstelle der metrischen Schnittstelle. Aber für komplexere Dinge ist es viel sicherer, die Scorer-Schnittstelle zu verwenden.

@qinhanmin2014
Ich denke, es wäre in Ordnung, y_pred zu plot_confusion_matrix hinzuzufügen. Die Frage ist, ob wir y_score zu plot_roc_curve und plot_precision_recall_curve hinzufügen wollen. Wenn wir dies tun, müssen wir auch pos_label hinzufügen, wie ich oben sagte, und die Dinge werden komplizierter.

Ich sehe hier drei Auswege:
a) Fügen Sie nur y_pred zu plot_confusion_matrix , aber nicht y_score zu plot_roc_curve usw. Nachteil: das Problem beim Anrufen von predict_proba mehrfach bleibt für diese Metriken vorhanden.
b) Machen Sie es einfacher, das Objekt Display direkt zu verwenden (obwohl ich nicht wirklich weiß, wie).
c) Fügen Sie eine weitere Methode oder Funktion hinzu, die die metrische Schnittstelle widerspiegelt. Nachteil: größere API-Oberfläche.

Ich glaube nicht, dass es im Allgemeinen eine gute Idee ist, die Funktion plot_X sowohl die Scorer- als auch die Metrikschnittstelle zu spiegeln.

Ich denke, es wäre großartig, dies in irgendeiner Weise zu lösen @adrinjalali ,

Ich habe manchmal Albträume zu diesem Thema. Vielleicht können wir eine statische Methode hinzufügen, die die Ausgabe der Metrik direkt übernimmt:

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

Für Roc-Kurve:

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

Nebenbei bemerkt, wenn ich mir Codebasen ansehe, denke ich, dass mehr Benutzer mit der Metrik-Schnittstelle als mit der Score-Schnittstelle vertraut sind.

Ich habe manchmal Albträume zu diesem Thema.

Ach nein :(

Nebenbei bemerkt, wenn ich mir Codebasen ansehe, denke ich, dass mehr Benutzer mit der Metrik-Schnittstelle als mit der Score-Schnittstelle vertraut sind.

Ich denke, das ist definitiv wahr. Aber ich bin mir auch ziemlich sicher, dass die Leute y_pred wenn sie y_score und falsche Ergebnisse erhalten, weil die Benutzeroberfläche Ihnen nicht sagt, dass Sie etwas anderes tun müssen und keine- man liest immer die docs.

Ich bin mir nicht sicher, wie sich die von Ihnen vorgeschlagene statische Methode vom Konstruktor unterscheidet, aber vielleicht übersehe ich etwas.

Hallo, ich habe das Problem gerade positiv bewertet - als langjähriger sklearn-Benutzer fand ich die aktuelle API für plot_confusion_matrix sehr... nun, verwirrend. Ich mag seine Hinzufügung sehr (weniger Copy-Paste), aber die Metrikfunktionen verwendeten immer das (y_true, y_pred)-Schema, das einfach flexibler ist und an das ich bereits gewöhnt bin.

In meinem Fall macht es keinen Sinn, einen Schätzer einzugeben, da es sich um ein sehr langsames Modell handelt und ich die Vorhersagen lieber aus einer Datei lade, als sie jedes Mal erneut auszuführen, wenn ich die Ergebnisse analysieren möchte. Ich freue mich, in diesem Thread herausgefunden zu haben, dass es eine Problemumgehung mit dem *Display-Objekt gibt, aber seine Auffindbarkeit ist nicht großartig - ich würde vorschlagen, dies zumindest in die plot_confusion_matrix Dokumentation oder vielleicht in das Benutzerhandbuch zur Verwirrungsmatrix aufzunehmen ?

In meinem Fall macht es keinen Sinn, einen Schätzer einzugeben, da es sich um ein sehr langsames Modell handelt und ich lieber die Vorhersagen laden würde

Danke für deinen Beitrag. Wenn die aktuelle API verwirrend ist, wäre es immer sinnvoller, zu einer mehr Metriken-API-ähnlichen Schnittstelle zu wechseln und einen schmerzhaften Verfallszyklus zu durchlaufen.

Die größte Sorge, die wir bei der Verwendung der Metrik-Schnittstelle haben, ist:

Aber ich bin mir auch ziemlich sicher, dass die Leute y_pred verwenden, wenn sie y_score verwenden sollten, und falsche Ergebnisse erhalten, weil die Benutzeroberfläche Ihnen nicht sagt, dass Sie etwas anderes tun müssen und niemand die Dokumentation liest.

@pzelasko Was

@thomasjpfan Ich verstehe das Problem, es ist ein schwieriges. Vielleicht wäre ein vernünftiger Kompromiss, nur Schlüsselwortargumente für diese Funktion zuzulassen (jetzt, da Sie Python 2 nicht mehr unterstützen müssen)? Wie: def plot_confusion_matrix(*, y_true, y_pred, ...) . Es unterscheidet sich immer noch von den anderen Metriken, aber 1) es hat einen guten Grund dafür, 2) verwendet es zumindest die gleiche Art von Eingaben wie die anderen Funktionen.

Wie auch immer, ich weiß, warum Sie zögern, API-Änderungen vorzunehmen, deshalb habe ich vorgeschlagen, die Problemumgehung zumindest in den Dokumenten zu erwähnen. (Ich habe sie tatsächlich schon oft gelesen und schätze sie sehr!)

Die aktuelle Verwendungsweise von y_true und y_pred wird hier gezeigt: https://scikit-learn.org/stable/auto_examples/miscellaneous/plot_display_object_visualization.html#create -confusionmatrixdisplay

Ich weiß, dass ich mich hier dehne, aber was ist damit:

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

wobei die zweite Position y_true als Vorhersagen akzeptiert, wenn estimator='precomputed .

Wenn Sie noch mehr dehnen möchten, würde ich plot_confusion_matrix((estimator, X, y), ...) oder plot_confusion_matrix((y_true, y_pred), ...) bevorzugen, aber ich bin mir nicht sicher, ob es die von @amueller angesprochenen

Es gibt ein paar neue Plotting-Dienstprogramme, bei denen es wirklich sinnvoll wäre, eine metric API zuzulassen:

Ich verstehe das von @amueller erwähnte Problem, dass pos_label usw. übergeben werden müssen, aber dies ist für keine der oben genannten Funktionen ein Problem.

Ist es in Ordnung, sowohl die Scorer- als auch die Metrik-API für diese beiden zu unterstützen? Da brauchen wir uns keine Sorgen um die Abwärtskompatibilität zu machen.

Ich bin immer noch für meinen Vorschlag, precomputed , die wir normalerweise in unseren Schätzern verwenden. In diesem Fall lautet die Signatur:

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

Ich werde PR zusammenstellen, um zu sehen, wie das aussieht.

Ich diskutiere die API noch nicht wirklich, ich frage nur, ob wir beide Optionen für neue PRs unterstützen können.

(Aber in Bezug auf die API glaube ich nicht, dass 'vorberechnet' viel hilft: Was machen wir mit X ? Ich denke, wir sollten (y_pred) und (estimator, X) sich gegenseitig ausschließen, indem wir richtig Fehler machen Was bedeutet es auch, dass ein Schätzer vorberechnet wird?)

Oder estimator='none' , estimator='predictions' , estimator='precomputed_predictions' und dann wird X zu y_pred oder y_score . Es ist fast so, wie wir vorberechnete Distanzen mit X in Schätzern handhaben.

Ist es in Ordnung, sowohl die Scorer- als auch die Metrik-API für diese beiden zu unterstützen?

Wie werden wir beide Optionen unterstützen? Mit zwei Funktionen?

Ich hätte auch gerne:

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

das wären zwei Methoden.

Guillaumes Vorschlag zur Verwendung von Tupeln https://github.com/scikit-learn/scikit-learn/issues/15880#issuecomment -670590882 ist eine Option. Ich denke, es wäre die beste Option gewesen, wenn wir von vorne angefangen hätten. Aber ich befürchte, dass die Verwendung von Tupeln die Konsistenz mit den vorhandenen Dienstprogrammen verletzt.

plot_XYZ(estimator=None, X=None, y=None, y_pred=None) mit gegenseitigem Ausschluss ist eine weitere Option, und dafür plädiere ich vorerst.

Ich mag CalibrationDisplay.from_estimator(...) , aber wie Andy bemerkte, müssten wir dann die plot_XYZ Funktionen entfernen. Es könnte eine Überlegung wert sein.

Ich denke, wir können zu Tupeln übergehen und das aktuelle Verhalten verwerfen. (Solange wir der Verwendung von Tupeln zustimmen)

Das scheint also eine Diskussion über die Namespaces zu sein, oder?
Egal, ob wir eine Funktion und einen Konstruktor oder zwei Klassenmethoden oder zwei Funktionen haben, es ist genau die gleiche Funktionalität und im Grunde der gleiche Code.

@pzelasko @jhennrich Wie

Und wenn Sie zwei Funktionen oder zwei Klassenmethoden bevorzugen, sehen Sie trotz Auffindbarkeit einen Vorteil? Auffindbarkeit könnte Grund genug sein, um Klassenmethoden zu verwenden, aber ich sehe kein starkes Argument dafür, zwei Funktionen zu haben.

Könnten wir hier das Blocker-Label hinzufügen? Es scheint, dass es den Fortschritt bei #18020 und #17443 verhindert (cc @cmarmo)

Das Blocker-Label ist für Release-Blocker (Dinge, die unbedingt vor einer Veröffentlichung behoben werden müssen), nicht für PR-Blocker

Ahh gut zu wissen.

@pzelasko @jhennrich Wie

Und wenn Sie zwei Funktionen oder zwei Klassenmethoden bevorzugen, sehen Sie trotz Auffindbarkeit einen Vorteil? Auffindbarkeit könnte Grund genug sein, um Klassenmethoden zu verwenden, aber ich sehe kein starkes Argument dafür, zwei Funktionen zu haben.

Ich mag den Zwei-Klassen-Methoden-Ansatz am meisten, besonders das from_xxx -Muster - etw, wie @thomasjpfan vorgeschlagen hat:

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

Es sieht so aus, als ob es keine starke Opposition gegen die Verwendung von 2-Klassenmethoden gibt, also lass uns das tun. Wir müssen:

  • Stellen Sie die Klassenmethoden für die derzeit vorhandenen Plots vor:

    • ConfusionMatrixDisplay
    • PrecisionRecallDisplay
    • RocCurveDisplay
    • DetCurveDisplay
    • PartialDependenceDisplay . In diesem Fall möchten wir die Klassenmethode from_predictions einführen, weil es keinen Sinn machen würde, wir wollen nur from_estimator .
  • Stellen Sie für alle oben aufgeführten Displays die entsprechende plot_... Funktion ein. Wir müssen plot_det_curve nicht verwerfen, weil es noch nicht veröffentlicht wurde, wir können es einfach entfernen.

  • für neue PRs wie #17443 und #18020 können wir die Klassenmethoden sofort implementieren, anstatt eine plot Funktion einzuführen.

Das ist ein bisschen Arbeit, aber ich denke, wir können dies vor 0,24 erledigen, damit #17443 und #18020 bereits vorankommen können.

Irgendwelche Einwände @thomasjpfan @jnothman @amueller @glemaitre ?

@jhennrich @pzelasko , wären Sie daran interessiert, eine PR einzureichen, um die Klassenmethoden in einem der Display-Objekte vorzustellen?

Danke für die Entscheidung @NicolasHug! Ich komme auf #17443 (nachdem ich auf Einwände gewartet habe)

Ich habe keine Einwände.

Auch kein Einwand.

Ich werde mich dann um die anderen Klassen kümmern und meine festgefahrene PR vorantreiben.
@lucyleeow falls ich das nicht alles gemacht habe und du nach ein paar PRs suchst, ping mich :)

Ich würde gerne dazu beitragen, aber ich bin derzeit an zu vielen Projekten beteiligt. Danke fürs Zuhören der Vorschläge!

Hört sich gut an :)

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen