使用scikit-learn计算分类器的ROC曲线及AUC值

在前面的博客中介绍了使用scikit-learn绘制分类器的学习曲线,今天介绍一下使用scikit-learn绘制分类器的ROC曲线,以及计算AUC的值。

ROC曲线主要用于衡量二分类器的性能,当正负样本不均衡时,准确率和召回率不能合理度量分类器的性能。关于ROC曲线和AUC的计算scikit-learn工具包中主要提供了以下几个函数:

1、roc_curve函数(只能用于二分类):根据模型预测结果(概率,置信度等)和样本真实标签,按照模型预测结果降序排序依次选择阈值,基于阈值计算fpr、tpr,基于fpr和tpr即可得到分类器的ROC曲线

2、auc函数:基于roc_curve函数返回fpr、tpr序列计算二分类器的AUC值

3、roc_auc_score函数:基于样本真实标签y_target和模型预测结果(概率,置信度等)计算AUC的值,可以用于计算多分类器的AUC数值

下面通过例子看一下函数的具体使用方法:

roc_curve示例:

根据模型预测结果(概率,置信度等)和样本真实标签,按照模型预测结果降序排序依次选择阈值,基于阈值计算fpr/tpr。

from sklearn.metrics import roc_auc_score
from sklearn.metrics import roc_curve
from sklearn.metrics import auc
import numpy as np


y = np.array([1, 1, 2, 2])
scores = np.array([0.1, 0.4, 0.35, 0.8])
fpr, tpr, thresholds = roc_curve(y, scores, pos_label=2)

fpr, tpr, thresholds

输出的fpr、tpr和thresholds如下:

(array([0. , 0. , 0.5, 0.5, 1. ]),
array([0. , 0.5, 0.5, 1. , 1. ]),
array([1.8 , 0.8 , 0.4 , 0.35, 0.1 ]))

基于fpr(x轴)和tpr(y轴)绘制ROC曲线如下:

%matplotlib inline
from matplotlib import pyplot as plt

plt.plot(fpr, tpr)
plt.xlabel("FPR")
plt.ylabel("TPR")
plt.xlim([0, 1])
plt.ylim([0, 1])

auc示例:

基于roc_curve函数返回fpr、tpr序列计算AUC的值(和roc_auc_score等价)。

import numpy as np
y = np.array([1, 1, 2, 2])
pred = np.array([0.1, 0.4, 0.35, 0.8])
fpr, tpr, thresholds = roc_curve(y, pred, pos_label=2)
auc(fpr, tpr), roc_auc_score(y, pred)

输出结果如下:

(0.75, 0.75)

roc_auc_score示例:

基于样本真实标签y_target和模型预测结果(概率,置信度等)计算AUC的值,可以用于计算多分类器的AUC数值。

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from sklearn.svm import SVC
from sklearn.metrics import roc_curve, roc_auc_score, auc, plot_roc_curve
from sklearn.multiclass import OneVsOneClassifier, OneVsRestClassifier
from sklearn.preprocessing import label_binarize
from sklearn import datasets
from sklearn.model_selection import train_test_split
np.random.seed(100)

# 加载iris数据集
iris = datasets.load_iris()
X = iris.data
y = iris.target
print(X.shape, y.shape)
n_samples, n_features = X.shape

# iris数据集加入噪声,使得ROC不是那么完美
X = np.c_[X, np.random.randn(n_samples, 50 * n_features)]
# y = label_binarize(y, classes=[0, 1, 2])
# n_classes = y.shape[1]
# 训练样本的类别数量
n_classes = 3

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.5, random_state=0)
print(X_train.shape, y_train.shape)
print(X_test.shape, y_test.shape)

# 使用One-vs-One模式训练SVM分类器
clf = OneVsRestClassifier(SVC(kernel="linear", probability=True))
clf.fit(X_train, y_train)

# 计算分类器在测试集上的决策值
y_scores = clf.predict_proba(X_test)
print(y_scores.shape)

# 绘制每个类别的ROC曲线
fig, axes = plt.subplots(2, 2, figsize=(8, 8))
colors = ["r", "g", "b", "k"]
markers = ["o", "^", "v", "+"]

y_test = label_binarize(y_test, classes=clf.classes_)
for i in range(n_classes):
    # 计算每个类别的FPR, TPR 
    fpr, tpr, thr = roc_curve(y_test[:, i], y_scores[:, i])
#     print("classes_{}, fpr: {}, tpr: {}, threshold: {}".format(i, fpr, tpr, thr))
    # 绘制ROC曲线,并计算AUC值
    axes[int(i / 2), i % 2].plot(fpr, tpr, color=colors[i], marker=markers[i], label="AUC: {:.2f}".format(auc(fpr, tpr)))
    axes[int(i / 2), i % 2].set_xlabel("FPR")
    axes[int(i / 2), i % 2].set_ylabel("TPR")
    axes[int(i / 2), i % 2].set_title("Class_{}".format(clf.classes_[i]))
    axes[int(i / 2), i % 2].legend(loc="lower right")

print("AUC:", roc_auc_score(y_test, clf.predict_proba(X_test), multi_class="ovr", average=None))

输出结果如下:

AUC: [0.99647266 0.8237037  0.90196078]

这个例子中是一个多分类问题,y_scores和y_test的形状都是(n_samples, 3),且y_scores、y_test的每列分别代表clf.classes_每种类型的真实标签和预测概率,然后基于每种类型的真是标签和预测概率计使用roc_curve函数计算fpr和tpr,并使用auc函数计算AUC的值。最后使用roc_auc_score函数计算多分类的整体AUC值。

在计算多分类的roc_auc_score值时,可以通过参数multi_class : {'raise', 'ovr', 'ovo'}控制多分类模型是使用哪种模式训练的,参数average : {'micro', 'macro', 'samples', 'weighted'} or None表示使用何种方式计算多分类器AUC的值,常用的包括宏平均和微平均。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章