二分类确定画出roc曲线,以及基于roc曲线获得最佳划分阈值

2023-05-16

问题

在做二分类问题时候,有正样本和负样本。构建的算法,针对每个样本会输出一个分数值。假设该分数大小为[0, 1]区间内的值。有时候单纯地以分数0.5位阈值划分样本为预测为1或者预测为0,效果有时候并不好,此时如何确定很好的阈值分数呢?答案是可以利用roc曲线来确定比较好的划分阈值。

ROC曲线介绍

二分类过程,设定阈值,大于该分数为1,小于该分数为0,统计计算TP, FN, FP,TN等数据计算FPR,TPR


  • p(positive): 标签1
  • n(negative): 标签0
  • t(true): 预测正确
  • f(false): 预测错误

  • TP: 实例是正类并被预测成正类 正确预测正类(把正类预测正类)
  • FP:实例是负类并被预测成正类 错误预测正类(把负类预测为正类)
  • TN:实例是负类并被预测成负类 正确预测负类(把负类预测为负类)
  • FN:实例是正类并被预测为负类 错误预测负类 (把正类预测为负类)

        |          -      |     实际表现           |
        ---------------------------------------------------
        |                |      1        0       |   合计
        |--------------------------------------------------
        |           | 1  |     11(TP)    01(FP)  |   TP+FP
        | 预测表现   |    |                       |
        |           |  0 |     10(FN)    00(TN)  |   FN+TN
        | ----------------------------------------------------------
        |   合计        |       TP+FN      FP+TN |  TP + FP + FN + TN
        -------------------------------------------------------------
  • 真正类率(TPR):TPR = TP/(TP+FN) 刻画的是分类器所识别出的 正实例占所有正实例的比例 灵敏度

  • 负正类率(FPR): FPR = FP/(FP+TN) 计算的是分类器错认为正类的负实例占所有负实例的比例 1-特异度

  • 真负类率(TNR): TNR = TN/(FP+TN) = 1-FPR 分类器所识别出的负实例占所有负实例的比例 特异度

  • 准确率: accuracy = (TP+TN) / (TP+TN+FP+FN) 准确率的定义是预测正确的结果占总样本的百分比, 样本不均衡时候不好

  • 精准率: precision = TP / (TP+FP) 所有被预测为正的样本中实际为正的样本的概率

  • 召回率(查全率): recall = TP / (TP+FN) 在实际为正的样本中被预测为正样本的概率

  • P-R曲线:查准率-查全率, 希望查准率和查全率同时高,但不现实

  • F1分数均衡:F1_score = (2pr)/(p+r)

  • ROC曲线: 横坐标FPR, 纵坐标TPR

代码实现

两种方式:

  • 自己遍历统计计算
  • 调用skearln中的相关计算包
#!/bin/python
# fileUsing: 画出ROC曲线,并熟悉混淆矩阵相关的知识

import sys
import numpy as np
from sklearn import metrics
from sklearn.metrics import auc
import matplotlib.pyplot as plt


