ROC Curve: my interpretation
首先我们来看个例子:
import pandas as pd
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve
bc = load_breast_cancer()
feat = pd.DataFrame(bc['data'])
feat.columns = bc['feature_names']
label = pd.Series(bc['target'])
train_X = feat.loc[0:99, ] # contrary to usual python slices, both the start and the stop are included in .loc!
train_y = label.loc[0:99]
test_X = feat.loc[100:, ]
test_y = label.loc[100:]
lr_config = dict(penalty='l2', C=1.0, class_weight=None, random_state=1337,
solver='liblinear', max_iter=100, verbose=0, warm_start=False, n_jobs=1)
lr = LogisticRegression(**lr_config)
lr.fit(train_X, train_y)
proba_test_y = lr.predict_proba(test_X)[:, 1]
auroc_df = pd.DataFrame(np.column_stack(roc_curve(test_y, proba_test_y, pos_label=1)))
auroc_df.columns = ["False Positive Rate", "True Positive Rate", "Decision Threshold"]
auroc_df.to_csv("auroc_test.tsv", sep='\t', index=False, header=True)
>>> auroc_df.head(n=3)
False Positive Rate True Positive Rate Decision Threshold
0 0.000000 0.003106 0.999988
1 0.000000 0.624224 0.953624
2 0.006803 0.624224 0.952853
>>> auroc_df.tail(n=3)
False Positive Rate True Positive Rate Decision Threshold
38 0.360544 0.996894 7.970653e-05
39 0.360544 1.000000 7.513310e-05
40 1.000000 1.000000 2.495012e-44
1. AxesPermalink
- x-axis 是
- y-axis 是
2. 序列规律Permalink
我们假设有
>>> library(ggplot2)
>>> auroc_df <- read.table("auroc_test.tsv", header=TRUE, sep="\t", stringsAsFactors=FALSE)
>>> colnames(auroc_df)
'False.Positive.Rate' 'True.Positive.Rate' 'Decision.Threshold'
>>> p <- ggplot(data=auroc_df, mapping=aes(x=False.Positive.Rate, y=True.Positive.Rate)) + geom_line(size=0.3) + geom_point(size=0.4, color=I("blue"))
>>> p
规律:
:从 0 单调递增到 1 :从 0 单调递增到 1 :从 1 单调递减到 0
所以 ROC curve 第一个点一定是
画一个图演示一下
ggplot(data=auroc_df[0:10, ], mapping=aes(x=False.Positive.Rate, y=True.Positive.Rate)) + geom_line(size=0.3) + geom_point(size=0.4, color=I("blue")) + geom_text(aes(label=sprintf("%0.3f", round(Decision.Threshold, digits=3))), hjust=-0.2, vjust=-0.4, size=2.2)
注意用 python 画图时,会出现 其原因是对 float 处理的误差。比如其实是
误差导致的作图如下:
p = ggplot(aesthetics=aes(x="False Positive Rate", y="True Positive Rate"), data=auroc_df.loc[0:20,:]) + geom_line() + geom_point(color="blue")
p
3. 单调性的原因Permalink
假设 test dataset 的 ground-true labels 为 classifier.predict_proba(X)[:, 1]
得到概率为 classifier.predict(X)
得到预测为
当 threshold 从
- ground-true positive 的数量
不变 - ground-true negative 的数量
不变 - threshold 减小,predict 为 positive 的数量只多不少
- 尤其当
时,
- 对
而言: 是新增的 predict 为 positive 的 cases,其中必然有 0 个或者若干个新增的 False Positive
- 对
而言: 是新增的 predict 为 positive 的 cases,其中必然有 0 个或者若干个新增的 True Positive
4. Randon Guess 与 AUROC = 0.5Permalink
有一类描述非常的 misleading,比如 quote from Can AUC-ROC be between 0-0.5:
… a predictor which makes random guesses has an AUC-ROC score of 0.5.
主要原因是这里 random guess 往往是忽视 thresholds 的,它和 thresholds 没有关系,所以本质上 a predictor which makes random guess 是做不出 ROC curve 的,它只有一个
Similarly, if you predict a random assortment of 0’s and 1’s, let’s say 90% 1’s, you could get the point
(0.9, 0.9)
, which again falls along that diagonal line.
这里需要这样理解:
- 你在
上预测了 90% 为 Positive,这些全部都是 True Positive,所以 - 你在
上预测了 90% 为 Positive,这些全部都是 False Positive,所以
所以 AUROC = 0.5 这条线本质上是一系列 predictors which make random guess,不可能是某个特定的 predictor
5. 可能出现 AUROC < 0.5 吗?为什么我们常见的 AUROC 都是 > 0.5?Permalink
AUROC 的范围是 [0, 1]
,所以当然可能会有 AUROC < 0.5。我们先来研究一下为什么常见的 AUROC 都是 > 0.5。
这个要借鉴 wikipedia: Receiver operating characteristic 上
In binary classification, the class prediction for each instance is often made based on a continuous random variable
, which is a “score” computed for the instance (e.g. estimated probability in logistic regression). Given a threshold parameter , the instance is classified as “positive” if , and “negative” otherwise. follows a probability density if the instance actually belongs to class “positive”, and if otherwise. Therefore, the true positive rate is given by and the false positive rate is given by .
用我们自己的符号表示就是:
中间的 vertical bar 是 threshold
- 如果
,则 右边 bell 的面积和 bell 的面积都是 1 - 如果
,则 右边 bell 的面积和 bell 的面积都是 0 - otherwise,则
右边 bell 的面积永远大于 bell 的面积,因为 bell 更靠右
所以这种情况下永远有
那么问题来了:为什么 classifier.predict_proba(X)[:, 1]
,必然有
同理,想要 AUROC < 0.5,你设法把 classifier.predict_proba(X)[:, 0]
;站在 predict 的角度,这么做相当于 flip the prediction。所以你算出了 AUROC < 0.5 也不要慌,换一下 label 就正常了。
再衍生一下:如果
6. 为什么说 AUROC 比 accuracy 好?Permalink
主要就好在 accuracy 识别不了 random guess。比如 90%
7. 为什么有人说 you should not use ROC curve with highly imbalance data?Permalink
我的觉得有点言重了,但是 ROC 的不足的确是存在的。
更好地讨论这个问题的一篇文章是 The Precision-Recall Plot Is More Informative than the ROC Plot When Evaluating Binary Classifiers on Imbalanced Datasets。
ROC 在处理 imbalanced data 时的不足是:False Positive Rate 不足以反映
- 考虑最常见的
的情况 - Balanced dataset:
; classifier predicts at threashold : - Imbalanced dataset:
; classifier predicts at the same threashold :
如果在所有的 theashold 上都有这样类似的关系,i.e.
那如果是
还有一种说法也比较恰当:ROC is not sensitive to class balance。
待续:更复杂的积分形式Permalink
复习一下符号:假设
wikipedia: Receiver operating characteristic 上的这个式子我推不出来:
到底是
更新:等价形式Permalink
The meaning and use of the area under a receiver operating characteristic (ROC) curve 是篇很好的文章。它提到:这 3 种 metrics 是等价的:
- “True” AUROC
- “True” 的意思是 sample 数要够多,有限的 sample 数不能代表 population,只能算是 estimate
(即上面 wikipedia 的那个大积分形式)- where
is the score for a positive instance and is the score for a negative instance - That is to say, AUROC is equal to the probability that a classifier will rank a randomly chosen positive instance higher than a randomly chosen negative one (assuming ‘positive’ ranks higher than ‘negative’)
- 这个积分的证明在文章的 reference [6] Green D, Swets J. Signal detection theory and psychophysics. New York: John Wiley and Sons, 1966: 45-49 里。(原书我找不到,目前看来只能去买了……)
- where
- Wilcoxon statistic (as in Wilcoxon-Mann-Whitney test)
Comments