• 多分类下的ROC曲线和AUC


     本文主要介绍一下多分类下的ROC曲线绘制和AUC计算,并以鸢尾花数据为例,简单用python进行一下说明。如果对ROC和AUC二分类下的概念不是很了解,可以先参考下这篇文章:http://blog.csdn.net/ye1215172385/article/details/79448575

            由于ROC曲线是针对二分类的情况,对于多分类问题,ROC曲线的获取主要有两种方法:

            假设测试样本个数为m,类别个数为n(假设类别标签分别为:0,2,...,n-1)。在训练完成后,计算出每个测试样本的在各类别下的概率或置信度,得到一个[m, n]形状的矩阵P,每一行表示一个测试样本在各类别下概率值(按类别标签排序)。相应地,将每个测试样本的标签转换为类似二进制的形式,每个位置用来标记是否属于对应的类别(也按标签排序,这样才和前面对应),由此也可以获得一个[m, n]的标签矩阵L。

             比如n等于3,标签应转换为:

            方法1:每种类别下,都可以得到m个测试样本为该类别的概率(矩阵P中的列)。所以,根据概率矩阵P和标签矩阵L中对应的每一列,可以计算出各个阈值下的假正例率(FPR)和真正例率(TPR),从而绘制出一条ROC曲线。这样总共可以绘制出n条ROC曲线。最后对n条ROC曲线取平均,即可得到最终的ROC曲线。

            方法2:首先,对于一个测试样本:1)标签只由0和1组成,1的位置表明了它的类别(可对应二分类问题中的‘’正’’),0就表示其他类别(‘’负‘’);2)要是分类器对该测试样本分类正确,则该样本标签中1对应的位置在概率矩阵P中的值是大于0对应的位置的概率值的。基于这两点,将标签矩阵L和概率矩阵P分别按行展开,转置后形成两列,这就得到了一个二分类的结果。所以,此方法经过计算后可以直接得到最终的ROC曲线。

           上面的两个方法得到的ROC曲线是不同的,当然曲线下的面积AUC也是不一样的。 在python中,方法1和方法2分别对应sklearn.metrics.roc_auc_score函数中参数average值为'macro'和'micro'的情况。

          下面以方法1为例,直接上代码,概率矩阵P和标签矩阵L分别对应代码中的y_score和y_one_hot:

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
     
    import numpy as np
    import pandas as pd
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    from sklearn.model_selection import train_test_split
    from sklearn.linear_model import LogisticRegressionCV
    from sklearn import metrics
    from sklearn.preprocessing import label_binarize
     
    if __name__ == '__main__':
        np.random.seed(0)
        data = pd.read_csv('iris.data', header = None)  #读取数据
        iris_types = data[4].unique()
        n_class = iris_types.size
        x = data.iloc[:, :2]  #只取前面两个特征
        y = pd.Categorical(data[4]).codes  #将标签转换0,1,...
        x_train, x_test, y_train, y_test = train_test_split(x, y, train_size = 0.6, random_state = 0)
        y_one_hot = label_binarize(y_test, np.arange(n_class))  #装换成类似二进制的编码
        alpha = np.logspace(-2, 2, 20)  #设置超参数范围
        model = LogisticRegressionCV(Cs = alpha, cv = 3, penalty = 'l2')  #使用L2正则化
        model.fit(x_train, y_train)
        print '超参数:', model.C_
        # 计算属于各个类别的概率,返回值的shape = [n_samples, n_classes]
        y_score = model.predict_proba(x_test)
        # 1、调用函数计算micro类型的AUC
        print '调用函数auc:', metrics.roc_auc_score(y_one_hot, y_score, average='micro')
        # 2、手动计算micro类型的AUC
        #首先将矩阵y_one_hot和y_score展开,然后计算假正例率FPR和真正例率TPR
        fpr, tpr, thresholds = metrics.roc_curve(y_one_hot.ravel(),y_score.ravel())
        auc = metrics.auc(fpr, tpr)
        print '手动计算auc:', auc
        #绘图
        mpl.rcParams['font.sans-serif'] = u'SimHei'
        mpl.rcParams['axes.unicode_minus'] = False
        #FPR就是横坐标,TPR就是纵坐标
        plt.plot(fpr, tpr, c = 'r', lw = 2, alpha = 0.7, label = u'AUC=%.3f' % auc)
        plt.plot((0, 1), (0, 1), c = '#808080', lw = 1, ls = '--', alpha = 0.7)
        plt.xlim((-0.01, 1.02))
        plt.ylim((-0.01, 1.02))
        plt.xticks(np.arange(0, 1.1, 0.1))
        plt.yticks(np.arange(0, 1.1, 0.1))
        plt.xlabel('False Positive Rate', fontsize=13)
        plt.ylabel('True Positive Rate', fontsize=13)
        plt.grid(b=True, ls=':')
        plt.legend(loc='lower right', fancybox=True, framealpha=0.8, fontsize=12)
        plt.title(u'鸢尾花数据Logistic分类后的ROC和AUC', fontsize=17)
        plt.show()

    我的实战

    Bnew_one1=[]
        for lis in Bnew4:
            bol=np.zeros(51)
            bol=bol.tolist()
            bol[lis[0]]=1
            Bnew_one1.append(bol)
        
        Blast_one=[]
        for lis in Blast:
            bol=np.zeros(51)
            bol=bol.tolist()
            bol[lis[0]]=1
            Blast_one.append(bol)
        
        Bnew_one1=np.array(Bnew_one1)
        Blast_one=np.array(Blast_one)
        Bnew_one=np.array(Bnew_one)
        
        print('调用函数auc:', metrics.roc_auc_score(Blast_one, Bnew_one1, average='micro'))
        
        fpr, tpr, thresholds = metrics.roc_curve(Blast_one.ravel(),Bnew_one1.ravel())
        auc = metrics.auc(fpr, tpr)
        print('手动计算auc:', auc)
        #绘图
        mpl.rcParams['font.sans-serif'] = u'SimHei'
        mpl.rcParams['axes.unicode_minus'] = False
        #FPR就是横坐标,TPR就是纵坐标
        plt.plot(fpr, tpr, c = 'r', lw = 2, alpha = 0.7, label = u'AUC=%.3f' % auc)
        plt.plot((0, 1), (0, 1), c = '#808080', lw = 1, ls = '--', alpha = 0.7)
        plt.xlim((-0.01, 1.02))
        plt.ylim((-0.01, 1.02))
        plt.xticks(np.arange(0, 1.1, 0.1))
        plt.yticks(np.arange(0, 1.1, 0.1))
        plt.xlabel('False Positive Rate', fontsize=13)
        plt.ylabel('True Positive Rate', fontsize=13)
        plt.grid(b=True, ls=':')
        plt.legend(loc='lower right', fancybox=True, framealpha=0.8, fontsize=12)
        plt.title(u'大类问题一分类后的ROC和AUC', fontsize=17)
        plt.show()
        

  • 相关阅读:
    消息分发
    subprocess.CalledProcessError: Command ‘(‘lsb_release’, ‘-a’)’ returned non-zero exit status 1.
    ubuntu14.04 安装python3.7
    通过shell脚本查看python版本并比较
    shell 小数比较大小
    python 私有方法
    python 类的倒入
    python 路径拼接
    python 脚本接受参数
    python 获取文件运行路径
  • 原文地址:https://www.cnblogs.com/caiyishuai/p/13270956.html
Copyright © 2020-2023  润新知