class DrawRoc(object):
    def __init__(self):
        pass

    def draw_roc(self, predict_scores: list, ture_labelsi: list) -> float:
        """二分类过程,设定阈值,大于该分数为1,小于该分数为0,统计计算TP, FN, FP,TN等数据
            计算FPR,TPR
            p(positive): 标签1
            n(negative): 标签0
            t(true): 预测正确
            f(false): 预测错误
            TP: 实例是正类并被预测成正类  正确预测正类(把正类预测正类)
            FP:实例是负类并被预测成正类  错误预测正类(把负类预测为正类)
            TN:实例是负类并被预测成负类  正确预测负类(把负类预测为负类)
            FN:实例是正类并被预测为负类  错误预测负类 (把正类预测为负类)
            -----------------------------------------
            |                |     实际表现           |
            ---------------------------------------------------
            |                |      1        0       |   合计
            |--------------------------------------------------
            |           | 1  |     11(TP)    01(FP)  |   TP+FP
            | 预测表现   |    |                       |
            |           |  0 |     10(FN)    00(TN)  |   FN+TN
            | ----------------------------------------------------------
            |   合计        |       TP+FN      FP+TN |  TP + FP + FN + TN
            -------------------------------------------------------------
            真正类率(TPR):TPR = TP/(TP+FN)  刻画的是分类器所识别出的 正实例占所有正实例的比例  灵敏度
            负正类率(FPR): FPR = FP/(FP+TN)  计算的是分类器错认为正类的负实例占所有负实例的比例 1-特异度
            真负类率(TNR): TNR = TN/(FP+TN) = 1-FPR 分类器所识别出的负实例占所有负实例的比例 特异度

            准确率: accuracy = (TP+TN) / (TP+TN+FP+FN)  准确率的定义是预测正确的结果占总样本的百分比, 样本不均衡时候不好
            精准率: precision = TP / (TP+FP)  所有被预测为正的样本中实际为正的样本的概率
            召回率(查全率): recall = TP / (TP+FN)  在实际为正的样本中被预测为正样本的概率
            P-R曲线:查准率-查全率, 希望查准率和查全率同时高,但不现实
            F1分数均衡:F1_score = (2*p*r)/(p+r)
            ROC曲线: 横坐标FPR, 纵坐标TPR
        """
        ths = list(np.linspace(0, 1, 100))  # 阈值 分100等分
        tprs = []
        fprs = []
        diffs = []
        auc = 0
        # 开始计算
        for th in ths:
            tp = 0
            tn = 0
            fp = 0
            fn = 0
            predict_labels = [1 if score >= th else 0 for score in predict_scores]  # 大于等于阈值时候,判定为预测为正
            length = len(predict_labels)
            for idx in range(len(predict_labels)):
                predict_label = predict_labels[idx]
                ture_label = ture_labels[idx]
                if ture_label == 1 and predict_label == 1:
                    tp += 1
                if ture_label == 1 and predict_label == 0:
                    fn += 1
                if ture_label == 0 and predict_label == 0:
                    tn += 1
                if ture_label == 0 and predict_label == 1:
                    fp += 1
            tpr = tp / (tp+fn)
            fpr = fp / (fp+tn)
            tprs.append(tpr)
            fprs.append(fpr)
            diffs.append(tpr-fpr)

        # get fpr tpr ths and plot
        plt.plot(fprs, tprs, 'yo-')
        plt.ylabel('True Positive Rate')
        plt.xlabel('False Positive Rate')
        plt.show()
        plt.savefig('roc1.png')

        # calc auc, 受样本影响大,除非全是正样本,无负样本时候,使用类似微积方法计算得到的面积才对
        """
        fprs_tprs = []
        for i in range(len(ths)):
            fpr = tprs[i]
            tpr = fprs[i]
            fprs_tprs.append([fpr, tpr])
        fprs_tprs.sort(key=lambda x:x[0], reverse=False)
        for i in range(1, len(ths)):
            fpr, tpr = fprs_tprs[i-1]
            fpr_i, tpr_i = fprs_tprs[i]
            height = tpr_i
            weight = fpr_i - fpr
            auc += height * weight
        print("auc1:", auc)
        """

        # get best th
        max_diff = max(diffs)
        optimal_idx = diffs.index(max_diff)
        optimal_th = ths[optimal_idx]
        return optimal_th

    def draw_roc_by_sklearn(self, predict_scores: list, ture_labels: list) -> float:
        score = np.array(predict_scores)
        y = np.array(ture_labels)
        fpr, tpr, thresholds = metrics.roc_curve(y, score)
        auc = metrics.auc(fpr, tpr)
        print("auc2:", auc)
        optimal_idx = np.argmax(tpr - fpr)
        optimal_th = thresholds[optimal_idx]
        plt.plot(fpr, tpr, 'bo-')
        plt.ylabel('True Positive Rate')
        plt.xlabel('False Positive Rate')
        plt.show()
        plt.savefig('roc2.png')
        return optimal_th


if __name__ == '__main__':
    dr = DrawRoc()
    right_scores_file = sys.argv[1]  # 正确样本的分数列表
    error_scores_file = sys.argv[2]   # 错误样本的分数列表
    predict_scores = []
    ture_labels = []
    with open(right_scores_file) as f:
        for line in f:
            data = line.rstrip('\n')
            if data:
                score = float(data)
                predict_scores.append(score)
                ture_labels.append(1)

    with open(error_scores_file) as f:
        for line in f:
            data = line.rstrip('\n')
            if data:
                score = float(data)
                predict_scores.append(score)
                ture_labels.append(0)
    th1 = dr.draw_roc(predict_scores, ture_labels)
    print("th1:", th1)
    th2 = dr.draw_roc_by_sklearn(predict_scores, ture_labels)
    print("th2:", th2)

