目录
本文部分图片与代码来自《老饼讲解-机器学习》
一、什么是AUC
1.1 AUC用来做什么
AUC(Area Under Curve)即曲线下面积,主要用于二分类模型的评价。它是从所有正样本中随机选取一个样本,再从所有负样本中随机选取一个样本,然后根据你的学习器对这两个随机样本预测得到的正样本概率大于负样本概率的概率,就是 AUC 值。AUC值越大的分类器,正确率越高。
具体来说,AUC的作用有:
- AUC值是一个概率值,当你随机挑选一个正样本以及一个负样本,当前的分类算法根据计算得到的Score值将这个正样本排在负样本前面的概率就是AUC值。AUC值越大,当前的分类算法越有可能将正样本排在负样本前面,即能够更好的分类。
- AUC常常用来作为模型排序好坏的指标,原因在于AUC可以看做随机从正负样本中选取一对正负样本,其中正样本的得分大于负样本的得分的概率。
- AUC=1,是完美分类器,采用这个预测模型时,不管设定什么阈值都能得出完美预测。绝大多数预测的场合,不存在完美分类器。
- 0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。
需要注意的是,AUC作为数值可以直观的评价分类器的好坏,值越大越好。
1.2 在python的sklearn中如何计算AUC
使用python的sklearn计算AUC可以通过如下方式,
# -----调用sklearn包计算AUC--------
from sklearn import metrics
import numpy as np
import pandas as pd
#=====================标签与score数据=============================
lable = np.array([0, 1 ,0,1 ,1,1 ,0 ,1,0,1,0,0,0,0,1,0])
score = np.array([0.2, 0.28,0.1 ,0.6,0.5, 0.3, 0.6, 0.8,0.2,0.25,0.4,0.2,0.5,0.3,0.18,0.18])
#=====================标签与score数据=============================
fpr, tpr, thresholds = metrics.roc_curve(lable,score,drop_intermediate=False)
auc = metrics.auc(fpr, tpr)
print('thresholds:'+str(thresholds))
print('FPR:'+str(fpr))
print('TPR:'+str(tpr))
print('AUC:'+str(auc))
那么,sklearn内部是如何计算出AUC的呢,下节我们不妨进行探讨
二、sklearn内部是怎么实现AUC的
下面,我们先通过手动计算过程,了解sklearn内部的计算AUC的流程。然后用代码实现,复现与sklearn一模一样的结果。
1.1AUC的手动计算过程
为了如下:
2.2复现slearn计算AUC的过程
根据上述的计算过程,使用代码实现如下:
# -*- coding: utf-8 -*-
"""
AUC计算与ROC曲线绘画
"""
import numpy as np
import pandas as pd
#=====================标签与score数据=============================
lable = np.array([0, 1 ,0,1 ,1,1 ,0 ,1,0,1,0,0,0,0,1,0])
score = np.array([0.2, 0.28,0.1 ,0.6,0.5, 0.3, 0.6, 0.8,0.2,0.25,0.4,0.2,0.5,0.3,0.18,0.18])
#===================计算FPR和TPR==========================================
df = pd.DataFrame({'score':score,'label':lable}) # 生成【分值,标签】的DataFrame
df = df.sort_values('score',ascending=False).reset_index(drop=True) # 对分值进行排序
df['last_score'] = df['score'].diff(-1)!=0 # 标记是否是同一个socre值的最后一条数据
df['csum0'] = (df['label']==0).cumsum() # 0类样本的累计条数
df['csum1'] = (df['label']==1).cumsum() # 1类样本的累计条数
df['fpr'] = df['csum0']/(df['label']==0).sum() # 计算fpr:0类样本的累计占比
df['tpr'] = df['csum1']/(df['label']==1).sum() # 计算tpr:1类样本的累计占比
df = df[df['last_score']==True]
start_row = pd.DataFrame( {'score':score.max()+1,'fpr':0,'tpr':0},pd.Index(range(1))) # 起始行[0,0]
df = pd.concat([start_row,df[['score','fpr','tpr']]]).reset_index(drop=True) # 添加起始行到df
#=============绘画ROC曲线===================================
import matplotlib.pyplot as plt
plt.plot(df['fpr'],df['tpr'], marker='o', markerfacecolor='r', markersize=5) # 绘制ROC曲线
plt.fill_between(df['fpr'],0, df['tpr'], facecolor='green', alpha=0.3) # 给ROC区域添加颜色
plt.xlim(0,1);plt.ylim(0,1); # 限制x,y轴的范围
plt.title('ROC');plt.xlabel('fpr');plt.ylabel('tpr') # 加标题
#===============计算AUC======================================
df['area'] = 0 # 初始化面积为0
for i in range(1,df.shape[0]):
df.loc[i,'area'] = (df['tpr'][i]+df['tpr'][i-1])*(df['fpr'][i]-df['fpr'][i-1])/2 # 添加每小段的面积
auc = df['area'].sum()
#=======打印结果=======================================
print('=====FPR和TPR====================')
print(df)
print('=====AUC====================')
print('AUC:'+str(auc))
运行后结果显示如下:
写文不易,点赞收藏吧~!