python 绘制ROC曲线

简述

  机器学习很多是为测试样本产生一个预测值,然后将这个预测值与阈值进行对比,若大于阈值则分为正类,否则分为反类。这个预测值的好坏,直接决定了学习器泛化能力。根据这个预测值,我们可以对测试样本进行排序,“最可能”是正例的排在最前面,“最不可能”是正例的排在最后面。这样,分类过程就相当于在这个排序中以某个截断点将样本分为两部分,前面一部分作为正例,后面一部分作为反例。
  如果我们更加重视“查准率”,则可以选择排序中靠前的位置进行阶段(尽可能的准确预测正例);若更加重视“查全率”,则可以选择排序中靠后的位置进行截断(尽可能多的包含正例)。因此排序的好坏,直接体现了综合考虑学习器在不同任务下的“期望泛化性能”的好坏。ROC曲线就是从这个角度出发来研究学习器泛化性能的。

真正例率和假正例率

这里写图片描述

  • 真正例率:前半部分预测为正的样例占实际为正的样例的比例

TPR=TPTP+FN T P R = T P T P + F N

  • 假正例率:后半部分预测为正的样例占实际为反的样例的比例
    FPR=FPTN+FP F P R = F P T N + F P
数据集:
x1  0.9894352   1
x2  0.9794352   1
x3  0.977945262 1
x4  0.960783037 1
x5  0.944241384 1
x6  0.93664411  1
x7  0.924929575 1
x8  0.920406882 0
x9  0.888570298 1
x10 0.882629706 1
x11 0.882401646 1
x12 0.853832401 1
x13 0.839347591 1
x14 0.836771262 1
x15 0.833144033 1
x16 0.828867488 1
x17 0.815303556 0
x18 0.805622582 1
x19 0.802897991 1
x20 0.789226942 0
x21 0.758042059 1
x22 0.716307689 1
x23 0.69443123  1
x24 0.693818886 1
x25 0.684523938 1
x26 0.672463705 1
x27 0.629302653 0
x28 0.58780351  1
x29 0.548529475 1
x30 0.488394372 0
x31 0.483994649 0
x32 0.43695701  1
x33 0.408835528 1
x34 0.393323919 0
x35 0.374834691 1
x36 0.349519471 0
x37 0.29704696  0
x38 0.273542305 0
x39 0.205748558 0
x40 0.187974058 1
x41 0.179264057 0
x42 0.164596829 0
x43 0.142258075 0
x44 0.138514809 0
x45 0.128892511 0
x46 0.126119067 0
x47 0.113361272 0
x48 0.083327915 0
x49 0.071568497 0
x50 0.031525573 0

测试样本包含三列,第一列样本序号,第二列为预测值,第三列为真实标记值。

#-*- coding: utf-8 -*-
import matplotlib.pyplot as plt

def get_data(path):
    f = open(path)
    data_list  = f.readlines()
    return data_list

def get_truth_value():
    threshold_list = []
    truth_value = []
    data_list  = get_data('test.txt')
    for item in data_list:
        truth_value.append(
            item.strip().split('\t')[2])

    return truth_value

def plot_curve(x,y):
    plt.scatter(x,y)
    plt.xlabel(u"假正例率",fontproperties='SimHei')
    plt.ylabel(u"真正例率",fontproperties='SimHei')
    plt.show()

def get_tpr_fpr():
    truth_value = get_truth_value()
    tpr = []
    fpr = []
    for i  in range(1,len(truth_value)):
        forecast = []
        forecast.extend([1]*(i))
        forecast.extend([0]*(len(truth_value) - i))
        tmp_list = [forecast[j]*int(truth_value[j]) for j in range(len(forecast))]
        tp = sum(tmp_list[0:i])
        fp = i - tp
        fn = sum([int(x) for x in truth_value[i:len(truth_value)]])
        tn = len(truth_value)-i - fn
        print(tp,fp,fn,tn)
        tpr.append(tp*1.0/(tp+fn))
        fpr.append(fp*1.0/(tn+fp))

    return tpr,fpr  

if __name__ == "__main__":
    x,y = get_tpr_fpr()
    plot_curve(y,x)
绘图

这里绘图方法是将测试样本的每一个值作为阈值,然后分别计算出真正例率和假正例率,如图所示:
这里写图片描述

对于同一个测试样本,不同的学习器产生的预测值不同,绘制的ROC曲线也不同,当一个曲线将另一个曲线完全包住时,包住的曲线对应的学习器的泛化能力是强于另外一个的,当两条曲线有交点时,需要计算ROC曲线围住的面积:

AUC=12i=1m1(xi+1xi)(yi+yi+1) A U C = 1 2 ∑ i = 1 m − 1 ( x i + 1 − x i ) ∗ ( y i + y i + 1 )

提示:这里讲面积划分为许多梯形的面积,然后求和,梯形面积公式:

S=12(+) S = 1 2 ( 上 底 + 下 底 ) ∗ 高

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值