Python如何为Keras分类器生成ROC曲线的简单指南

阅读本指南后,您将了解如何通过ROC和AUC评估Keras分类器:

  • 为二元分类分类器生成ROC图; 这样做应用交叉验证。

  • 计算AUC并使用它来比较分类器的性能。

  • 将ROC分析应用于多级分类。

ROC和AUC是什么?他们能做什么?

受试者工作特征曲线 (receiver operating characteristic curve,简称ROC曲线)是根据一系列不同的二分类方式(分界值或决定阈),以真阳性率(灵敏度)为纵坐标,假阳性率(1-特异度)为横坐标绘制的曲线。ROC曲线的评价方法与传统的评价方法不同,允许有中间状态,可以把试验结果划分为多个有序分类。我将向你展示如何通过one-vs-all方法将ROC绘制成多标签分类器。

AUC(Area Under Curve)被定义为ROC曲线下的面积,显然这个面积的数值不会大于1。又由于ROC曲线一般都处于y=x这条直线的上方,所以AUC的取值范围在0.5和1之间。使用AUC值作为评价标准是因为很多时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而作为一个数值,对应AUC更大的分类器效果更好。

ROC,二元分类器的AUC

首先,让我们使用Sklearn的make_classification()函数来生成一些训练/测试数据。

from sklearn.datasets import make_classification

from sklearn.model_selection import train_test_split

X, y = make_classification(n_samples=80000)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5)

X_train, X_train_lr, y_train, y_train_lr = train_test_split(X_train,

y_train,

test_size=0.5)

接下来,我们照例构建和训练Keras分类器模型。

from keras.models import Sequential

from keras.layers import Dense

def build_model():

model = Sequential()

model.add(Dense(20, input_dim=20, activation='relu'))

model.add(Dense(40, activation='relu'))

model.add(Dense(1, activation='sigmoid'))

# Compile model

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

return model

from keras.wrappers.scikit_learn import KerasClassifier

keras_model = build_model()

keras_model.fit(X_train, y_train, epochs=5, batch_size=100, verbose=1)

然后我们在保留的测试数据上调用model.predict来生成概率值。之后,使用概率和基础标签生成绘制ROC曲线所必需的两个数据阵列对:

fpr:每个可能阈值的假阳性率

tpr:对于每个可能的阈值,均为真正的阳性率

我们可以调用sklearn的roc_curve()函数来生成这两个。这是使它们发生的代码。

from sklearn.metrics import roc_curve

y_pred_keras = keras_model.predict(X_test).ravel()

fpr_keras, tpr_keras, thresholds_keras = roc_curve(y_test, y_pred_keras)

AUC值也可以像这样计算。

from sklearn.metrics import auc

auc_keras = auc(fpr_keras,tpr_keras)

让我们训练另一个二元分类器,并稍后在同一图表中将其与我们的Keras分类器进行比较。

from sklearn.ensemble import RandomForestClassifier

#基于随机森林的监督转化

rf = RandomForestClassifier(max_depth = 3,n_estimators = 10)

rf.fit(X_train,y_train)

y_pred_rf = rf.predict_proba(X_test)[:,1 ]

fpr_rf,tpr_rf,thresholds_rf = roc_curve(y_test,y_pred_rf)

auc_rf = auc(fpr_rf,tpr_rf)

现在,让我们绘制两个分类器的ROC。

plt.figure(1)

plt.plot([0, 1], [0, 1], 'k--')

plt.plot(fpr_keras, tpr_keras, label='Keras (area = {:.3f})'.format(auc_keras))

plt.plot(fpr_rf, tpr_rf, label='RF (area = {:.3f})'.format(auc_rf))

plt.xlabel('False positive rate')

plt.ylabel('True positive rate')

plt.title('ROC curve')

plt.legend(loc='best')

plt.show()

# Zoom in view of the upper left corner.

plt.figure(2)

plt.xlim(0, 0.2)

plt.ylim(0.8, 1)

plt.plot([0, 1], [0, 1], 'k--')

plt.plot(fpr_keras, tpr_keras, label='Keras (area = {:.3f})'.format(auc_keras))

plt.plot(fpr_rf, tpr_rf, label='RF (area = {:.3f})'.format(auc_rf))

plt.xlabel('False positive rate')

plt.ylabel('True positive rate')

plt.title('ROC curve (zoomed in at top left)')

plt.legend(loc='best')

plt.show()

结果如下:

