66-ROC曲线

it2024-05-07  48

     上一篇博客介绍了 PR 曲线,这一篇博客介绍另一种曲线 ROC 曲线。


ROC曲线

  ROC(Receiver Operating Characteristic Curve),它其实是统计学上经常使用的一个术语,它描述的是 TPR 和 FPR 之间的关系。

  那么我们首先来看看 TPR 和 FPR 这两个指标是什么意思?

  TRP,是 True Positive Result 的缩写。其实 TPR 和我们之前学的 R e c a l l Recall Recall 是一个意思。

  

FPR 是 False Positive Result 的缩写。其实它和 TPR 是对应的关系。

     其实 TPR 和 PPR 之前也存在着一种联系。我们还是画出一条 score 轴,轴上分布着很多样本点,而星形是我们关注的样本点,即分类为 1,那么圆形的分类为 0。

  当我们取不同的 t h r e s h o l e threshole threshole(阈值)来对我们的样本进行分类的时候,相应的 TPR 和 FRP 是怎样变化的?

  当我们的 t h r e s h o l e threshole threshole 取得非常大的时候,我们计算相应的 TPR 和 PPR 。

  如果我们减小 t h r e s h o l e threshole threshole ,计算相应的 TPR 和 PPR 。

  我们继续减少 t h r e s h o l e threshole threshole ,计算相应的 TPR 和 PPR 。

     那么很容易观察到,随着 t h r e s h o l e threshole threshole 的变化,我们的 TPR 和 PPR 是怎么变化的。在 t h r e s h o l e threshole threshole 逐渐降低的过程中,FPR 是在逐渐升高的,TPR 也在逐渐升高。换句话说,TPR 和 PPR 之间是呈现相一致的趋势。TPR 越高,FPR 跟着也变高。和 p r e c i s i o n precision precision r e c a l l recall recall 之间的关系是正好相反的。

  当然,我们也可以直观地理解一下,为了提高 TPR,我们就必须拉低阈值,阈值拉低以后,相应的我们犯 FP 这种错误也会增高。其实 ROC 曲线就是刻画这两个指标之间的关系。

  下面我们实现一个 TPR 和 FPR 两个函数。我们在之前的 metrics.py 文件中添加下列函数。

# metrics.py def TN(y_true, y_predict): assert len(y_true) == len(y_predict) return np.sum((y_true == 0) & (y_predict == 0)) def FP(y_true, y_predict): assert len(y_true) == len(y_predict) return np.sum((y_true == 0) & (y_predict == 1)) def FN(y_true, y_predict): assert len(y_true) == len(y_predict) return np.sum((y_true == 1) & (y_predict == 0)) def TP(y_true, y_predict): assert len(y_true) == len(y_predict) return np.sum((y_true == 1) & (y_predict == 1)) # 混淆矩阵 def confusion_matrix(y_true, y_predict): return np.array([ [TN(y_true, y_predict), FP(y_true, y_predict)], [FN(y_true, y_predict), TP(y_true, y_predict)] ]) # 精准率 def precision_score(y_true, y_predict): assert len(y_true) == len(y_predict) tp = TP(y_true, y_predict) fp = FP(y_true, y_predict) try: return tp / (tp + fp) except: return 0.0 # 召回率 def recall_score(y_true, y_predict): assert len(y_true) == len(y_predict) tp = TP(y_true, y_predict) fn = FN(y_true, y_predict) try: return tp / (tp + fn) except: return 0.0 # f1_score def f1_score(y_true, y_predict): precision = precision_score(y_true, y_predict) recall = recall_score(y_true, y_predict) try: return 2. * precision * recall / (precision + recall) except: return 0.0 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.0 def FPR(y_true, y_predict): tn = TN(y_true, y_predict) fp = FP(y_true, y_predict) try: return fp / (tn + fp) except: return 0.0


  那么 ROC 的应用场合在哪里呢?就在于比较两个模型的孰优孰劣。比如下面这个图。

  这两根曲线就代表了两个模型,或者是同一个模型由两组超参数得到的模型,这种情况下,我们应该选择曲线下面面积(曲线与 x x x 轴和 x = 1 x = 1 x=1 所围的面积)更大的那个模型,我们认为这个模型相应的是一个更好的模型。

  至此,我们谈论的都是二分类问题,下一篇博客将会谈论在多分类问题的情况。

  具体代码见 66 ROC曲线.ipynb

最新回复(0)