ROC与AUC曲线绘制
由于ROC曲线面积比较难求得,所以判断模型好坏一般使用AUC曲线
关于AUC曲线的绘制,西瓜书上写得比较学术,不太能理解,假设有这么一个样本集:
假设预测样本为20个,预测为正类的概率已经进行了排序,得分递减,画图步骤为:
(1) 在所排序的样本最左边,画一条线即 无 | 1 2 3 4 5 …,线左边的认为是正类,右边认为是负类,可以算出,TP(实际为正,预测为正)=0,FN(实际为正,预测为负)=10,TN(实际为负,预测为负)=10,FP(实际为负,预测为正)=0,故而TPR=0,FPR=0
(2) 在第一个样本后面,画一条线即 1 | 2 3 4 …,线左边的认为是正类,右边认为是负类,可以算出,TP(实际为正,预测为正)=1,FN(实际为正,预测为负)=9,TN(实际为负,预测为负)=10,FP(实际为负,预测为正)=0,故而TPR=0.1,FPR=0
(3) 在第二个样本后面,画一条线即 1 2| 3 4 …,线左边的认为是正类,右边认为是负类,可以算出,TP(实际为正,预测为正)=2,FN(实际为正,预测为负)=8,TN(实际为负,预测为负)=10,FP(实际为负,预测为正)=0,故而TPR=0.2,FPR=0
(4) 在第三个样本后面,画一条线即 1 2 3| 4 5…,线左边的认为是正类,右边认为是负类,可以算出,TP(实际为正,预测为正)=2,FN(实际为正,预测为负)=8,TN(实际为负,预测为负)=10,FP(实际为负,预测为正)=1,故而TPR=0.2,FPR=0.1
... ...
依次例推:起点一定为(0,0),终点一定为(1,1),由此即可画出AUC曲线
但这样做比较繁琐,可以总结规律为:
按照预测为正类的概率值由大到小排序,首先起点一定是(0,0),然后使用上述划线法进行计算,每次碰到一个预测为正的样本,则在Y方向加一个Y步长,否则在X方向加一个X步长,其中X和Y的步长,计算方法为X: 负类样本个数分之1,Y:正类样本个数分之1,如果是降序排列,则是减一个对应方向的步长即可。
代码部分详情可参考《机器学习实战》:
import numpy as np import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties def plotROC(predStrengths,classLabels): font = FontProperties(fname = r"c:\windows\fonts\simsun.ttc",size=14) cur=(1.0,1.0) #绘制光标位置 ySum=0.0 #用于计算AUC numPosClas=np.sum(np.array(classLabels)==1.0) #正类样本的个数 yStep = 1/float(numPosClas) #Y轴步长 xStep = 1/float(len(classLabels)-numPosClas) #X轴步长 sortedIndicies = predStrengths.argsort() fig =plt.figure() fig().clf() ax=plt.figure() for inddex in sortedIndicies.tolist()[0]: if classLabels[index]==1.0 delX=0; delY = yStep #碰到一个正类,Y的步长减 1 else: delX = xStep; delY=0 #碰到一个负类,X的步长减1 ySum += cur[1] #每次cur[1]都可能变化了 #高度累加 ax.plot([cur[0],cur[0]-delX],[cur[1],cur[1]-delY],c = 'b') #绘制ROC cur = (cur[0]-delX,cur[1]-delY) #更新绘制光标的位置 ax.plot([0,1],[0,1],'b--') plt.title('ROC曲线',FontProperties =font) plt.xlabel('假正例率',FontProperties = font) plt.ylabel(('真正例率',FontProperties = font)) ax.axis([0,1,0,1]) print('AUC面积:',ySum*xStep) #计算AUC plt.show()
更新一段可用代码:
# coding=UTF-8 from sklearn import metrics import matplotlib.pylab as plt #真实值 GTlist = [1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0] #模型预测值 Problist = [0.99, 0.98, 0.97, 0.93, 0.85, 0.80, 0.79, 0.75, 0.70, 0.65, 0.64, 0.63, 0.55, 0.54, 0.51, 0.49, 0.30, 0.2, 0.1, 0.09] fpr, tpr, thresholds = metrics.roc_curve(GTlist, Problist, pos_label=1) roc_auc = metrics.auc(fpr, tpr) #auc为Roc曲线下的面积 print(roc_auc) plt.plot(fpr, tpr, 'b',label='AUC = %0.2f'% roc_auc) plt.legend(loc='lower right') # plt.plot([0, 1], [0, 1], 'r--') plt.xlim([-0.1, 1.1]) plt.ylim([-0.1, 1.1]) plt.xlabel('False Positive Rate') #横坐标是fpr plt.ylabel('True Positive Rate') #纵坐标是tpr plt.title('Receiver operating characteristic example') plt.show()
结果图: