首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【机器学习 | ROC & AUC】

【机器学习 | ROC & AUC】

原创
作者头像
九年义务漏网鲨鱼
发布2025-06-27 08:00:06
发布2025-06-27 08:00:06
16000
代码可运行
举报
文章被收录于专栏:machine learningmachine learning
运行总次数:0
代码可运行
一、前置知识

真阳性(TPR):正样本被正确分类个数与所有正样本的总数的比值

TPR = \frac{TP}{TP+FN}

假阳性(FPR):负样本被错误分类个数与所有负样本的总数的比值

FPR=\frac{FN}{FN+TN}

其中,TP表示正确分类的正样本,TN表示正确分类的负样本,FN表示错误分类的负样本,FN表示错误分类的负样本

二、ROC基本内容

在机器学习与深度学习模型中,模型输出阈值$\tau$的设置会直接影响到结果的判断,利用ROC表示模型在不同阈值下的表现

在二分类中一般采用Sigmoid激活函数输出结果。如图所示,x轴表示最后模型的输出概率,y轴表示经过sigmoid的变换后的输出结果,对应的TPR、FPR如表示所示,可以发现不同阈值的结果不同。

TPR

FPR

左图

0.5

1

右图

0.75

0.75

不同阈值的设置会造成大量的参数和结果,为此,ROC曲线以FPR为x轴,TPR为y轴绘制二维图像,在ROC图上的特殊线:

  • y = 1:表示正样本全部判断正确,并且x值越小模型的效果越好;
  • x = 0:表示负样本全部没有误判,并且y值越大模型的效果越好;
  • y = x:表示TPR = FPR,(1,1)点表示正样本全部判断正确,负样本全部错判;
三、AUC
  • 基本理解

AUC(Area Under the Curve)表示的是在ROC曲线与坐标轴围成的面积,表示在FPR从0到1的过程中TPR的累积值

\int_0^1 TPR\,d(FPR)
  • x = 0:表示在当前阈值下,只有正样本的得分大于阈值;
  • y = 1:表示在当前阈值下,所有正样本的得分大于阈值;
  • x = 1:表示在当前阈值下,所有样本的得分都大于阈值;

因此,我们可以观察到,当阈值慢慢下降时,有:

① 逐渐有正样本的得分大于阈值,TPR上升,但此时还没有负样本被误判,因此FPR为0,表现为x = 0;

② 当负样本的阈值开始大于阈值时,TRP不变,FPR增加,此时开始对AUC进行计算,因为AUC表示的是从0到1的过程中TPR的累积值

FPR开始增加时,不同的TPR对AUC的累积值不同,比如两个模型分别在TPR=0.5TPR=0.75时负样本分数开始大于阈值,第二个模型在最终AUC的计算得分要优于第一个模型

③ 最好的情况就是所有的正样本得分大于负样本,此时当TPR为1时,FPR才开始增加,这时的TPR累计值为1.

  • 更深层理解

AUC可以描述的是随机抽取一个正样本和负样本,正样本得分大于负样本得分的概率:

$$

AUC=P(正样本得分>负样本得分)

$$

因为AUC在计算的过程中也间接计算了正负样本的排序,当出现错误顺序(误判负样本为正样本时),AUC的累积值减少,如图所示,模型而(蓝色线)的AUC累积值要大于模型一(红色线),这是由于在阈值降低的过程中,出现错误顺序的阈值更低。同时,FPR的增加,可以与坐标轴围成矩形区域,该面积可以表示为样本中得分比当前负样本得分高的所有正负样本对。

四、代码实现
代码语言:python
代码运行次数:0
运行
复制
def calculate_roc_acc(y, y_prop):
    y = np.array(y)
    y_prop = np.array(y_prop)
    
    sorted_indexs = np.argsort(-y_prop) # 默认从小到大将索引排序,所以从大到小需要负号
    y = y[sorted_indexs]
    y_prop = y_prop[sorted_indexs]
    
    posNum = sum(y)
    negNum = len(y) - posNum
    
    # 记录不同阈值下的TPR和FPR
    TPRS = [0]
    FPRS = [0]
    
    # 阈值初始化
    thresholds = y_prop[np.argsort(-y_prop)]
    
    for threshold in thresholds:
        TP = np.sum((y_prop >= threshold) & (y == 1))  # 预测为正且实际为正
        FP = np.sum((y_prop >= threshold) & (y == 0))  # 预测为正但实际为负
        TPRS.append(TP / posNum)
        FPRS.append(FP / negNum)
    
    AUC = 0
    for i in range(1, len(FPRS)):
        AUC += (FPRS[i] - FPRS[i - 1]) * (TPRS[i] + TPRS[i - 1]) / 2

    return FPRS, TPRS, AUC
四、可视化代码
代码语言:python
代码运行次数:0
运行
复制
def plot_roc_curve(FPR, TPR, auc):
    plt.rcParams["axes.linewidth"] = 1.8
    plt.rcParams["axes.labelsize"] = 12
    plt.rcParams["xtick.minor.visible"] = True
    plt.rcParams["ytick.minor.visible"] = True
    plt.rcParams["xtick.direction"] = "in"
    plt.rcParams["ytick.direction"] = "in"
    plt.rcParams["xtick.labelsize"] = 12
    plt.rcParams["ytick.labelsize"] = 12
    plt.rcParams["xtick.top"] = False
    plt.rcParams["ytick.right"] = False
    # plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.figure(figsize=(6, 6))
    plt.plot(FPR, TPR, label=f"AUC = {auc:.2f}", color='blue')
    plt.plot([0, 1], [0, 1], 'r--')
    plt.title("ROC Curve")
    plt.xlabel("False Positive Rate")
    plt.ylabel("True Positive Rate")
    plt.legend(loc="lower right")
    plt.grid()
    plt.show()

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前置知识
  • 二、ROC基本内容
  • 三、AUC
  • 四、代码实现
  • 四、可视化代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档