结果

  • roc1
    在这里插入图片描述
  • roc2
    在这里插入图片描述

参考

  • https://blog.csdn.net/ybdesire/article/details/51999995
  • https://zhuanlan.zhihu.com/p/25212301
  • https://www.cnblogs.com/nxld/p/6365637.html
  • https://zhuanlan.zhihu.com/p/32824418
  • https://blog.csdn.net/qq_34840129/article/details/85253932
  • https://www.cnblogs.com/nxld/p/6365637.html
  • https://stackoverflow.com/questions/28719067/roc-curve-and-cut-off-point-python
  • https://blog.csdn.net/ZYC88888/article/details/103755818
  • https://zhuanlan.zhihu.com/p/46714763(推荐)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

二分类确定画出roc曲线,以及基于roc曲线获得最佳划分阈值 的相关文章

  • stata绘制roc曲线_绘制ROC曲线、找截断值,教你两种软件操作方法!

    我们在前面学习过用SPSS SPSS操作 多项测量指标的ROC曲线分析 和Stata Stata教程 ROC曲线下面积的比较 绘制ROC曲线 但是 最佳临界点 截断值 cut off point 该怎么选取呢 今天我们来讲一下如何用SPSS
  • ROC曲线绘制与计算

    假设现在有一个二分类问题 xff0c 先引入两个概念 xff1a 真正例率 xff08 TPR xff09 xff1a 正例中预测为正例的比例假正例率 xff08 FPR xff09 xff1a 反例中预测为正例的比例 再假设样本数为6 x
  • 理解ROC曲线,TPR与FPR

    在垃圾邮件判别模型中 邮件被判别为垃圾邮件为positive 被判别为非垃圾邮件为negative 那么 TPR TP TP FN 的含义是 垃圾邮件被正常判别为垃圾邮件的比例 FPR FP FP TN 的含义是 非垃圾邮件被判别为垃圾邮件
  • 如何获得逻辑回归中 ROC 的最佳截止点作为数字

    我想将逻辑回归中 ROC 的最佳截止点作为数字而不是两条交叉曲线 使用下面的代码 我可以获得显示最佳点的图 但在某些情况下 我只需要该点作为可用于其他计算的数字 以下是代码行 library Epi ROC form IsVIP var1
  • sklearn 中留一交叉验证的 ROC 曲线

    我想绘制一个ROC曲线的分类器使用留一法交叉验证 好像有人问过类似的问题here但没有任何答复 在另一个问题中here据称 为了使用 LeaveOneOut 获得有意义的 ROC AUC 您需要 计算每次折叠的概率估计 每个折叠只包含 一个
  • 根据 R 中的交叉验证(训练)数据绘制 ROC 曲线

    我想知道是否有一种方法可以从使用 SVM RFE 模型生成的交叉验证数据中绘制平均 ROC 曲线caret包裹 我的结果是 Recursive feature selection Outer resampling method Cross
  • 在单个 ROC 图上绘制线性判别分析、分类树和朴素贝叶斯曲线

    数据显示在页面的最底部 称为 LDA scores 这是一个分类任务 我在数据集上执行了三种监督机器学习分类技术 提供所有编码以显示这些 ROC 曲线是如何生成的 我很抱歉提出了一个有问题的问题 但近两周来我一直在尝试使用不同的代码组合来解
  • 来自插入符号中的训练数据的 ROC 曲线

    使用R包插入符号 如何根据train 函数的交叉验证结果生成ROC曲线 比如说 我执行以下操作 data Sonar ctrl lt trainControl method cv summaryFunction twoClassSummar
  • ROC 函数错误“预测变量必须是数字或有序的。”

    我无法让 ROC 函数正常工作 收到错误 预测器必须是数字或有序的 我浏览了其他帖子 但没有解决我的问题 非常感谢任何帮助 Get data flying dget https www math ntnu no emner TMA4268
  • R 中的 SVM:“预测器必须是数字或有序的。”

    我是 R 新手 遇到了这个问题 我想比较两种预测技术 支持向量机和神经网络 将它们应用于某些数据 并且我想比较它们的性能 为此 我使用 ROC 曲线 该代码应该计算 ROC 曲线下的面积 但它不起作用 神经网络代码工作正常 但是当 SVM
  • 如何使用 matplotlib/python 绘制 ROC 曲线 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想绘制一条 ROC 曲线python with matplotlib并想像这样展示它 假设我们有 0 0 到 1 0 的预测y sc
  • roc_auc_score 和plot_roc_curve 结果不同

    我正在训练一个RandomForestClassifier sklearn 预测信用卡欺诈 然后当我测试模型并检查 rocauc 分数时 我在使用时会得到不同的值roc auc score and plot roc curve roc au
  • 在 R 中使用 ROCR 与 pROC 绘制 ROC

    我正在绘制 ROC 并测量部分 AUC 作为生态位模型质量的指标 当我在 R 中工作时 我使用 ROCR 和 pROC 包 我会选择使用其中一款 但现在 我只是想看看它们的表现如何 以及是否能更好地满足我的需求 让我困惑的一件事是 在绘制
  • 绘制多个类别的 ROC 曲线

    我正在按照此链接绘制多个类别的 ROC 曲线的文档 http scikit learn org stable auto examples model selection plot roc html http scikit learn org
  • Scikit - 如何定义绘制 roc 曲线的阈值

    我有一个增强树模型以及测试数据集的概率和分类 我正在尝试绘制相同的 roc curve 但我无法弄清楚如何在 scikit learn 中定义 roc 曲线的阈值 alpha from sklearn metrics import prec
  • 如何用tensorflow计算AUC?

    我已经使用 Tensorflow 构建了一个二元分类器 现在我想使用 AUC 和准确性来评估分类器 就准确性而言 我可以轻松地这样做 X tf placeholder float None n input y tf placeholder
  • 使用 pROC 绘制 ROC 曲线失败

    我有一个数据集 其组织方式如下 gt head crypto data time btc price btc change btc change label eth price block size difficulty estimated
  • 使用 Caret 包的测试集的 ROC 曲线

    我正在尝试从测试集上的插入符号中获取最佳模型的 ROC 曲线 我碰到MLeval包似乎很方便 输出非常全面 使用几行代码提供了所有需要的指标和图表 一个很好的例子在这里 https stackoverflow com a 59134729
  • R 中多类分类的 ROC 曲线

    我有一个包含 6 个类别的数据集 我想绘制多类别分类的 ROC 曲线 Achim Zeileis 给出的第一个答案非常好 R中使用rpart包的ROC曲线 https stackoverflow com questions 30818188
  • 使用seaborn绘制简单线图

    我正在尝试使用seaborn python 绘制ROC曲线 对于 matplotlib 我只需使用该函数plot plt plot one minus specificity sensitivity bs where one minus s

