男神鹏:机器学习之ROC和AUC

1.什么是ROC:

    ROC曲线:接收者操作特征曲线(receiver operating characteristic curve),是反映敏感性和特异性连续变量的综合指标,roc曲线上每个点反映着对同一信号刺激的感受性。

2.如果学习ROC,首先必须知道什么:

         要学习ROC曲线首先得知道什么是TPR,什么是FPR。

          TPR的英文全称为:True Positive Rate
          FPR的英文全称为:False Positive Rate
          中文解释为:
          TPR(真正例率):真实值是正例,且预测为正例的比例
          FPR(假正例率):真实值为负例,而预测为正例的比例

例如此图:

  

此图分为四部分:

    A部分:真实为正例,预测为正例
    B部分:真实为正例,预测为负例
    C部分:真实为负例,预测为正例
    D部分:真实为负例,预测为负例

ROC曲线就是以TPR为Y轴,以FPR为X轴,然后以一个对不同的预测值进行分类.
当取不同阈值时会得到不同的TPR和FPR,对应于ROC曲线上的一个点。
那么ROC曲线就反映了FPR与TPR之间动态关系的情况。
通俗地来说,即在TPR随着FPR递增的情况下,谁增长得更快,快多少的问题。
TPR增长得越快,曲线越往上曲,反映了模型的分类性能就越好。
当正负样本不平衡时,这种模型评价方式比起一般的精确度评价方式 的好处尤其显著。

说完ROC,说一下AUC。

         AUC (Area Under Curve) 被定义为ROC曲线下的面积,显然这个面积的数值不会大于1。

         又由于ROC曲线一般都处于y=x这条直线的上方,所以AUC的取值范围一般在0.5和1之间。

         使用AUC值作为评价标准是因为很多时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而作为一个数值,对应AUC更大的分类器效果更好。

从AUC判断分类器(预测模型)优劣的标准:

  • AUC = 1,是完美分类器,采用这个预测模型时,存在至少一个阈值能得出完美预测。绝大多数预测的场合,不存在完美分类器。
  • 0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。
  • AUC = 0.5,跟随机猜测一样(例:丢铜板),模型没有预测价值。
  • AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。

为什么使用ROC和AUC?

       既然已经这么多评价标准,为什么还要使用ROC和AUC呢?因为ROC曲线有个很好的特性:当测试集中的正负样本的分布变化的时候,ROC曲线能够保持不变。
     在实际的数据集中经常会出现类不平衡(class imbalance)现象,即负样本比正样本多很多(或者相反),而且测试数据中的正负样本的分布也可能随着时间变化。
 
绘制ROC曲线代码如下:

#绘制ROC曲线函数
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import StratifiedKFold
def drawROC(classifier,X,y):
#X:训练集/测试集
#y:训练集标签/测试集标签
print(X.shape)
print(y.shape)
# 画平均ROC曲线的两个参数
mean_tpr = 0.0 # 用来记录画平均ROC曲线的信息
mean_fpr = np.linspace(0, 1, 100)
cnt = 0
cv = StratifiedKFold(n_splits=6) #导入该模型,后面将数据划分6份
for i, (train, test) in enumerate(cv.split(X,y)): #利用模型划分数据集和目标变量 为一一对应的下标
cnt +=1
probas_ = classifier.fit(X[train], y[train]).predict_proba(X[test]) # 训练模型后预测每条样本得到两种结果的概率
fpr, tpr, thresholds = roc_curve(y[test], probas_[:, 1]) # 该函数得到伪正例、真正例、阈值,这里只使用前两个

mean_tpr += np.interp(mean_fpr, fpr, tpr) # 插值函数 interp(x坐标,每次x增加距离,y坐标) 累计每次循环的总值后面求平均值
mean_tpr[0] = 0.0 # 将第一个真正例=0 以0为起点

roc_auc = auc(fpr, tpr) # 求auc面积
plt.plot(fpr, tpr, lw=1, label='ROC fold {0:.2f} (area = {1:.2f})'.format(i, roc_auc)) # 画出当前分割数据的ROC曲线

plt.plot([0, 1], [0, 1], '--', color=(0.6, 0.6, 0.6), label='Luck') # 画对角线

mean_tpr /= cnt # 求数组的平均值
mean_tpr[-1] = 1.0 # 坐标最后一个点为(1,1) 以1为终点
mean_auc = auc(mean_fpr, mean_tpr)

plt.plot(mean_fpr, mean_tpr, 'k--',label='Mean ROC (area = {0:.2f})'.format(mean_auc), lw=2)
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate') # 可以使用中文,但需要导入一些库即字体
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()
#调用
train_Y[train_Y == 2] = 0
print(train_Y)
drawROC(clf,train_X[:,:],train_Y[:])

绘图效果:

  

希望能帮助到大家。






 



   
原文地址:https://www.cnblogs.com/lyp0626/p/10722613.html