博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
点击率模型AUC
阅读量:6174 次
发布时间:2019-06-21

本文共 3756 字,大约阅读时间需要 12 分钟。

一 背景 

      首先举个例子:

                         正样本(90)                       负样本(10)        

模型1预测        正(90)                                正(10)

模型2预测        正(70)负(20)                正(5)负(5)

结论:

       模型1准确率90%;

       模型2 准确率75%      

       考虑对正负样本对预测能力,显然模型2要比模型1好,但对于这种正负样本分布不平衡对数据,准确率不能衡量分类器对好坏了,所以需要指标auc解决倾斜样本的评价问题。

二分类混淆矩阵

预测\实际       1            0

1                    TP          FP

0                    FN          TN

       TPR=TP/P=TP/TP+FN   直观1中猜对多少

       FPR=FP/N=FP/FP+TN  直观0中猜错多少

       Auc对横纵坐标分别为FPR和TPR,相对于y=x这条直线靠近左上角对分类器性能更好,所以模型2更优。

                            TPR                            FPR

模型1                 90/90=1                   10/10=1

模型2                 70/90=0.78                5/10=0.5

模型1和2的auc点位分别如下图所示,显然模型1更优:

 

 

二 研究现状 

       AUC直观概念,任意取一对正负样本,正样本score大于负样本对概率。 

       计算方法:正样本和负样本pair对,auc=预估正样本score大于负样本score的pair对数/总的pair对数。

       E.g. 分别计算模型1和2对auc?

四个样本label为y1=+1, y2=+1, y3=-1, y4=-1

模型1的预测为 y1=0.9, y2=0.5, y3=0.2, y4=0.6

模型2的预测为 y1=0.1, y2=0.9, y3=0.8, y4=0.2

解: 

        模型1: 正样本score大于负样本的pair包括(y1, y3), (y1, y4), (y2, y3),auc为3/4=0.75

        模型2: 正样本score大于负样本的pair包括(y2, y3),(y2, y4),auc为2/4=0.5

 

计算参考paper:《 An introduction to ROC analysis 》(Tom Fawcett)

方法:

1按照score对样本排序;

2依次对每个样本,label分对TP增1,否则FP增1。计算每个小梯形的面积。

3累加所有样本,计算auc

代码:

= sorted(range(len(probs)),key=lambda i: probs[i], reverse== = = = = = = = probs[i_sorted[]] +                                              i  last_prob !=+= (TP+TP_pre) * (FP-FP_pre) / === labels[i_sorted[i]] == = TP +         = FP + += (TP+TP_pre) * (FP-FP_pre) / = auc_temp / (TP *=== line = line.strip().split(= (line[= (line[ len(sys.argv) != = read_file(sys.argv[= % __name__==

 

 

三 点击率模型auc计算方法 

       如上图,以两个分桶为例,每个分桶计算的AUC为图中的阴影部分。全局AUC部分需要补充P3部分的面积,等于前i-1个桶的sum(click)乘以每i个桶的noclick。

       整体的AUC就是曲线下的面积除以曲线的起点、终点锚定矩型的面积。

步骤

1按照pctr聚合 sum_show和sum_clk;

2样本按照pctr排序;

3依次对每个样本,计算noclk和clk围成对小梯形对面积。

       代码:

import sys#init auc dictparams_auc_dict = {"last_ctr":1.1, "slot_show_sum":0, "slot_click_sum":0, \                     "auc_temp":0.0, "click_sum":0.0, "old_click_sum":0.0, "no_click":0.0, \                     "no_click_sum":0.0} #init q distributeq_bucket = 1000params_Q_dict = {"count_list":[0]*(q_bucket+1)}for line in sys.stdin:    lineL = line.strip().split('\t')    if len(lineL) < 3:        continue    pctr = float(lineL[0])    #print lineL[0]    #pctr = float(lineL[0])/1e6    show = int(float(lineL[1]))    click = int(float(lineL[2]))    slot_info = '-'        ### calculate auc    params_auc_dict["slot_show_sum"] += show    params_auc_dict["slot_click_sum"] += click    if params_auc_dict["last_ctr"] != pctr:        params_auc_dict["auc_temp"] += (params_auc_dict["click_sum"] + \                                         params_auc_dict["old_click_sum"]) * params_auc_dict["no_click"] / 2.0        params_auc_dict["old_click_sum"] = params_auc_dict["click_sum"]        params_auc_dict["no_click"] = 0.0        params_auc_dict["last_ctr"] = pctr    params_auc_dict["no_click"] += show - click    params_auc_dict["no_click_sum"] += show - click    params_auc_dict["click_sum"] += click           ### calculate Q distribution    index = int(pctr / (1.0/q_bucket)) #interval [0, 0.001) left close, right open    count_list = params_Q_dict["count_list"]    count_list[index] += show# last instance for aucparams_auc_dict["auc_temp"] += (params_auc_dict["click_sum"] + \         params_auc_dict["old_click_sum"]) * params_auc_dict["no_click"] / 2.0if params_auc_dict["auc_temp"] > 0:    auc = params_auc_dict["auc_temp"] / (params_auc_dict["click_sum"] * params_auc_dict["no_click_sum"])else:    auc = 0print "AUC:%s\tshow_sum:%s\tclk_sum:%s" %( auc, params_auc_dict["slot_show_sum"], params_auc_dict["slot_click_sum"])#print Q distribution resultfor item in params_Q_dict:    count_list = params_Q_dict["count_list"]    print "Max bucket num: %s" %(sum(count_list))    for i in range(q_bucket+1):        if i < (q_bucket - 1):            print str((i+1)*(1.0/q_bucket)) + '\t' + str(count_list[i])        else:            print '1.0\t' + str(count_list[i]+count_list[i+1])            break
本文转自 bxst 51CTO博客,原文链接:http://blog.51cto.com/13013670/1943966

转载地址:http://czhba.baihongyu.com/

你可能感兴趣的文章
如何配置 Log4J 只保留最近七天的日志文件
查看>>
Python 类与元类的深度挖掘 II
查看>>
prometheus收集springboot指标
查看>>
global gtags的配置
查看>>
iOS开发 — Quartz 2D知识点应用 (制作了一个Demo,源代码)
查看>>
Creating a Windows Image on OpenStack
查看>>
jquery图片自动缩放
查看>>
ie6 失真问题
查看>>
Regular Expression
查看>>
你到了第几层?图片式标题、按钮与隐藏文本
查看>>
大话重构连载14:我们是这样自动化测试的
查看>>
我的友情链接
查看>>
iis6 php安装 (一)
查看>>
关于,在Mysql中,外键是否会影响性能的问题???
查看>>
利用javascript设置图片等比例缩小
查看>>
dedeCMS如何给频道页添加缩略图
查看>>
CoreSeek快速安装
查看>>
Linux 网络性能调试工具Netstat
查看>>
我的友情链接
查看>>
报表下载SSH
查看>>