ACU个人详解的理解及代码实现

您所在的位置:网站首页 auc统计学原理 ACU个人详解的理解及代码实现

ACU个人详解的理解及代码实现

#ACU个人详解的理解及代码实现| 来源: 网络整理| 查看: 265

ACU详解及代码实现 ROC曲线AUC计算方法一: 方法二:

ROC曲线

理解AUC需要首先理解ROC曲线,AUC是ROC曲线的面积。 详细参考这个博士AUC详解

AUC计算 方法一:

有M个正样本,N个负样本,一共有M*N个样本对,也就是说从M和N中分别取样,然后组成一个样本对,然后计算对正样本对预测概率大于对负样本预测的概率。 ∑ I ( P p o s , P n e c ) M × N \frac{\sum I(P_{pos},P_{nec})}{M \times N} M×N∑I(Ppos​,Pnec​)​ 举个例子:

DLablepreA00.1B00.4C10.35D10.8

这里假设有4个样本,2个正样本和两个负样本。我们所指的概率就是pre,需需要注意的是pre是软概率,也就是越接近1就是正,越接近0就是负,而不是分别针对正负分别预测的,这个很关键,开始我就理解错了。 这里我就是直观的希望对正样本的预测概率大于正样本的。 具体的,这里有四个样本对(C,A),(C,B),(D,A) 和(D,B),这里只有(C,B)是不满足的,应该为零,其他的是1. 那么auc: 1 + 1 + 1 + 0 2 ∗ 2 = 0.75 \frac{1+1+1+0}{2 * 2} = 0.75 2∗21+1+1+0​=0.75 如果两个概率相等,那么 I = 0.5 I=0.5 I=0.5。

方法二:

这个方法本质和方法一是一样的,只不过这里用数学规律进行了计算。

首先将模型预测出来的概率从高到底进行排序(其中正样本M,负样本N个)每个样本设置了一个rank,概率最高的rank是n,其次是n-1。这里的rank实际上就是每一个样本的概率大于多少的样本数量。 基于上面的条件,我们可以发现: 如果我们想要得到的就是每个正样本的概率大于负样本的概率的数量,然后求和。那么,如果概率最大的样本(rank为n)他一定大于剩余的n-1个样本,n-1个样本中有这个正样本M-1个,这M-1个其实并不是我们需要的,所以我们减去,那么就是我们把所有正样本的rank相加,再减去每次多余的正样本就可以了。 举个例子: 样本ABCDEFpre0.80.70.60.50.40.3labelPNPNPNrank654321

A的rank是6,那么代表他是大于等于6个节点的,很明显是包括自己以及其他的正样本,这些实际上应该被扣除,因为(A,正样本)是没有意义d的。也就是说: A: 6 - M C:4 - (M - 1) E:2 - (M - 2) 减去的部分,实际上就是 M,M-1, … ,1, 0,这可以用公式 M ∗ M ( M + 1 ) / 2 M*M(M+1)/2 M∗M(M+1)/2,因此AUC表示为: A U C = ∑ i ∈ p o s r a n k i − M ( 1 + M ) 2 M ∗ N AUC=\frac{\sum_{i \in posrank_i - \frac{M(1+M)}{2}}}{M * N} AUC=M∗N∑i∈posranki​−2M(1+M)​​​ 如果概率相同,则求rank的平均值。

import numpy as np from sklearn.metrics import auc from sklearn.metrics import roc_curve def auc_calculate(labels, preds, n_bins=100): postive_len = sum(labels) negative_len = len(labels) - postive_len total_case = postive_len * negative_len pos_hist = [0] * n_bins # 直方图长度就是100,因为概率是0-1,乘以100,就是0-100 neg_hist = [0] * n_bins bin_width = 1.0 / n_bins for i in range(len(labels)): nth_bin = int(preds[i] / bin_width) if labels[i] == 1: pos_hist[nth_bin] += 1 else: neg_hist[nth_bin] += 1 accumulated = 0 # 用于累加比pos_hist[i]概率小的负样本的个数 satisfied = 0 for i in range(n_bins): satisfied += (pos_hist[i] * accumulated + pos_hist[i] * neg_hist[i] * 0.5) # *0.5是为了计算两个样本概率相等的情况 accumulated += neg_hist[i] return satisfied / float(total_case) if __name__ == '__main__': y = np.array([1, 0, 0, 0, 1, 0, 1, 0, ]) pred = np.array([0.9, 0.8, 0.3, 0.1, 0.4, 0.9, 0.66, 0.7]) fpr, tpr, thresholds = roc_curve(y, pred, pos_label=1) print("-----sklearn:", auc(fpr, tpr)) print("-----py脚本:", auc_calculate(y, pred))

结果: 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3