ROC曲线和AUC

1.二分类问题的混淆矩阵(confusion matrix)以及precision、recall:

真实情况预测结果(正例positive)预测结果(反例negative)
正例(true)TP(真正例)FN(假反例)
反例(false)FP(假正例)TN(真反例)

precision = TP / (TP + FP): 预测为正例中,有多少真的是正例,也就是我判别为正例中有多大比例是对的。
recall = TP / (TP + FN):所有正样本中,有多少被我判别成了正例,也就是正例中我召回了多少比例。

2.ROC曲线和AUC

2.1 ROC曲线和AUC曲线概念:

ROC曲线:受试者工作特性曲线(Receiver Operating Characteristic Curve)。横轴是假正例率(False Positive Rate, fpr),纵轴是真正例率(True Positive Rate, tpr)。

横轴:FPR = FP / (TN + FP):负样本中预测为正样本的比例。分母就是负样本的数量。
纵轴:TPR = TP / (TP + FN):正样本中预测为正样本的比例,其实就是recall。分母就是正样本的数量。

这里写图片描述
AUC:Area under ROC curve,即ROC曲线下的面积。

2.2 ROC的评判标准:

1.若一个分类器的ROC曲线被另一个分类器的ROC曲线完全“包住”,则后者性能优于前者
2.若两个分类器的ROC曲线发生交叉,则难以一般性地断言两者孰优孰劣。如果一定要进行比较,可以比较AUC大小。

2.3 ROC的绘制:
  1. 给定数据集包含m个正例,n个反例,根据分类器的预测概率进行降序排序,然后将分类阈值设置为最大:即所有预测结果都是反例,FPR和TPR都为0,也就是原点。
  2. 将分类阈值按照之前降序排列的顺序依次赋值,相当于每次只增加一个样本进行考察:如果当前样本是真正例,则纵坐标tpr += 1/m, 即(fpr, tpr)–> (fpr, tpr+1/m);如果当前样本是假正例,则横坐标fpr += 1/n,即(fpr, tpr) –> (fpr+1/n, tpr)。
  3. 依次连接各点即得ROC曲线。

对角线对应随机猜测模型。如果曲线经过点(0,1)则对应理想分类器。
现实任务中测试数据集是有限的,无法产生光滑的ROC曲线,只能绘制出类似上图的阶梯状的曲线。

3.关于ROC曲线的几点讨论

3.1 为什么可以用ROC曲线度量分类器的好坏?

在周志华老师的《机器学习》中是这么说的:
分类器的概率预测结果直接决定了学习器的泛化能力,在不同的应用任务中,我们可根据任务需求来采用不同的截断点,例如更重视precision,则阈值可以设置的大一点;如果更重视recall,则阈值设置小一点。因此,排序本身的质量好坏,体现了综合考虑学习器在不同任务下的“期望泛化性能”的好坏,或者说,“一般情况下”泛化性能的好坏。ROC曲线则是从这个角度出发来研究学习器泛化性能的有力工具。

4. 实例:sklearn绘制ROC曲线(sklearn上的两个demo)

4.1 二分类问题ROC曲线绘制
# -*- coding: utf-8 -*-
#!/usr/bin/env python
'''
5折交叉检验的ROC曲线图及平均ROC曲线图
'''
import numpy as np
from scipy import interp
import matplotlib.pyplot as plt
from itertools import cycle

from sklearn import svm, datasets
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import StratifiedKFold

# 使用iris数据集,只保留类别0和类别1,共2类
iris = datasets.load_iris()
X = iris.data
y = iris.target
X, y = X[y != 2], y[y != 2]
n_samples, n_features = X.shape

# 加噪音
random_state = np.random.RandomState(0)
X = np.c_[X, random_state.randn(n_samples, 200 * n_features)]


# 设置分类器、交叉检验、绘制ROC曲线
cv = StratifiedKFold(n_splits=6)
classifier = svm.SVC(kernel='linear', probability=True,
                     random_state=random_state)

mean_tpr = 0.0
mean_fpr = np.linspace(0, 1, 100)

colors = cycle(['cyan', 'indigo', 'seagreen', 'yellow', 'blue', 'darkorange'])
lw = 2

i = 0
for (train, test), color in zip(cv.split(X, y), colors):
    probas_ = classifier.fit(X[train], y[train]).predict_proba(X[test])
    # 计算fpr, tpr, auc
    fpr, tpr, thresholds = roc_curve(y[test], probas_[:, 1])
    mean_tpr += interp(mean_fpr, fpr, tpr)
    mean_tpr[0] = 0.0
    roc_auc = auc(fpr, tpr)
    plt.plot(fpr, tpr, lw=lw, color=color,
             label='ROC fold %d (area = %0.2f)' % (i, roc_auc))

    i += 1
plt.plot([0, 1], [0, 1], linestyle='--', lw=lw, color='k',
         label='Luck')

mean_tpr /= cv.get_n_splits(X, y)
mean_tpr[-1] = 1.0
mean_auc = auc(mean_fpr, mean_tpr)
plt.plot(mean_fpr, mean_tpr, color='g', linestyle='--',
         label='Mean ROC (area = %0.2f)' % mean_auc, lw=lw)

plt.xlim([-0.05, 1.05])
plt.ylim([-0.05, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()

这里写图片描述

4.2 多分类问题ROC曲线绘制
# -*- coding: utf-8 -*-
#!/usr/bin/env python
'''
只绘制了多分类问题其中一类的ROC曲线,其他类别可以仿照绘制
'''
import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle

from sklearn import svm, datasets
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import label_binarize
from sklearn.multiclass import OneVsRestClassifier
from scipy import interp

# Import some data to play with
iris = datasets.load_iris()
X = iris.data
y = iris.target

# Binarize the output
y = label_binarize(y, classes=[0, 1, 2])
n_classes = y.shape[1]

# Add noisy features to make the problem harder
random_state = np.random.RandomState(0)
n_samples, n_features = X.shape
X = np.c_[X, random_state.randn(n_samples, 200 * n_features)]

# shuffle and split training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.5,
                                                    random_state=0)

# Learn to predict each class against the other
classifier = OneVsRestClassifier(svm.SVC(kernel='linear', probability=True,
                                         random_state=random_state))
y_score = classifier.fit(X_train, y_train).decision_function(X_test)

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


plt.figure()
lw = 2
plt.plot(fpr[2], tpr[2], color='darkorange',
         lw=lw, label='ROC curve (area = %0.2f)' % roc_auc[2])
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值