上一篇博客()介绍了二分类下的ROC曲线及AUC计算,本文主要介绍多分类下的ROC曲线及AUC计算。

对于多分类数据,假设测试样本个数为m,分类个数为n(分类label分别为:1,2,...,n),可以将这些样本及对应的label表示为矩阵形式,每行一个样本,每列为该样本是否属于该分类,从而形成一个[m, n]的标签矩阵:

ID

分类1

分类2

分类3

A

1

0

0

B

0

0

1

C

0

1

0

D

0

0

1

模型预测完成后,会计算出测试样本在各个分类下的概率,模型预测得分也能用一个[m, n]的矩阵表示,每一行表示样本在各个类别下的概率,记该矩阵为P。

ID

分类1

分类2

分类3

A

0.8

0.15

0.05

B

0.2

0.3

0.5

C

0.3

0.6

0.1

D

0.2

0.1

0.7

多分类下画ROC曲线有两种方法:

方法1:对每种类别,都可以从矩阵P中得到m个测试样本在该分类下的打分(矩阵P中的列),从矩阵L中获取样本的类别,从而形成一个类似二分类的得分矩阵,以上图为例,分类1 的矩阵为:

ID

label

score

A

1

0.8

B

0

0.2

C

0

0.3

D

0

0.2

按二分类中画ROC曲线的方法,根据以上矩阵,可以计算出各个阈值下的假正例率(FPR)和真正例率(TPR),从而画出一条ROC曲线。

对每一个类别,可以画出一条ROC曲线,总共可以画出n条ROC曲线。最后对这n条ROC曲线取平均值,即可得到最终的ROC曲线。

在python中,该方法对于sklearn里sklearn.metrics.roc_auc_score函数中参数average值为'macro'的情况。

方法2:对于一个测试样本:

(1)标签由0和1组成,1的位置表明了它的类别,0表示其他类别。1对应二分类问题中的“正”,0对应“负”

(2)如果模型对该样本分类正确,则该样本在标签矩阵L中1对应的位置在概率矩阵P中的值,即为模型预测该分类的概率值。

基于以上两点,将标签矩阵L和概率矩阵P分别按行展开(即sklearn里的ravel()函数),然后转置形成两列,这就得到了一个二分类结果,根据结果直接画出ROC曲线。

在python中,该方法对于sklearn里sklearn.metrics.roc_auc_score函数中参数average值为'micro'的情况。

代码示例:

#-*-coding:utf-8-*-

import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle
from sklearn.metrics import roc_curve, auc
from scipy import interp

y_label = np.array([
[1, 0, 0], [1, 0, 0], [1, 0, 0],
[0, 1, 0], [0,  1, 0], [0, 1, 0],
[0, 0, 1], [0, 0, 1], [0, 0, 1]
])

y_score = np.array([
[0.8, 0.1, 0.1], [0.2, 0.32, 0.48], [0.6, 0.1, 0.3],
[0.2, 0.5, 0.3], [0.1, 0.6, 0.3], [0.2, 0.75, 0.05],
[0.05, 0.05, 0.9], [0.1, 0.3, 0.6], [0.12, 0.8, 0.08],
])

n_classes = 3

# 计算每一类的ROC
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(n_classes):
    fpr[i], tpr[i], _ = roc_curve(y_label[:, i], y_score[:, i])
    roc_auc[i] = auc(fpr[i], tpr[i])

# micro(方法二)
fpr["micro"], tpr["micro"], _ = roc_curve(y_label.ravel(), y_score.ravel())
roc_auc["micro"] = auc(fpr["micro"], tpr["micro"])

# macro(方法一)
# First aggregate all false positive rates
all_fpr = np.unique(np.concatenate([fpr[i] for i in range(n_classes)]))
# Then interpolate all ROC curves at this points
mean_tpr = np.zeros_like(all_fpr)
for i in range(n_classes):
    mean_tpr += interp(all_fpr, fpr[i], tpr[i])
# Finally average it and compute AUC
mean_tpr /= n_classes
fpr["macro"] = all_fpr
tpr["macro"] = mean_tpr
roc_auc["macro"] = auc(fpr["macro"], tpr["macro"])

# Plot all ROC curves
lw=2
plt.figure()
plt.plot(fpr["micro"], tpr["micro"],
         label='micro-average ROC curve (area = {0:0.2f})'
               ''.format(roc_auc["micro"]),
         color='deeppink', linestyle=':', linewidth=4)

plt.plot(fpr["macro"], tpr["macro"],
         label='macro-average ROC curve (area = {0:0.2f})'
               ''.format(roc_auc["macro"]),
         color='navy', linestyle=':', linewidth=4)

colors = cycle(['aqua', 'darkorange', 'cornflowerblue'])
for i, color in zip(range(n_classes), colors):
    plt.plot(fpr[i], tpr[i], color=color, lw=lw,
             label='ROC curve of class {0} (area = {1:0.2f})'
             ''.format(i, roc_auc[i]))

plt.plot([0, 1], [0, 1], 'k--', lw=lw)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('multi-calss ROC')
plt.legend(loc="lower right")
plt.show()

ROC曲线:

多类别dice tensorflow 多类别roc曲线_模型预测