scikit-learn/examples/model_selection/plot_roc.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

190 lines
5.8 KiB
Python
Raw Normal View History

"""
=======================================
Receiver Operating Characteristic (ROC)
=======================================
Example of Receiver Operating Characteristic (ROC) metric to evaluate
classifier output quality.
2013-01-15 17:46:38 +08:00
ROC curves typically feature true positive rate on the Y axis, and false
positive rate on the X axis. This means that the top left corner of the plot is
the "ideal" point - a false positive rate of zero, and a true positive rate of
one. This is not very realistic, but it does mean that a larger area under the
curve (AUC) is usually better.
The "steepness" of ROC curves is also important, since it is ideal to maximize
the true positive rate while minimizing the false positive rate.
2013-09-20 21:56:56 +08:00
ROC curves are typically used in binary classification to study the output of
2019-07-18 04:45:27 +08:00
a classifier. In order to extend ROC curve and ROC area to multi-label
classification, it is necessary to binarize the output. One ROC
2013-09-20 19:17:32 +08:00
curve can be drawn per label, but one can also draw a ROC curve by considering
each element of the label indicator matrix as a binary prediction
2015-08-30 17:47:07 +08:00
(micro-averaging).
2019-07-18 04:45:27 +08:00
Another evaluation measure for multi-label classification is
2015-08-30 17:47:07 +08:00
macro-averaging, which gives equal weight to the classification of each
label.
2013-09-20 19:17:32 +08:00
2013-01-15 17:46:38 +08:00
.. note::
2013-09-20 19:17:32 +08:00
See also :func:`sklearn.metrics.roc_auc_score`,
2019-07-18 04:45:27 +08:00
:ref:`sphx_glr_auto_examples_model_selection_plot_roc_crossval.py`
2013-01-15 17:46:38 +08:00
"""
import numpy as np
import matplotlib.pyplot as plt
2015-10-24 00:40:11 +08:00
from itertools import cycle
from sklearn import svm, datasets
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split
2013-09-20 19:17:32 +08:00
from sklearn.preprocessing import label_binarize
from sklearn.multiclass import OneVsRestClassifier
2019-07-18 04:45:27 +08:00
from sklearn.metrics import roc_auc_score
# Import some data to play with
iris = datasets.load_iris()
X = iris.data
y = iris.target
2013-09-20 19:17:32 +08:00
# Binarize the output
y = label_binarize(y, classes=[0, 1, 2])
n_classes = y.shape[1]
# Add noisy features to make the problem harder
random_state = np.random.RandomState(0)
n_samples, n_features = X.shape
X = np.c_[X, random_state.randn(n_samples, 200 * n_features)]
# shuffle and split training and test sets
2013-09-20 19:17:32 +08:00
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)
2013-09-20 19:17:32 +08:00
# Learn to predict each class against the other
classifier = OneVsRestClassifier(
svm.SVC(kernel="linear", probability=True, random_state=random_state)
)
y_score = classifier.fit(X_train, y_train).decision_function(X_test)
2013-09-20 19:17:32 +08:00
# Compute ROC curve and ROC area for each class
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(n_classes):
fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_score[:, i])
2013-09-20 19:17:32 +08:00
roc_auc[i] = auc(fpr[i], tpr[i])
2013-09-20 19:17:32 +08:00
# Compute micro-average ROC curve and ROC area
fpr["micro"], tpr["micro"], _ = roc_curve(y_test.ravel(), y_score.ravel())
2013-09-20 19:17:32 +08:00
roc_auc["micro"] = auc(fpr["micro"], tpr["micro"])
2015-08-30 17:47:07 +08:00
# %%
# Plot of a ROC curve for a specific class
plt.figure()
2015-10-24 00:40:11 +08:00
lw = 2
plt.plot(
fpr[2],
tpr[2],
color="darkorange",
lw=lw,
label="ROC curve (area = %0.2f)" % roc_auc[2],
)
plt.plot([0, 1], [0, 1], color="navy", lw=lw, linestyle="--")
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel("False Positive Rate")
plt.ylabel("True Positive Rate")
plt.title("Receiver operating characteristic example")
plt.legend(loc="lower right")
plt.show()
2013-09-20 19:17:32 +08:00
2015-08-30 17:47:07 +08:00
# %%
# Plot ROC curves for the multiclass problem
2019-07-18 04:45:27 +08:00
# ..........................................
2014-09-10 01:20:39 +08:00
# Compute macro-average ROC curve and ROC area
# First aggregate all false positive rates
all_fpr = np.unique(np.concatenate([fpr[i] for i in range(n_classes)]))
# Then interpolate all ROC curves at this points
mean_tpr = np.zeros_like(all_fpr)
for i in range(n_classes):
mean_tpr += np.interp(all_fpr, fpr[i], tpr[i])
# Finally average it and compute AUC
mean_tpr /= n_classes
fpr["macro"] = all_fpr
tpr["macro"] = mean_tpr
2014-09-10 01:20:39 +08:00
roc_auc["macro"] = auc(fpr["macro"], tpr["macro"])
# Plot all ROC curves
2014-09-14 00:05:57 +08:00
plt.figure()
2014-09-10 01:20:39 +08:00
plt.plot(
fpr["micro"],
tpr["micro"],
2015-08-30 17:47:07 +08:00
label="micro-average ROC curve (area = {0:0.2f})".format(roc_auc["micro"]),
2015-10-24 00:40:11 +08:00
color="deeppink",
linestyle=":",
linewidth=4,
)
2014-09-10 01:20:39 +08:00
plt.plot(
fpr["macro"],
tpr["macro"],
2015-08-30 17:47:07 +08:00
label="macro-average ROC curve (area = {0:0.2f})".format(roc_auc["macro"]),
2015-10-24 00:40:11 +08:00
color="navy",
linestyle=":",
linewidth=4,
)
2015-10-24 00:40:11 +08:00
colors = cycle(["aqua", "darkorange", "cornflowerblue"])
for i, color in zip(range(n_classes), colors):
plt.plot(
fpr[i],
tpr[i],
color=color,
lw=lw,
label="ROC curve of class {0} (area = {1:0.2f})".format(i, roc_auc[i]),
)
2015-10-24 00:40:11 +08:00
plt.plot([0, 1], [0, 1], "k--", lw=lw)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel("False Positive Rate")
plt.ylabel("True Positive Rate")
plt.title("Some extension of Receiver operating characteristic to multiclass")
plt.legend(loc="lower right")
plt.show()
2019-07-18 04:45:27 +08:00
# %%
2019-07-18 04:45:27 +08:00
# Area under ROC for the multiclass problem
# .........................................
# The :func:`sklearn.metrics.roc_auc_score` function can be used for
# multi-class classification. The multi-class One-vs-One scheme compares every
# unique pairwise combination of classes. In this section, we calculate the AUC
2019-07-18 04:45:27 +08:00
# using the OvR and OvO schemes. We report a macro average, and a
# prevalence-weighted average.
y_prob = classifier.predict_proba(X_test)
macro_roc_auc_ovo = roc_auc_score(y_test, y_prob, multi_class="ovo", average="macro")
weighted_roc_auc_ovo = roc_auc_score(
y_test, y_prob, multi_class="ovo", average="weighted"
)
macro_roc_auc_ovr = roc_auc_score(y_test, y_prob, multi_class="ovr", average="macro")
weighted_roc_auc_ovr = roc_auc_score(
y_test, y_prob, multi_class="ovr", average="weighted"
)
print(
"One-vs-One ROC AUC scores:\n{:.6f} (macro),\n{:.6f} "
"(weighted by prevalence)".format(macro_roc_auc_ovo, weighted_roc_auc_ovo)
)
2019-07-18 04:45:27 +08:00
print(
"One-vs-Rest ROC AUC scores:\n{:.6f} (macro),\n{:.6f} "
"(weighted by prevalence)".format(macro_roc_auc_ovr, weighted_roc_auc_ovr)
)