ROC AUC 代价曲线
Tsukinousag
1.049
·
字数 933 · 阅读 44
2021-02-02 17:14
1.ROC(Receiver Operation Characteristic)
我们根据学习器的预测结果对样例进行排序,按此顺序逐个把样本作为正例进行预测,每次计算出两个重要量的值,与P—R曲线的使用查准率与查全率为纵,横轴不同,ROC曲线的纵轴是“真正例率(TPR,True Positive Rate)”,横轴是“假正例率(False Positive Rate)”.
2.AUC(Area Under ROC Curve)与rank—loss
进行学习器比较时,与P—R图相似,若一个学习器的ROC曲线被另一个学习器的曲线完全“包住”,则可以断言后者的性能优于前者;若两个学习器的ROC曲线发生交叉,则难以一般性地断言两者孰优孰劣,此时如果一定要进行比较,则较为合理的判断依据是比较ROC曲线下的面积,即AUC.
形象化地看,AUC考虑的是样本预测的排序质量,因此它与排序误差有紧密联系
若正例的预测值小于反例,则记1个罚分,若相等则记0.5个罚分(可以理解成线代里面的逆序对数量),那么rank—loss对应的是ROC曲线之上的面积
3.cost curve(代价曲线)
明确参数 : p=m+/m
目的:对于一个模型,根据p不同,找到使得代价总期望最小的模型的阈值
横轴:归一化的正概率代价期望
纵轴:归一化的总代价期望
大致过程:给定p,给定模型根据归一化代价期望的最小值
确定混淆矩阵的成分比例,阈值决定了这个比例,那如果这个比例确定了,阈值也就确定了,所以这时模型的阈值也对应确定下来了,也就是模型固定下来了
同时模型的综合考量指标P,R,F1,Fbeta等都确定下来了
4 .实例
4.1一个阈值对应一条直线
4.1.1 引入模型:
下面我们用实例来说明一个阈值对应一条直线,我们的例子是一个二分类问题,它是五还是不是五,样本是如图所示的十二张图片进入该分类器后,给其打分
评判标准:得分越高的越是五,得分越低的越不是五
4.1.2 代码试验:
import pandas as pd
import matplotlib as pml
import matplotlib.pyplot as plt
#函数输出打分,从左到右分数依次增高
#1 2 3 4 5 6 7 8 9 10 11
output_score=list(range(12))
#正确分类,是五还是不是五
y=[0,0,0,0,1,0,1,1,0,1,1,1]
#p为样例是正例的概率(实际情况的正例率),取值范围[0,1],集合中正例的比例(m+/m),此时刚好为顺序排列
p=list(range(0,100,10))
p=[i/100 for i in p]
#[0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]
#设定代价
c01=3
c02=2
#一个阈值
theta=6.5
#根据阈值和打分情况判断是5还是不是5,0代表是5,1代表是5
def calculate_output_result(output_score,theta):
output_result=[]
for i in range(len(output_score)):
if output_score[i] output_result.append(0)#小于theta记为0 else: output_result.append(1)#大于theta记为1 return output_result #output_result为我们自己的判断 output_result=calculate_output_result(output_score,theta) #统计y中的正例(m+),反例(m-)个数 def calculate_m_positive_negtive(y): #value_counts确认数据出现的频率。 result = pd.value_counts(y) m_positive=result[0] m_negative=result[1] return m_positive,m_negative m_positive,m_negative=calculate_m_positive_negtive(y) #m_positive=6,m_negative=6 #output_result为[0,0,0,0,0,0,0,1,1,1,1,1]为预测分类 #y为[0,0,0,0,1,0,1,1,0,1,1,1]为正确分类 #然后根据我们预测的值去计算混淆矩阵 def calculate_confusion(y,output_result): TP=0 FN=0 FP=0 TN=0 for i in range(len(y)): if y[i]==1: if y[i]==output_result[i]: TP+=1 else: FN+=1 else: if y[i]==output_result[i]: TN+=1 else: FP+=1 return TP,FN,FP,TN TP,FN,FP,TN=calculate_confusion(y,output_result) #计算得TP,FN,FP,TN分别为4 2 1 5 #求几个比例,保留四位小数 def calculate_FNR_FPR(TP,FN,FP,TN): FNR=round(FN/(FN+TP),4) FPR=round(FP/(FP+TN),4) return FNR,FPR FNR,FPR=calculate_FNR_FPR(TP,FN,FP,TN) #FNR为0.333 FTR为0.1667 #计算 正概率代价(横轴) def calculate_Pcost(p,c01,c02): Pcosts=[] for i in range(len(p)): Pcost=round(p[i]*c01/(p[i]*c01+(1-p[i])*c02),4) Pcosts.append(Pcost) return Pcosts Pcosts=calculate_Pcost(p,c01,c02) #Pcosts为:[0.0, 0.1429, 0.2727, 0.3913, 0.5, 0.6, 0.6923, 0.7778, 0.8571, 0.931] #计算 归一化总概率(纵轴) def calculate_cost_norm(p,c01,c02,FNR,FPR): costs_norm=[] for i in range(len(p)): cost_norm=round((FNR*p[i]*c01+FPR*(1-p[i])*c02)/(p[i]*c01+(1-p[i])*c02),4) costs_norm.append(cost_norm) return costs_norm costs_norm=calculate_cost_norm(p,c01,c02,FNR,FPR) #costs_norm为:[0.1667, 0.1905, 0.2121, 0.2319, 0.25, 0.2667, 0.282, 0.2963, 0.3095, 0.3218] #画出图像,对比两种不同的横轴下的图像 def plot_lines(X,Y,color): plt.plot(X,Y,color) return plot_lines(Pcosts,costs_norm,'r') plot_lines(p,costs_norm,"b:") plt.show() 4.1.3 实验结果: 4.1.4 反思: 1.如果我们使用Pcosts作为横轴,得出的是红色直线,而以p作为横轴,得出的是紫色弯曲虚线,不是一个线性关系,虽然我们想要的就是已知某一个p,我们到底应该对应哪一条曲线的θ值更好,但是不能拿p当横轴,因为其返回曲线是非线性的,不利于我们分析。 2.当p等于0时Pcosts等于0,cost_norm=FPR;当p等于1时Pcosts等于1,cost_norm=FNR 3.p的含义:连接两点的线段如何用参数方程表示?假设两点分别是A,B,如果想表示AB连线所有点的集合用λA+(1-λ)B,λ∈[0,1],通过λ的变化,我们可以得到线段AB。、 4.2 多条直线围成代价敏感曲线 生成多个阈值下的曲线 4.2.1代码实验 import pandas as pd import matplotlib as pml import matplotlib.pyplot as plt #函数输出打分,从左到右分数依次增高 #1 2 3 4 5 6 7 8 9 10 11 output_score=list(range(12)) #正确分类,是五还是不是五 y=[0,0,0,0,1,0,1,1,0,1,1,1] #p为样例是正例的概率(实际情况的正例率),取值范围[0,1],集合中正例的比例(m+/m),此时刚好为顺序排列 p=list(range(0,100,10)) p=[i/100 for i in p] #[0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0] #设定代价 c01=3 c02=2 #根据阈值和打分情况判断是5还是不是5,0代表是5,1代表是5 def calculate_output_result(output_score,theta): output_result=[] for i in range(len(output_score)): if output_score[i] output_result.append(0)#小于theta记为0 else: output_result.append(1)#大于theta记为1 return output_result #统计y中的正例(m+),反例(m-)个数 def calculate_m_positive_negtive(y): #value_counts确认数据出现的频率。 result = pd.value_counts(y) m_positive=result[0] m_negative=result[1] return m_positive,m_negative def calculate_confusion(y,output_result): TP=0 FN=0 FP=0 TN=0 for i in range(len(y)): if y[i]==1: if y[i]==output_result[i]: TP+=1 else: FN+=1 else: if y[i]==output_result[i]: TN+=1 else: FP+=1 return TP,FN,FP,TN #求几个比例,保留四位小数 def calculate_FNR_FPR(TP,FN,FP,TN): FNR=round(FN/(FN+TP),4) FPR=round(FP/(FP+TN),4) return FNR,FPR #计算 正概率代价(横轴) def calculate_Pcost(p,c01,c02): Pcosts=[] for i in range(len(p)): Pcost=round(p[i]*c01/(p[i]*c01+(1-p[i])*c02),4) Pcosts.append(Pcost) return Pcosts #计算 归一化总概率(纵轴) def calculate_cost_norm(p,c01,c02,FNR,FPR): costs_norm=[] for i in range(len(p)): cost_norm=round((FNR*p[i]*c01+FPR*(1-p[i])*c02)/(p[i]*c01+(1-p[i])*c02),4) costs_norm.append(cost_norm) return costs_norm ###################################################### #生成多个θ的时候 thetas=list(range(12)) thetas=[i+0.5 for i in thetas] #生成12个θ:[0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5] #计算每个θ对应的点的函数,并存在列表里 def calculate_Pcost_cost_norm(thetas,output_score,y,calculate_Pcost,calculate_cost_norm): Pcosts_n=[] costs_norm_n=[] theta_FPR_FNR={} for i in range(len(thetas)): theta=thetas[i] #计算输出结果 output_result=calculate_output_result(output_score,theta) #统计正反例个数 m_positive,m_negative=calculate_m_positive_negtive(y) #计算混淆矩阵 TP,FN,FP,TN=calculate_confusion(y,output_result) #计算FNR,FPR FNR,FPR=calculate_FNR_FPR(TP,FN,FP,TN) theta_FPR_FNR[theta]=[FNR,FPR] #正概率代价 Pcosts=calculate_Pcost(p,c01,c02) Pcosts_n.append(Pcosts) #归一化总概率 costs_norm=calculate_cost_norm(p,c01,c02,FNR,FPR) costs_norm_n.append(costs_norm) return Pcosts_n,costs_norm_n,theta_FPR_FNR #调用函数计算每个θ对应的点 Pcosts_n,costs_norm_n,theta_FNR_FPR=calculate_Pcost_cost_norm(thetas,output_score,y,calculate_Pcost,calculate_cost_norm) #画图 def plot_lines(X,Y,color): plt.plot(X,Y,color) return for i in range(len(Pcosts_n)): plot_lines(Pcosts_n[i],costs_norm_n[i],'r') plt.show() 4.2.2 实验结果 机器学习 2 谢谢老板 赞赏支持 相关推荐 GSEA背后的统计学原理 阅读 284 PCA分析中的PC1指代什么 阅读 170 理解DESeq2的标准化步骤 阅读 755 【转录组07】样本表达分布、相关性分析&差异表达分析 阅读 722 相关性分析 | R语言 -- 相关性矩阵及可视化 阅读 654