模型评价-ROC曲线

ROC曲线是由TPR和FPR为横纵轴,

  • TPR表示:所有实际为,我的模型有多少也预测为
  • FPR表示:所有实际为,我的模型由多少预测为

二者实现如下,其中你已经知道TP,FN,FP,TN的含义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def TPR(y_true, y_predict):
tp = TP(y_true, y_predict)
fn = FN(y_true, y_predict)
try:
return tp / (tp + fn)
except:
return 0.


def FPR(y_true, y_predict):
fp = FP(y_true, y_predict)
tn = TN(y_true, y_predict)
try:
return fp / (fp + tn)
except:
return 0.

TPR和FPR是和P&R相似的概念,计算所用到的值都在Confusion Matrix中。所以绘制ROC图过程同PR曲线

1
2
3
4
5
6
7
fprs = []
tprs = []
thresholds = np.arange(np.min(decision_scores), np.max(decision_scores), 0.1)
for threshold in thresholds:
y_predict = np.array(decision_scores >= threshold, dtype='int')
fprs.append(FPR(y_test, y_predict))
tprs.append(TPR(y_test, y_predict))

得到不同的threshold值,每一个值对应一个模型,计算每一个模型的TPR和FPR,分别放入空列表中。就可以绘图了:

1
2
3
4
5
plt.plot(fprs, tprs, label='ROC')
plt.legend(loc='lower right', prop={'size': 10})
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.show()

结果:

图 ROC曲线

使用sklearn中自带实现:

1
2
3
4
5
6
7
8
9
from sklearn.metrics import roc_curve

fprs, tprs, thresholds = roc_curve(y_test, decision_scores)

plt.plot(fprs, tprs, label='ROC')
plt.legend(loc='lower right', prop={'size': 10})
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.show()

如图:

图 ROC曲线 built-in

ROC的作用是为了计算AUC(Area Under Curve)。而比较模型的相对性能,只要得到两个模型各自的ROC,分别计算各自的AUC,谁大,谁的相对性能好。

sklearn提供AUC的计算:

1
2
3
from sklearn.metrics import roc_auc_score

print(roc_auc_score(y_test, decision_scores)) # 0.98304526749

传入y_test和decision_scores即可得到。

敲黑板ROC的两个指标,与PR指标相似又不同,是另一个角度的对模型性能的量化。引入相似但不同的信息有助于减少系统的不确定性,这里是模型选择的不确定性。衡量一个模型的性能,通常要尽可能把所有指标都找到,综合衡量。
给出liuyubobobo老师的话
我们的目的不是“找到”单一的“最好”的指标;而是了解所有的指标背后在反映什么,在看到这个指标出现问题的时候,能够判断问题可能出现在哪里,进而改进我们的模型。虽然我们的改进方向可能是单一的。

具体到PR曲线和ROC曲线,他们的核心区别在TN。可以看出来,PR曲线其实不反应TN。所以,如果你的应用场景中,如果TN并不重要,那么PR曲线是一个很好的指标(事实上,Precision和Recall就是通过抹去TN,来去除极度的偏斜数据带来的影响,进而放大FP, FN和TP三者的关系的)。

而ROC曲线则综合了TN, FP, FN和TP。虽然它对TN极度多的情况下,FP,FN和TP的变化不敏感。所以在TN没有那么多(数据没有那么偏斜),或者TN是一种很重要的需要考虑的情况下,ROC能反映出PR不能反映的问题。