随机推荐

  • cefsharp111.2.20(winform)版本体验

    第一步 xff1a 更新步骤 xff1a 先下载再本地更新会快一点 https globalcdn nuget org packages cefsharp winforms 111 2 20 nupkg https globalcdn nu
  • CefSharp.WinForms 112.2.70最新版体验

    一 准备 下载最新包及依赖包 对应 NET4 5 2 后续版本可能4 6 2 到packages中 本地升级更快 NuGet Gallery CefSharp WinForms 112 2 70 NuGet Gallery CefSharp
  • VUE3(.NET6)管理后台

    基于Admin NET框架 xff0c 预览下效果 内置功能 主控面板 xff1a 控制台页面 xff0c 可进行工作台 xff0c 分析页 xff0c 统计等功能的展示 用户管理 xff1a 对企业用户和系统管理员用户的维护 xff0c
  • 2011年养成的一个工作习惯

    作者 xff1a 朱金灿 来源 xff1a http blog csdn net clever101 有一句名言 xff0c 没有记录的公司 xff0c 迟早要垮掉的 xff0c 多么尖锐 个人也不是如此吗 xff1f 在下半年 xff0c
  • Cefsharp.WinForms-v112.3.0 带您最新版体验(小更新)

    一 准备 下载最新包及依赖包 对应 NET4 5 2 后续版本可能4 6 2 到packages中 本地升级更快 NuGet Gallery CefSharp WinForms 112 3 0 NuGet Gallery CefSharp
  • 无人机飞行控制算法、控制律设计软件与半物理仿真

    工业级多功能可编程飞行控制系统专业的图形化控制律设计软件灵活强大的工程应用开发平台DSP处理器及高精度传感器自定义高速遥测数据采集嵌入式半物理仿真系统丰富的用户设备接口适用于固定翼 旋翼机 特殊飞行器 车船艇 机器人 云台等 概 述 xff
  • 程序调试记录

    最近把师兄的程序在万兆网络上进行测试 xff0c 现在把调试中出现的问题进行记录 xff1a 1 xff09 其中一共是十六块板子 xff0c 板子的配置文件是sipixel xml xff0c 每块板子的配置信息里都有对应的IP xff0
  • 华清远见嵌入式学习day27——编译工具和环境搭建

    0 系统移植四天课程安排 1 编译工具 xff0c 环境搭建 2 bootloader 3 kernel 4 文件系统 1 嵌入式系统的应用领域 1 军事 2 医疗 3 移动设备 4 家电 5 工控 2 什么是嵌入式系统 一般的定义 xff
  • tf.Variable函数的用法

    tf Variable xff08 initializer xff0c name xff09 xff1a initializer是初始化参数 xff0c 可以有tf random normal xff0c tf constant xff0c
  • Docker入门操作+文件备份

    文件备份操作 bin sh it is a shell script which provides function of auto backup ecology logfiles regularly by 494389 date 61 9
  • Qnap Docker(Container Station)更改国内镜像源

    0x01qpkg环境 通常qnap市场中下载的qpkg应用 xff0c 其环境变量就在自己的包环境中 所以要修改系统中的配置 xff0c 通常需要修改qpkg应用中对应的配置 即 share CACHEDEV1 DATA qpkg xxx
  • docker源码编译(containerd+runc源码编译)

    目录 源码下载docker cli docker enginebugsgo get timeoutdebian超时git clone TLS containerd源码编译runc源码编译docker 43 containerd 43 run
  • ros中激光雷达的消息类型(sensor_msgs/LaserScan Message)说明

    最近在做一些视觉和激光数据融合的项目 xff0c 但是对激光数据的结构不是太了解 xff0c 因此查了很多相关的内容 xff0c 记录以下 下图是在http wiki ros org中截取的图片 xff1a Header 是一个结构体 xf
  • Linux下安装常见的configure错误列表

    Linux下安装常见的configure错误列表 标签 xff1a linux nginx configure 安装 错误 it 附一些常见的configure错误列表供参考 configure error No curses termca
  • 世界上不存在完美的人性

    白夜追凶 观后感 作者 xff1a 朱金灿 来源 xff1a http blog csdn net clever101 前几天看了克里斯多福 诺兰导演的惊悚电影 白夜追凶 剧情大致如下 xff1a 威尔 多莫 xff08 阿尔 帕西诺饰 x
  • k210-arduino深度学习视觉机械臂抓取

    一 arduino对机械臂的基础控制 1 首先实现arduino对机械臂的控制 xff08 点动和自动 xff09 xff0c 六个轴分别定义为xyzjkl 点动 xff1a 点动方式为按一下对应按键使对应轴正转或反转3度 xff0c 此方
  • stm32串口助手配置步骤

    串口设置的一般步骤可以总结为如下几个步骤 xff1a 1 串口时钟使能 xff0c GPIO 时钟使能 2 设置引脚复用器映射 xff1a 调用 GPIO PinAFConfig 函数 3 GPIO 初始化设置 xff1a 要设置模式为复用
  • linux查看新增串口、USB设备,Minicom + Usb转串口

    查看新增串口 USB设备 注意 xff1a 虚拟机环境下的ubuntu默认情况下是不能自动识别的 xff0c 需要在虚拟机窗口右下角点击 34 Prolific USB Serial Controller 34 xff0c 然后选择 34
  • yolo图像检测数据集格式转换:xml 与 txt格式相互转换

    格式介绍 一图流介绍的比较详细 xff0c 一般图像检测数据集格式为txt或者xml格式 xff0c 在使用labelimg进行标注的时候 xff0c 可以设置获得不同格式的数据集 xff0c 以满足不同算法训练格式要求 xff1a 一般建
  • 二分类确定画出roc曲线,以及基于roc曲线获得最佳划分阈值

    问题 在做二分类问题时候 xff0c 有正样本和负样本 构建的算法 xff0c 针对每个样本会输出一个分数值 假设该分数大小为 0 1 区间内的值 有时候单纯地以分数0 5位阈值划分样本为预测为1或者预测为0 xff0c 效果有时候并不好