接收机工作特性曲线揭秘(Python语言)

接收机工作特性曲线揭秘(Python语言)

在数据科学中,评价模型性能是非常重要的,最常用的性能指标是分类分数。然而,当处理严重的类不平衡的欺诈数据集时,分类分数没有多大意义。相反,接收机工作特性或ROC曲线提供了更好的选择。ROC是针对噪声(假阳性率)的信号图(真阳性率)。模型性能是通过观察ROC曲线下的面积来决定的。最好的AUC是1,最差的是0.5(45度随机线)。任何小于0.5的值都意味着我们可以做与模型建议相反的事情,使值回到0.5以上。

虽然ROC曲线很常见,但是并没有那么多的教学资源来解释它是如何计算和推导出来的。在这篇文章中,我将逐步揭示如何使用Python绘制ROC曲线。然后,我将解释一个基本ROC曲线的特征。

类的概率分布

首先,让我们假设我们的假设模型产生了一些概率来预测每个记录的类别。和大多数二元欺诈模型一样,我们假设我们的类是“good”和“bad”,模型产生P(X=“bad”)的概率。为了创建这个概率分布,我们绘制了一个高斯分布,每个类的均值不同。Python实现如下:

import numpy as np

import matplotlib.pyplot as plt

def pdf(x, std, mean):

cons = 1.0 / np.sqrt(2*np.pi*(std**2))

pdf_normal_dist = const*np.exp(-(x-mean)**2)/2.0*(std**2))

return pdf_normal_dist

x = np.linspace(0, 1, num=100)

good_pdf = pdf(x,0.1,0.4)

bad_pdf = pdf(x,0.1,0.6)

现在我们有了分布,让我们创建一个Python函数来绘制分布

def plot_pdf(good_pdf, bad_pdf, ax):

ax.fill(x, good, "g", alpha=0.5)

ax.fill(x, bad,"r", alpha=0.5)

ax.set_xlim([0,1])

ax.set_ylim([0,5])

ax.set_title("Probability Distribution", fontsize=14)

ax.set_ylabel('Counts', fontsize=12)

ax.set_xlabel('P(X="bad")', fontsize=12)

ax.legend(["good","bad"])

现在让我们使用这个plot_pdf函数来生成图:

fig,ax = plt.subplots(1,1,figsize =(10,5))

plot_pdf(good,bad,ax)

接收机工作特性曲线揭秘(Python语言)

现在我们有二元类的概率分布,现在我们可以使用这个分布来推导ROC曲线。

推导ROC曲线

为了从概率分布中得到ROC曲线,我们需要计算真阳性率(TPR)和假阳性率(FPR)。对于一个简单的例子,我们假设阈值为P(X= ' bad ')=0.6。

接收机工作特性曲线揭秘(Python语言)

真正的阳性是在阈值的右边指定为“bad”的区域。假阳性表示在阈值右侧被指定为“good”的区域。Total positive是“bad”曲线下的总面积,Total negative是“good”曲线下的总面积。我们将图中所示的值进行划分,得到TPR和FPR。推导了不同阈值的TPR和FPR,得到了ROC曲线。利用这些知识,我们创建了ROC plot函数:

def plot_roc(good_pdf, bad_pdf, ax):

#Total

total_bad = np.sum(bad_pdf)

total_good = np.sum(good_pdf)

#Cumulative sum

cum_TP = 0

cum_FP = 0

#TPR and FPR list initialization

TPR_list=[]

FPR_list=[]

#Iteratre through all values of x

for i in range(len(x)):

#We are only interested in non-zero values of bad

if bad_pdf[i]>0:

cum_TP+=bad_pdf[len(x)-1-i]

cum_FP+=good_pdf[len(x)-1-i]

FPR=cum_FP/total_good

TPR=cum_TP/total_bad

TPR_list.append(TPR)

FPR_list.append(FPR)

#Calculating AUC, taking the 100 timesteps into account

auc=np.sum(TPR_list)/100

#Plotting final ROC curve

ax.plot(FPR_list, TPR_list)

ax.plot(x,x, "--")

ax.set_xlim([0,1])

ax.set_ylim([0,1])

ax.set_title("ROC Curve", fontsize=14)

ax.set_ylabel('TPR', fontsize=12)

ax.set_xlabel('FPR', fontsize=12)

ax.grid()

ax.legend(["AUC=%.3f"%auc])

现在让我们使用这个plot_roc函数来生成图

fig, ax = plt.subplots(1,1, figsize=(10,5))

plot_roc(good_pdf, bad_pdf, ax)

接收机工作特性曲线揭秘(Python语言)

现在将概率分布和ROC绘制在彼此旁边以进行视觉比较:

fig,ax = plt.subplots(1,2,figsize =(10,5))

plot_pdf(good_pdf,bad_pdf,ax [0])

plot_roc(good_pdf,bad_pdf,ax [1])

plt.tight_layout()

接收机工作特性曲线揭秘(Python语言)

分类的影响

现在我们可以得出两个图,让我们看看随着类分离(即模型性能)的改善,ROC曲线如何变化。我们通过改变概率分布中高斯的平均值来做到这一点。

x = np.linspace(0, 1, num=100)

fig, ax = plt.subplots(3,2, figsize=(10,12))

means_tuples = [(0.5,0.5),(0.4,0.6),(0.3,0.7)]

i=0

for good_mean, bad_mean in means_tuples:

good_pdf = pdf(x,0.1,good_mean)

bad_pdf = pdf(x,0.1,bad_mean)

plot_pdf(good_pdf, bad_pdf, ax[i,0])

plot_roc(good_pdf, bad_pdf, ax[i,1])

i+=1

plt.tight_layout()

接收机工作特性曲线揭秘(Python语言)

正如你所看到的,随着我们增加类之间的分离,AUC增加。

展望超越AUC

除AUC之外,ROC曲线还可以帮助调试模型。通过观察ROC曲线的形状,我们可以评估模型是错误分类的。例如,如果曲线的左下角更接近随机线,则意味着该模型在X = 0时被错误分类。而如果它是右上角的随机数,则意味着错误发生在X = 1处。另外,如果曲线上存在尖峰(而不是平滑),则意味着模型不稳定。

相关推荐