在前面的博客中介紹了使用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的值,常用的包括宏平均和微平均。