使用scikit-learn计算分类器的ROC曲线及AUC值
在前面的博客中介绍了使用scikit-learn绘制分类器的学习曲线,今天介绍一下使用scikit-learn绘制分类器的ROC曲线,以及计算AUC的值。ROC曲线主要用于衡量二分类器的性能,当正负样本不均衡时,准确率和召回率不能合理度量分类器的性能。关于ROC曲线和AUC的计算scikit-learn工具包中主要提供了以下几个函数:1、roc_curve函数(只能用于二分类):根据模型预测结果(
在前面的博客中介绍了使用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的值,常用的包括宏平均和微平均。
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)