写在前面:
sklearn计算auc(一):使用sklearn.metrics.roc_auc_score()计算二分类的auc
用法:计算auc
sklearn.metrics.roc_auc_score(y_true, y_score, *, average='macro', sample_weight=None, max_fpr=None, multi_class='raise', labels=None)[source])
输入参数(只介绍多分类情况下怎么使用):
y_true:真实的标签。形状(n_samples,)或(n_samples, n_classes)。二分类和多分类(一个样本只属于一个类别)的形状(n_samples,1),而多标签(一个样本属于多个类别)情况的形状(n_samples, n_classes)。
y_score:目标分数。形状(n_samples,)或(n_samples, n_classes)。多分类情况下,y_score概率的和为1。多分类和多标签情况下,输入的形状是(n_samples, n_classes)。多分类情况下,score的顺序必须跟labels的顺序相同。或者对应于y_true中标签的数字或字典顺序。
average='macro':用于多分类,只有两个属性可以选择 ‘macro’ 和 ‘weighted’ 。' macro ':计算每个标签的指标,并找到它们的未加权平均值。不考虑样本类别是否平衡。' weighted ':计算每个标签的指标,并找到它们的平均值,对(每个标签的真实实例的数量)进行加权。
sample_weight=None:样本权重。形状(n_samples,),默认=无。
max_fpr=None:不适用多分类。
multi_class='raise':只用于多分类。要使用的配置类型。默认值会引发错误,因此必须显式传递'ovr'或'ovo'。'ovr':对类别不平衡比较敏感,就是把一类当做正样本,其他类别都是负样本; 'ovo':对类别不平衡不敏感,将某一个类别A跟其他类组合,以A为正例,跟他组合的类别为负例,计算auc,最后取平均。即一对一,比如其他类别有B、C、D,则有AvsB AvsC AvsD,计算得到的auc取平均值作为最终结果。
labels=None:只用于多分类情况,索引y_score中的类的标签列表。如果没有,则使用y_true中标签的数字或字典顺序。
输出:
auc:是一个float的值。
2.1数据
这里做一个四分类,labels = [0, 1, 2, 3]要评估的数据格式如下:
id | label | pred_label | pred_label_score | pred_scores(模型输出的scores) |
12298 | 0 | 0 | 0.98808575 | 0.98808575_0.0009340739_0.005286925_0.005693246 |
68539 | 0 | 0 | 0.7303916 | 0.7303916_0.0015238398_0.0037256505_0.26435888 |
18922 | 0 | 0 | 0.9602715 | 0.9602715_0.0010683154_0.024411766_0.014248497 |
1945 | 2 | 0 | 0.6886738 | 0.6886738_0.0021379679_0.095860876_0.21332738 |
15456 | 3 | 3 | 0.9842621 | 0.013699691_0.000912238_0.0011260039_0.9842621 |
2.2demo
先将模型预测的结果保存到excel中,然后读取预测结果,进行auc计算:
# -*- encoding:utf-8 -*-
import requests, xlrd, re, xlwt, json
from data_clean import clean_line
from sklearn import metrics
def calculate_auc_multi(read_path):
workbook = xlrd.open_workbook(read_path) # 打开工作簿
sheets = workbook.sheet_names() # 获取工作簿中的所有表格
worksheet = workbook.sheet_by_name(sheets[0]) # 获取工作簿中所有表格中的的第一个表格
label = [] # 真实标签
preds = [] # 模型的打分结果中类别1的概率,是一个n行 ,4列的数组
for i in range(0, 100):
value = worksheet.cell_value(i, 1)
label.append(int(value))
a = worksheet.cell_value(i, 4)
a = a.split('_')
g = []
for j in a:
g.append(float(j))
preds.append(g)
roc = metrics.roc_auc_score(label, preds, multi_class='ovr')
print('--roc-ovr:', roc)
roc = metrics.roc_auc_score(label, preds, multi_class='ovo')
print('--roc-ovo', roc)
if __name__ == '__main__':
read_path = './new_mul.xlsx'
calculate_auc_multi(read_path)
输出:
--roc-ovr: 0.8210669063789675
--roc-ovo 0.815065531618266
分析:
“multi_class”:ovr对类别不平衡比较敏感,ovo对类别不平衡不敏感。到底用哪个?我的理解是ovo更好一点,使得类别的不平衡能反映到auc中,影响评价指标,比较真实。
tips:
关键代码只有2行,陪衬代码写了30+行,无语凝噎^.^,昨天看这个函数使用时,一直没有特别明白,今天再看,如有神助,分分钟理解其意义,对“书读百遍其义自见”投上认真的一票。
参考:
1.官方文档:https://scikit-learn.org/stable/modules/generated/sklearn.metrics.roc_auc_score.html?highlight=roc_auc_score