One-vs-Rest многоклассовая ROC
Многоклассовая стратегия One-vs-the-Rest (OvR) состоит в вычислении кривой ROC для каждого из n_classes
. На каждом этапе определенный класс рассматривается как положительный класс, а остальные классы рассматриваются как единый негативный класс. На этом этапе показано, как вычислить кривую ROC с использованием многоклассовой стратегии OvR.
from sklearn.preprocessing import LabelBinarizer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve, roc_auc_score
import matplotlib.pyplot as plt
from sklearn.metrics import RocCurveDisplay
## Бинаризация целевого признака с использованием стратегии OvR
label_binarizer = LabelBinarizer().fit(y_train)
y_onehot_test = label_binarizer.transform(y_test)
## Обучение модели логистической регрессии
classifier = LogisticRegression()
y_score = classifier.fit(X_train, y_train).predict_proba(X_test)
## Вычисление кривой ROC и значения ROC AUC для каждого класса
fpr, tpr, roc_auc = dict(), dict(), dict()
for i in range(n_classes):
fpr[i], tpr[i], _ = roc_curve(y_onehot_test[:, i], y_score[:, i])
roc_auc[i] = roc_auc_score(y_onehot_test[:, i], y_score[:, i])
## Вычисление микро-средней кривой ROC и площади под кривой
fpr["micro"], tpr["micro"], _ = roc_curve(y_onehot_test.ravel(), y_score.ravel())
roc_auc["micro"] = roc_auc_score(y_onehot_test, y_score, multi_class="ovr", average="micro")
## Вычисление макро-средней кривой ROC и площади под кривой
## Агрегация истинных/ложных положительных долей для каждого класса
fpr["macro"], tpr["macro"] = [], []
for i in range(n_classes):
fpr_averaged, tpr_averaged = [], []
for j in range(n_classes):
if i!= j:
fpr_averaged += list(fpr[j])
tpr_averaged += list(tpr[j])
fpr_averaged = np.array(fpr_averaged)
tpr_averaged = np.array(tpr_averaged)
fpr["macro"].append(fpr_averaged)
tpr["macro"].append(tpr_averaged)
fpr["macro"] = np.concatenate(fpr["macro"])
tpr["macro"] = np.concatenate(tpr["macro"])
roc_auc["macro"] = roc_auc_score(y_onehot_test, y_score, multi_class="ovr", average="macro")
## Построение кривых ROC для каждого класса и микро/макро-средних значений
fig, ax = plt.subplots(figsize=(6, 6))
colors = ["aqua", "darkorange", "cornflowerblue"]
for i, color in zip(range(n_classes), colors):
RocCurveDisplay.from_predictions(
y_onehot_test[:, i],
y_score[:, i],
name=f"ROC кривая класса {target_names[i]} (AUC = {roc_auc[i]:.2f})",
color=color,
ax=ax,
plot_micro=False,
plot_macro=False,
)
RocCurveDisplay.from_predictions(
y_onehot_test.ravel(),
y_score.ravel(),
name=f"Микро-средняя ROC кривая (AUC = {roc_auc['micro']:.2f})",
color="deeppink",
linestyle=":",
linewidth=4,
ax=ax,
)
plt.plot(
fpr["macro"],
tpr["macro"],
label=f"Макро-средняя ROC кривая (AUC = {roc_auc['macro']:.2f})",
color="navy",
linestyle=":",
linewidth=4,
)
plt.plot([0, 1], [0, 1], "k--", label="Уровень случайности")
plt.axis("square")
plt.xlabel("Доля ложных положительных")
plt.ylabel("Доля истинных положительных")
plt.title("One-vs-Rest ROC кривые")
plt.legend()
plt.show()