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:
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.
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.
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.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:
plot
aufrufenFü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:
plot_prediction_error
in https://github.com/scikit-learn/scikit-learn/pull/18020plot_calibration_curve
in https://github.com/scikit-learn/scikit-learn/pull/17443 (CC @lucyleeow )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 :)