420 lines
13 KiB
Python
420 lines
13 KiB
Python
|
from ...utils._plotting import _BinaryClassifierCurveDisplayMixin
|
||
|
from .._ranking import auc, roc_curve
|
||
|
|
||
|
|
||
|
class RocCurveDisplay(_BinaryClassifierCurveDisplayMixin):
|
||
|
"""ROC Curve visualization.
|
||
|
|
||
|
It is recommend to use
|
||
|
:func:`~sklearn.metrics.RocCurveDisplay.from_estimator` or
|
||
|
:func:`~sklearn.metrics.RocCurveDisplay.from_predictions` to create
|
||
|
a :class:`~sklearn.metrics.RocCurveDisplay`. All parameters are
|
||
|
stored as attributes.
|
||
|
|
||
|
Read more in the :ref:`User Guide <visualizations>`.
|
||
|
|
||
|
Parameters
|
||
|
----------
|
||
|
fpr : ndarray
|
||
|
False positive rate.
|
||
|
|
||
|
tpr : ndarray
|
||
|
True positive rate.
|
||
|
|
||
|
roc_auc : float, default=None
|
||
|
Area under ROC curve. If None, the roc_auc score is not shown.
|
||
|
|
||
|
estimator_name : str, default=None
|
||
|
Name of estimator. If None, the estimator name is not shown.
|
||
|
|
||
|
pos_label : int, float, bool or str, default=None
|
||
|
The class considered as the positive class when computing the roc auc
|
||
|
metrics. By default, `estimators.classes_[1]` is considered
|
||
|
as the positive class.
|
||
|
|
||
|
.. versionadded:: 0.24
|
||
|
|
||
|
Attributes
|
||
|
----------
|
||
|
line_ : matplotlib Artist
|
||
|
ROC Curve.
|
||
|
|
||
|
chance_level_ : matplotlib Artist or None
|
||
|
The chance level line. It is `None` if the chance level is not plotted.
|
||
|
|
||
|
.. versionadded:: 1.3
|
||
|
|
||
|
ax_ : matplotlib Axes
|
||
|
Axes with ROC Curve.
|
||
|
|
||
|
figure_ : matplotlib Figure
|
||
|
Figure containing the curve.
|
||
|
|
||
|
See Also
|
||
|
--------
|
||
|
roc_curve : Compute Receiver operating characteristic (ROC) curve.
|
||
|
RocCurveDisplay.from_estimator : Plot Receiver Operating Characteristic
|
||
|
(ROC) curve given an estimator and some data.
|
||
|
RocCurveDisplay.from_predictions : Plot Receiver Operating Characteristic
|
||
|
(ROC) curve given the true and predicted values.
|
||
|
roc_auc_score : Compute the area under the ROC curve.
|
||
|
|
||
|
Examples
|
||
|
--------
|
||
|
>>> import matplotlib.pyplot as plt
|
||
|
>>> import numpy as np
|
||
|
>>> from sklearn import metrics
|
||
|
>>> y = np.array([0, 0, 1, 1])
|
||
|
>>> pred = np.array([0.1, 0.4, 0.35, 0.8])
|
||
|
>>> fpr, tpr, thresholds = metrics.roc_curve(y, pred)
|
||
|
>>> roc_auc = metrics.auc(fpr, tpr)
|
||
|
>>> display = metrics.RocCurveDisplay(fpr=fpr, tpr=tpr, roc_auc=roc_auc,
|
||
|
... estimator_name='example estimator')
|
||
|
>>> display.plot()
|
||
|
<...>
|
||
|
>>> plt.show()
|
||
|
"""
|
||
|
|
||
|
def __init__(self, *, fpr, tpr, roc_auc=None, estimator_name=None, pos_label=None):
|
||
|
self.estimator_name = estimator_name
|
||
|
self.fpr = fpr
|
||
|
self.tpr = tpr
|
||
|
self.roc_auc = roc_auc
|
||
|
self.pos_label = pos_label
|
||
|
|
||
|
def plot(
|
||
|
self,
|
||
|
ax=None,
|
||
|
*,
|
||
|
name=None,
|
||
|
plot_chance_level=False,
|
||
|
chance_level_kw=None,
|
||
|
**kwargs,
|
||
|
):
|
||
|
"""Plot visualization.
|
||
|
|
||
|
Extra keyword arguments will be passed to matplotlib's ``plot``.
|
||
|
|
||
|
Parameters
|
||
|
----------
|
||
|
ax : matplotlib axes, default=None
|
||
|
Axes object to plot on. If `None`, a new figure and axes is
|
||
|
created.
|
||
|
|
||
|
name : str, default=None
|
||
|
Name of ROC Curve for labeling. If `None`, use `estimator_name` if
|
||
|
not `None`, otherwise no labeling is shown.
|
||
|
|
||
|
plot_chance_level : bool, default=False
|
||
|
Whether to plot the chance level.
|
||
|
|
||
|
.. versionadded:: 1.3
|
||
|
|
||
|
chance_level_kw : dict, default=None
|
||
|
Keyword arguments to be passed to matplotlib's `plot` for rendering
|
||
|
the chance level line.
|
||
|
|
||
|
.. versionadded:: 1.3
|
||
|
|
||
|
**kwargs : dict
|
||
|
Keyword arguments to be passed to matplotlib's `plot`.
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
display : :class:`~sklearn.metrics.RocCurveDisplay`
|
||
|
Object that stores computed values.
|
||
|
"""
|
||
|
self.ax_, self.figure_, name = self._validate_plot_params(ax=ax, name=name)
|
||
|
|
||
|
line_kwargs = {}
|
||
|
if self.roc_auc is not None and name is not None:
|
||
|
line_kwargs["label"] = f"{name} (AUC = {self.roc_auc:0.2f})"
|
||
|
elif self.roc_auc is not None:
|
||
|
line_kwargs["label"] = f"AUC = {self.roc_auc:0.2f}"
|
||
|
elif name is not None:
|
||
|
line_kwargs["label"] = name
|
||
|
|
||
|
line_kwargs.update(**kwargs)
|
||
|
|
||
|
chance_level_line_kw = {
|
||
|
"label": "Chance level (AUC = 0.5)",
|
||
|
"color": "k",
|
||
|
"linestyle": "--",
|
||
|
}
|
||
|
|
||
|
if chance_level_kw is not None:
|
||
|
chance_level_line_kw.update(**chance_level_kw)
|
||
|
|
||
|
(self.line_,) = self.ax_.plot(self.fpr, self.tpr, **line_kwargs)
|
||
|
info_pos_label = (
|
||
|
f" (Positive label: {self.pos_label})" if self.pos_label is not None else ""
|
||
|
)
|
||
|
|
||
|
xlabel = "False Positive Rate" + info_pos_label
|
||
|
ylabel = "True Positive Rate" + info_pos_label
|
||
|
self.ax_.set(
|
||
|
xlabel=xlabel,
|
||
|
xlim=(-0.01, 1.01),
|
||
|
ylabel=ylabel,
|
||
|
ylim=(-0.01, 1.01),
|
||
|
aspect="equal",
|
||
|
)
|
||
|
|
||
|
if plot_chance_level:
|
||
|
(self.chance_level_,) = self.ax_.plot(
|
||
|
(0, 1), (0, 1), **chance_level_line_kw
|
||
|
)
|
||
|
else:
|
||
|
self.chance_level_ = None
|
||
|
|
||
|
if "label" in line_kwargs or "label" in chance_level_line_kw:
|
||
|
self.ax_.legend(loc="lower right")
|
||
|
|
||
|
return self
|
||
|
|
||
|
@classmethod
|
||
|
def from_estimator(
|
||
|
cls,
|
||
|
estimator,
|
||
|
X,
|
||
|
y,
|
||
|
*,
|
||
|
sample_weight=None,
|
||
|
drop_intermediate=True,
|
||
|
response_method="auto",
|
||
|
pos_label=None,
|
||
|
name=None,
|
||
|
ax=None,
|
||
|
plot_chance_level=False,
|
||
|
chance_level_kw=None,
|
||
|
**kwargs,
|
||
|
):
|
||
|
"""Create a ROC Curve display from an estimator.
|
||
|
|
||
|
Parameters
|
||
|
----------
|
||
|
estimator : estimator instance
|
||
|
Fitted classifier or a fitted :class:`~sklearn.pipeline.Pipeline`
|
||
|
in which the last estimator is a classifier.
|
||
|
|
||
|
X : {array-like, sparse matrix} of shape (n_samples, n_features)
|
||
|
Input values.
|
||
|
|
||
|
y : array-like of shape (n_samples,)
|
||
|
Target values.
|
||
|
|
||
|
sample_weight : array-like of shape (n_samples,), default=None
|
||
|
Sample weights.
|
||
|
|
||
|
drop_intermediate : bool, default=True
|
||
|
Whether to drop some suboptimal thresholds which would not appear
|
||
|
on a plotted ROC curve. This is useful in order to create lighter
|
||
|
ROC curves.
|
||
|
|
||
|
response_method : {'predict_proba', 'decision_function', 'auto'} \
|
||
|
default='auto'
|
||
|
Specifies whether to use :term:`predict_proba` or
|
||
|
:term:`decision_function` as the target response. If set to 'auto',
|
||
|
:term:`predict_proba` is tried first and if it does not exist
|
||
|
:term:`decision_function` is tried next.
|
||
|
|
||
|
pos_label : int, float, bool or str, default=None
|
||
|
The class considered as the positive class when computing the roc auc
|
||
|
metrics. By default, `estimators.classes_[1]` is considered
|
||
|
as the positive class.
|
||
|
|
||
|
name : str, default=None
|
||
|
Name of ROC Curve for labeling. If `None`, use the name of the
|
||
|
estimator.
|
||
|
|
||
|
ax : matplotlib axes, default=None
|
||
|
Axes object to plot on. If `None`, a new figure and axes is created.
|
||
|
|
||
|
plot_chance_level : bool, default=False
|
||
|
Whether to plot the chance level.
|
||
|
|
||
|
.. versionadded:: 1.3
|
||
|
|
||
|
chance_level_kw : dict, default=None
|
||
|
Keyword arguments to be passed to matplotlib's `plot` for rendering
|
||
|
the chance level line.
|
||
|
|
||
|
.. versionadded:: 1.3
|
||
|
|
||
|
**kwargs : dict
|
||
|
Keyword arguments to be passed to matplotlib's `plot`.
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
display : :class:`~sklearn.metrics.RocCurveDisplay`
|
||
|
The ROC Curve display.
|
||
|
|
||
|
See Also
|
||
|
--------
|
||
|
roc_curve : Compute Receiver operating characteristic (ROC) curve.
|
||
|
RocCurveDisplay.from_predictions : ROC Curve visualization given the
|
||
|
probabilities of scores of a classifier.
|
||
|
roc_auc_score : Compute the area under the ROC curve.
|
||
|
|
||
|
Examples
|
||
|
--------
|
||
|
>>> import matplotlib.pyplot as plt
|
||
|
>>> from sklearn.datasets import make_classification
|
||
|
>>> from sklearn.metrics import RocCurveDisplay
|
||
|
>>> from sklearn.model_selection import train_test_split
|
||
|
>>> from sklearn.svm import SVC
|
||
|
>>> X, y = make_classification(random_state=0)
|
||
|
>>> X_train, X_test, y_train, y_test = train_test_split(
|
||
|
... X, y, random_state=0)
|
||
|
>>> clf = SVC(random_state=0).fit(X_train, y_train)
|
||
|
>>> RocCurveDisplay.from_estimator(
|
||
|
... clf, X_test, y_test)
|
||
|
<...>
|
||
|
>>> plt.show()
|
||
|
"""
|
||
|
y_pred, pos_label, name = cls._validate_and_get_response_values(
|
||
|
estimator,
|
||
|
X,
|
||
|
y,
|
||
|
response_method=response_method,
|
||
|
pos_label=pos_label,
|
||
|
name=name,
|
||
|
)
|
||
|
|
||
|
return cls.from_predictions(
|
||
|
y_true=y,
|
||
|
y_pred=y_pred,
|
||
|
sample_weight=sample_weight,
|
||
|
drop_intermediate=drop_intermediate,
|
||
|
name=name,
|
||
|
ax=ax,
|
||
|
pos_label=pos_label,
|
||
|
plot_chance_level=plot_chance_level,
|
||
|
chance_level_kw=chance_level_kw,
|
||
|
**kwargs,
|
||
|
)
|
||
|
|
||
|
@classmethod
|
||
|
def from_predictions(
|
||
|
cls,
|
||
|
y_true,
|
||
|
y_pred,
|
||
|
*,
|
||
|
sample_weight=None,
|
||
|
drop_intermediate=True,
|
||
|
pos_label=None,
|
||
|
name=None,
|
||
|
ax=None,
|
||
|
plot_chance_level=False,
|
||
|
chance_level_kw=None,
|
||
|
**kwargs,
|
||
|
):
|
||
|
"""Plot ROC curve given the true and predicted values.
|
||
|
|
||
|
Read more in the :ref:`User Guide <visualizations>`.
|
||
|
|
||
|
.. versionadded:: 1.0
|
||
|
|
||
|
Parameters
|
||
|
----------
|
||
|
y_true : array-like of shape (n_samples,)
|
||
|
True labels.
|
||
|
|
||
|
y_pred : array-like of shape (n_samples,)
|
||
|
Target scores, can either be probability estimates of the positive
|
||
|
class, confidence values, or non-thresholded measure of decisions
|
||
|
(as returned by “decision_function” on some classifiers).
|
||
|
|
||
|
sample_weight : array-like of shape (n_samples,), default=None
|
||
|
Sample weights.
|
||
|
|
||
|
drop_intermediate : bool, default=True
|
||
|
Whether to drop some suboptimal thresholds which would not appear
|
||
|
on a plotted ROC curve. This is useful in order to create lighter
|
||
|
ROC curves.
|
||
|
|
||
|
pos_label : int, float, bool or str, default=None
|
||
|
The label of the positive class. When `pos_label=None`, if `y_true`
|
||
|
is in {-1, 1} or {0, 1}, `pos_label` is set to 1, otherwise an
|
||
|
error will be raised.
|
||
|
|
||
|
name : str, default=None
|
||
|
Name of ROC curve for labeling. If `None`, name will be set to
|
||
|
`"Classifier"`.
|
||
|
|
||
|
ax : matplotlib axes, default=None
|
||
|
Axes object to plot on. If `None`, a new figure and axes is
|
||
|
created.
|
||
|
|
||
|
plot_chance_level : bool, default=False
|
||
|
Whether to plot the chance level.
|
||
|
|
||
|
.. versionadded:: 1.3
|
||
|
|
||
|
chance_level_kw : dict, default=None
|
||
|
Keyword arguments to be passed to matplotlib's `plot` for rendering
|
||
|
the chance level line.
|
||
|
|
||
|
.. versionadded:: 1.3
|
||
|
|
||
|
**kwargs : dict
|
||
|
Additional keywords arguments passed to matplotlib `plot` function.
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
display : :class:`~sklearn.metrics.RocCurveDisplay`
|
||
|
Object that stores computed values.
|
||
|
|
||
|
See Also
|
||
|
--------
|
||
|
roc_curve : Compute Receiver operating characteristic (ROC) curve.
|
||
|
RocCurveDisplay.from_estimator : ROC Curve visualization given an
|
||
|
estimator and some data.
|
||
|
roc_auc_score : Compute the area under the ROC curve.
|
||
|
|
||
|
Examples
|
||
|
--------
|
||
|
>>> import matplotlib.pyplot as plt
|
||
|
>>> from sklearn.datasets import make_classification
|
||
|
>>> from sklearn.metrics import RocCurveDisplay
|
||
|
>>> from sklearn.model_selection import train_test_split
|
||
|
>>> from sklearn.svm import SVC
|
||
|
>>> X, y = make_classification(random_state=0)
|
||
|
>>> X_train, X_test, y_train, y_test = train_test_split(
|
||
|
... X, y, random_state=0)
|
||
|
>>> clf = SVC(random_state=0).fit(X_train, y_train)
|
||
|
>>> y_pred = clf.decision_function(X_test)
|
||
|
>>> RocCurveDisplay.from_predictions(
|
||
|
... y_test, y_pred)
|
||
|
<...>
|
||
|
>>> plt.show()
|
||
|
"""
|
||
|
pos_label_validated, name = cls._validate_from_predictions_params(
|
||
|
y_true, y_pred, sample_weight=sample_weight, pos_label=pos_label, name=name
|
||
|
)
|
||
|
|
||
|
fpr, tpr, _ = roc_curve(
|
||
|
y_true,
|
||
|
y_pred,
|
||
|
pos_label=pos_label,
|
||
|
sample_weight=sample_weight,
|
||
|
drop_intermediate=drop_intermediate,
|
||
|
)
|
||
|
roc_auc = auc(fpr, tpr)
|
||
|
|
||
|
viz = cls(
|
||
|
fpr=fpr,
|
||
|
tpr=tpr,
|
||
|
roc_auc=roc_auc,
|
||
|
estimator_name=name,
|
||
|
pos_label=pos_label_validated,
|
||
|
)
|
||
|
|
||
|
return viz.plot(
|
||
|
ax=ax,
|
||
|
name=name,
|
||
|
plot_chance_level=plot_chance_level,
|
||
|
chance_level_kw=chance_level_kw,
|
||
|
**kwargs,
|
||
|
)
|