Python如何为Keras分类器生成ROC曲线的简单指南

正如你所看到的,考虑到AUC度量,Keras分类器优于其他分类器。

ROC,用于分类分类器的AUC

ROC曲线延伸到三个或更多类的问题,即所谓的one-vs-all”方法。

例如,如果我们有三个类,我们将创建三条ROC曲线,

对于每个类,我们把它作为正类,并将其余的类作为负类。

Class 1 vs classes 2&3

Class 2 vs classes 1&3

Class 3 vs classes 1&2

让我们开始创建一些带3类输出的训练/测试数据。

from sklearn.datasets import make_classification

from sklearn.preprocessing import label_binarize

# 3 classes to classify

n_classes = 3

X, y = make_classification(n_samples=80000, n_features=20, n_informative=3, n_redundant=0, n_classes=n_classes,

n_clusters_per_class=2)

# Binarize the output

y = label_binarize(y, classes=[0, 1, 2])

n_classes = y.shape[1]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5)

然后,我们像以前一样构建和训练一个分类Keras分类器。

from keras.models import Sequential

from keras.layers import Dense

def build_model():

model = Sequential()

model.add(Dense(20, input_dim=20, activation='relu'))

model.add(Dense(40, activation='relu'))

model.add(Dense(3, activation='softmax'))

# Compile model

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

return model

keras_model2 = build_model()

keras_model2.fit(X_train, y_train, epochs=10, batch_size=100, verbose=1)

在对模型进行训练之后,我们可以使用它来对测试输入进行预测,并为三个类中的每一个绘制ROC。

在此之前,让我们定义度量标准以评估所有类的总体表现。有两个略有不同的指标,micro and macro averaging。

在“macro averaging”中,我们根据k-class模型的单个真阳性、真阴性、假阳性和假阴性计算性能,例如精度:

Python如何为Keras分类器生成ROC曲线的简单指南

在macro averaging中,我们平均每个类的性能:

Python如何为Keras分类器生成ROC曲线的简单指南

这里是绘制这些ROC曲线和AUC值的代码。

import numpy as np

from scipy import interp

import matplotlib.pyplot as plt

from itertools import cycle

from sklearn.metrics import roc_curve, auc

# Plot linewidth.

lw = 2

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

roc_auc[i] = auc(fpr[i], tpr[i])

# Compute micro-average ROC curve and ROC area

fpr["micro"], tpr["micro"], _ = roc_curve(y_test.ravel(), y_score.ravel())

roc_auc["micro"] = auc(fpr["micro"], tpr["micro"])

# 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 += 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

roc_auc["macro"] = auc(fpr["macro"], tpr["macro"])

# Plot all ROC curves

plt.figure(1)

plt.plot(fpr["micro"], tpr["micro"],

label='micro-average ROC curve (area = {0:0.2f})'

''.format(roc_auc["micro"]),

color='deeppink', linestyle=':', linewidth=4)

plt.plot(fpr["macro"], tpr["macro"],

label='macro-average ROC curve (area = {0:0.2f})'

''.format(roc_auc["macro"]),

color='navy', linestyle=':', linewidth=4)

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

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 multi-class')

plt.legend(loc="lower right")

plt.show()

# Zoom in view of the upper left corner.

plt.figure(2)

plt.xlim(0, 0.2)

plt.ylim(0.8, 1)

plt.plot(fpr["micro"], tpr["micro"],

label='micro-average ROC curve (area = {0:0.2f})'

''.format(roc_auc["micro"]),

color='deeppink', linestyle=':', linewidth=4)

plt.plot(fpr["macro"], tpr["macro"],

label='macro-average ROC curve (area = {0:0.2f})'

''.format(roc_auc["macro"]),

color='navy', linestyle=':', linewidth=4)

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

plt.plot([0, 1], [0, 1], 'k--', lw=lw)

plt.xlabel('False Positive Rate')

plt.ylabel('True Positive Rate')

plt.title('Some extension of Receiver operating characteristic to multi-class')

plt.legend(loc="lower right")

plt.show()

这是结果,第二个图是图的左上角的放大视图。

Python如何为Keras分类器生成ROC曲线的简单指南

总结

在本教程中,我们逐步了解了如何使用ROC曲线和AUC值评估二元和分类Keras分类器。

ROC曲线将测试集上的排序器或概率模型的质量可视化,而不必承诺分类阈值。我们还学会了如何计算AUC值来帮助我们访问分类器的性能。

相关推荐