美文网首页
ROC AUC 代价曲线

ROC AUC 代价曲线

作者: Tsukinousag | 来源:发表于2021-02-02 17:14 被阅读0次
    • 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]<theta:
                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]<theta:
                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 实验结果

    相关文章

      网友评论

          本文标题:ROC AUC 代价曲线

          本文链接:https://www.haomeiwen.com/subject/eraltltx.html