ROC理解与AUC计算

说到ROC曲线,我们首先想到的是下面这四个值
  • TP     (真正)     实际正
  • FP     (假正)     实际负
  • TN     (真负)     实际负
  • FN     (假负)     实际正

以及下面两个比率
  • TPR(真正率) = TP➗(TP+FN) = 被预测正确的正例➗所有实际正例
  • FPR(假正率) = FP➗(FP+TN) = 被预测错误的负例➗所有实际负例

ROC曲线就是根据通过取不同的阈值,得到不同的(FPR, TPR)点画出来的曲线。
FPR为x轴,TPR为y轴

可以想象如果阈值为0,那么>=0的都认为是正例,所有的正例都被预测正确则FPR=1, 所有的负例都被预测错误TPR=1 最右侧点
如果阈值为1,那么所有的正例都认为是负例则FPR=0,没有负例被预测错误则TPR=0 最左侧点
AUC就是这条曲线下的面积,面积越大说明这个分类器的效果越好。

在推荐或者搜索里面一般是要评价最后这个结果的排序能力,那么我们也可以通过排序的好坏来计算AUC。AUC还有一个有趣的性质就是测试任意给定一个正样本和负样本,这个正样本有多大的概率大于负样本,下面解释一下这个公式。


怎么理解上面的公式呢,设正样本数量为M,负样本数量为N,那么正负两两组合就是M*N种,AUC=这些组合中正样本大于负样本的数量除以M*N。
计算方法如下: 按score从大到小倒序排序,score最大的rank为n(n=M+N)以此类推。score最大的正例rank为i的话,说明和该正例组合的样本一共有i种,还要减掉M个和正样本组合的情况, 排第二的正例要减去 M-1个正样本,以此类推,最后我们要减去的就是一个等比数列的和。这样就得到了上面的公式。就很容易写代码实现了。

如下计算AUC的scala代码:
<pre name="code" class="java">def abs(n: Double): Double = {
    n match {
        case i if i < 0 => -n
        case _ => n
    }
}

val datas = Array((0.7, 1.0), (0.8, 0.0), (0.9, 1.0), (0.5, 0.0))
val predicts = datas.sortBy(_._1)

val M = predicts.filter{case (score, label) => abs(label - 1.0) <= 1e-6}.length.toDouble
val N = predicts.filter{case (score, label) => abs(label - 0.0) <= 1e-6}.length.toDouble
val sumRank = predicts.zipWithIndex.map {
    case ((score, label), index) => (label, index+1)
}.filter {
    case (label, index) => abs(label - 1.0) <= 1e-6
}.map {
    case (label, index) => index
}.sum.toDouble

val auc = M*N match {
    case i if (i > 0) =>  (sumRank - M*(1+M)/2)/(M*N)
    case _ => 0.0
}
println(auc)


 输出结果:0.75 






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值