在线广告预估ctr的AUC计算方法_广告auc-程序员宅基地

技术标签: 机器学习  

一、auc选特征的原理

在优化模型的时候,我们期望能够加入足够多有典型区分度的特征。特征有良好的区分度,有助于在筛选广告阶段进行准确的排序。准确的排序意味着,在排序好的候选广告中,可以选择top1,或者top2等这样高预估ctr的广告进行展现。也就是说,加入的特征能够触发高ctr高的广告排在前面。

二、ctr的auc计算方法

(1)定义法:

     根据discrimination threshold阈值,每次在一个pCTR上进行划分,取划分这个pCTR为阈值,高于这个阈值的是预估的正样本,低于这个阈值,是预估的负样本。在这种情况下,计算当前这个划分的tprfpr。得到一个点对(fpr, tpr)。每个划分都会得到一个点对,那么就可以绘制出ROC,进而计算出AUC。

     tpr = tp/p = 预测是正样本实际也是正样本的个数(把正样本预测为正样本的个数)/正样本的个数

     fpr = fp/N = 预测是正样本实际是负样本的个数(把负样本预测为正样本的个数)/负样本的个数

给定一组样本如下,其中正样本4个,负样本4个:

 

样本真实值 pctr
1 0.9
1 0.8
0 0.7
1 0.5
0 0.4
1 0.3
0 0.2
0 0.1

在本例中,tp即为预测为正样本中,1的个数,fp即为预测为正样本中,0的个数

根据阈值0.9进行划分,大于等于0.9预测为正样本,小于0.9预测为负样本,tpr=1/4=0.25,fpr=0/4=0;

根据阈值0.8进行划分,大于等于0.8预测为正样本,小于0.8预测为负样本,tpr=2/4=0.5,fpr=0/4=0;

根据阈值0.7进行划分,大于等于0.7预测为正样本,小于0.7预测为负样本,tpr=2/4=0.5,fpr=1/4=0.25;

根据阈值0.5进行划分,大于等于0.5预测为正样本,小于0.5预测为负样本,tpr=3/4=0.75,fpr=1/4=0.25;

根据阈值0.4进行划分,大于等于0.4预测为正样本,小于0.4预测为负样本,tpr=3/4=0.75,fpr=2/4=0.5;

根据阈值0.3进行划分,大于等于0.3预测为正样本,小于0.3预测为负样本,tpr=4/4=1,fpr=1/4=0.25;

根据阈值0.2进行划分,大于等于0.2预测为正样本,小于0.2预测为负样本,tpr=4/4=1,fpr=3/4=0.75;

根据阈值0.1进行划分,大于等于0.1预测为正样本,小于0.1预测为负样本,tpr=4/4=1,fpr=4/4=1;

(2)Wilcoxon-Mann-Witney Test惠特尼检验的方法;

   Wilcoxon-Mann-Witney Test就是测试任意给一个正类样本和一个负类样本,正类样本的score有多大的概率大于负类样本的score.首先对score从大到小排序,然后令最大score对应的sample 的rank为n,第二大score对应sample的rank为n-1,以此类推。然后把所有的正类样本的rank相加,再减去正类样本的score为最 小的那M个值的情况。得到的就是所有的样本中有多少对正类样本的score大于负类样本的score。然后再除以M×N

还以上面的例子来计算,(M为正样本的个数,N为负样本的个数):

 

样本真实值 pctr rank
1 0.9 8
1 0.8 7
0 0.7 6
1 0.5 5
0 0.4 4
1 0.3 3
0 0.2 2
0 0.1 1

 

auc = (正样本的各个rank的和 - M*(M+1)/2)/M*N=[(8+7+5+3)-4*5/2]/4*4=13/16

也即总共有13的(正,负)的点对,正样本的ctr高于负样本的ctr

rank之和: 8 +7 + 5 + 3

                 4    3    2    1

实际:       4 + 4 + 3 + 2

实验方法:

1、从AUC统计意义去计算。所有的正负样本对中,正样本排在负样本前面占样本对数的比例,即这个概率值。 
具体的做法就是它也是首先对prob score从大到小排序,然后令最大prob score对应的sample 的rank为n,第二大score对应sample的rank为n-1,以此类推。然后把所有的正类样本的rank相加,再减去M-1种两个正样本组合的情况。得到的就是所有的样本中有多少对正类样本的score大于负类样本的score。最后再除以M×N。公式如下

def calAUC(prob,labels):
    f = list(zip(prob,labels))
    rank = [values2 for values1,values2 in sorted(f,key=lambda x:x[0])]
    rankList = [i+1 for i in range(len(rank)) if rank[i]==1]
    posNum = 0
    negNum = 0
    for i in range(len(labels)):
        if(labels[i]==1):
            posNum+=1
        else:
            negNum+=1
    auc = 0
    auc = (sum(rankList)- (posNum*(posNum+1))/2)/(posNum*negNum)
    print(auc)
    return auc

其中:其中输入prob是得到的概率值[0.5,0.6,04,0.3,0.1],labels是分类的标签[1,0,1,0,1]

2、通过计算梯形的面积

注意:(1)首先按ctr从大到小排序;(2)对于正样本来说,每个ctr的正样本,需要对前面的进行累加

得出当前的正样本,因为每次ctr划分。比如:>ctr1的为正样本,小于ctr1为负样本,前面的ctr都比ctr1大,

因此需要把前面的正样本累加到本次当中,负样本no_click不用累加。(3)横坐标为FPR=no_click/no_click_sum,

纵坐标为TPR = click_num/click_num_sum。

def scoreClickAUC(predicted_ctr):
    """
     利用梯形面积计算auc
     @predictd_ctr: {score:[show,click]}
    """
    i_sorted = sorted(predicted_ctr.iteritems(),key=lambda x:x[0],reverse=True)
    auc_temp = 0.0
    click_sum = 0.0 
    old_click_sum = 0.0 
    no_click = 0.0 
    no_click_sum = 0.0 
    for (pscore, [show, click]) in i_sorted:
        no_click = show - click
        #每次ctr的划分,需要对前面的正样本进行累加,前面的正样本对当前ctr来说也是
        #正样本
        click_sum += click
        auc_temp += (click_sum + old_click_sum) * no_click / 2.0 
        old_click_sum = click_sum
        #累加负样本
        no_click_sum += show - click
    auc = auc_temp / (click_sum * no_click_sum)
    return auc 

 

# coding=utf-8

import sys

import math

import time

import datetime

import numpy as np

class get_single_feature_auc(object):

    def __init__(self):

        self.thresh_hold_nums = 5 #最大序列长度

    def process(self,data_str,thresh_hold_nums):

        """

           返回每个区块周边的区块特征拼接

        """

        #feature_size = 0

        #if data_str is None: return

        score_dict = {}

        for elem in data_str.split(';'):

            p = elem.split(',')           

            if len(p) != 2:continue

            score_dict.setdefault(float(p[0]),[])

            score_dict[float(p[0])].append(int(p[1]))

        feature_distribute = {}

        score_list = sorted(score_dict.iteritems(), key=lambda x:x[0],reverse = False)

        #将实值列表,分到thresh_hold_nums个桶里

        seed = len(score_list) / thresh_hold_nums

        for i in range(len(score_list)):

            bucket_num = i / seed 

            click_ = len([e for e in score_list[i][1] if e == 1])

            no_click_ = len([e for e in score_list[i][1] if e == 0])

            feature_distribute.setdefault(bucket_num, [0,0])

            feature_distribute[bucket_num][0] += click_ + no_click_

            feature_distribute[bucket_num][1] += click_

        #基于每个桶,统计正负样本,并计算不同的阈值

        predicted_ctr = dict()

        for key in feature_distribute:

            show_,click_ = feature_distribute[key][:]

            pscore = click_ * 1.0/show_

            predicted_ctr.setdefault(pscore, [0,0])

            predicted_ctr[pscore][0] += show_

            predicted_ctr[pscore][1] += click_

        #计算梯形面积,累计出auc的值

        i_sorted = sorted(predicted_ctr.iteritems(), key=lambda x:x[0],reverse = True)

        auc_temp = 0.0

        click_sum = 0.0

        old_click_sum = 0.0

        no_click = 0.0

        no_click_sum = 0.0

        for (pscore, [show, click]) in i_sorted:

            no_click = show - click

            click_sum += click

            auc_temp += (click_sum + old_click_sum) * no_click /2.0

            old_click_sum = click_sum

            no_click_sum += show - click

        auc = auc_temp / (click_sum * no_click_sum)

        print auc

if __name__ == '__main__':

    op = get_single_feature_auc()

    op.process("0.3,1;0.45,0;0.56,1;0.3,0;0.21,1;0.33,0;0.43,1;0.78,0;0.65,1;0.98,0;0.75,0",5)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zcc_0015/article/details/77246407

智能推荐

linux静态编译curl和openssl_编译curl openssl-程序员宅基地

文章浏览阅读1.7k次。因为需要使用curl向服务器下发请求新版本curl在当前环境下测试有bug,旧版本ok,所以不得不静态编译curl。curl命令需要使用到ssl,为了避免openssl版本问题,所以这里就连同openssl一块编译了1.首先下载openssl源码编译:openssl下载链接./config -fPIC no-shared --prefix=/root/doris/openssl_install --openssldir=/root/doris/openssl_installmake2.下载_编译curl openssl

Ubuntu键鼠失灵_sudo apt-get install xserver-xorg 没有反应-程序员宅基地

文章浏览阅读408次。前情:一个来月去做别的没打开ubuntu, 打开之后它给了我小惊喜,直接键鼠失灵了。个人感觉是因为之前无脑跟书安装,也没仔细研究,安装了gym和mujuco。看了很多帖子,都说是xserver的问题,并且我也尝试了进GRUB并进行了以下帖子的流程:https://blog.csdn.net/formance/article/details/103264710?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineL_sudo apt-get install xserver-xorg 没有反应

Ubuntu 连接投影机-程序员宅基地

文章浏览阅读1.5k次。xrandr 显示所有支持的分辨率 xrandr -s 0 选择第一个分辨率 xrandr 命令行可以很方便地切换双屏,常用方式如下,其他的可以自己探索: xrandr --output VGA --same-as LVDS --auto 打开外接显示器(最高分辨率),与笔记本液晶屏幕显示同样内容(克隆) xrandr --output..._ubuntu 链接 极米

html+css+php+mysql 简单的页面登录与注册(数据库的交互)_html css注册登录-程序员宅基地

文章浏览阅读3.4k次,点赞18次,收藏92次。这是一个简单的小项目,但对于我这小白来说,也是写了好几天才完成,中间心态炸裂n次,但最后还是 搞定了!!!说了那麽多,还是分享一下吧!目录主页面(登录页面)登录页面的后台操作注册页面注册页面的后台操作实验环境是phpstudy2018。在phpstudy的www目录里,创建一个新文件夹test。文件里有:index.php 主页面(登陆页面)login.php 登录页面的后台操作register.html 注册页面register.php 注册页面的后台操作_html css注册登录

Java 遍历 HashMap_遍历hashmap java entry-程序员宅基地

文章浏览阅读47次。如何遍历 hashMapA?这里的知识点包括:HashMap.Entry<A, B> entryB 可以构建迭代器元素 entryB。HashMap.entrySet() 方法可以提供迭代遍历。entry.getKey(),entry.getValue() 方法可以获取键和值。for (HashMap.Entry<Integer, String> entryB : hashMapA.entrySet()) { if (entryB.getKey() == C &_遍历hashmap java entry

window 编程 -- Beep函数之祝你生日快乐!_祝你生日快乐beep函数输出-程序员宅基地

文章浏览阅读1.9k次。#include <Windows.h>int main(){ MessageBeep(MB_ICONHAND); MessageBeep(MB_ICONEXCLAMATION); MessageBeep(MB_ICONASTERISK); //system("pause"); while (1) {#if 1 Beep(523, 200); Beep(523, 200); Beep(578, 400); Beep(523, 400); Beep(698,._祝你生日快乐beep函数输出

随便推点

Java40万年薪所需技术_40万年薪java-程序员宅基地

文章浏览阅读125次。对于一个年薪 40W 的 Java 开发人员来说,需要掌握哪些知识点呢?经过我自己的总结,我列出了下面的思维导图:从上面的图片我们可以看出大致分为三个部分:JDK 源码、JVM 原理、框架源码。一、JDK源码JDK 源码是一切的基础,许多框架都参考了 JDK 源码的实现思路,因此弄懂 JDK 源码是一件非常重要的事情。而 JDK 源码又可以分为下面 5 大块:集合源码 并..._40万年薪java

Vue上传图片并预览(好)-程序员宅基地

文章浏览阅读1.1k次。Vue上传图片并预览(好)_vue上传图片并预览

WebStorm 之 Cordova 环境搭建_webstorm cordova 运行-程序员宅基地

文章浏览阅读554次。转发:https://www.cnblogs.com/xinaixia/p/6756779.html一、环境搭建  Cordova 环境配置之前,应先下载安装 Node.js ,中文官网:http://nodejs.cn/。  以管理员身份运行 cmd 命令行工具:  1、查看 Node.js 是否已安装成功,命令为:node -v  2、查看 npm 是否已安装,命令为:np..._webstorm cordova 运行

最新交易猫链接源码 带完整版教程_交易猫源码链接生成-程序员宅基地

文章浏览阅读957次。带一款非常简洁好看的后台。搭建教程:修改数据库账号密码直接使用。源码下载:下载地址网盘下载地址:https://pan.baidu.com/s/19iOsoyK-J-Rhi2dZYqzMMg?pwd=iumr提取码:iumr_交易猫源码链接生成

《论文笔记》CCM-SLAM: Robust and Efficient Centralized Collaborative Monocular SLAM for Robotic Teams_ccm_slam论文-程序员宅基地

文章浏览阅读1.1k次,点赞5次,收藏9次。《CCM-SLAM: Robust and Efficient Centralized Collaborative Monocular SLAM for Robotic Teams》作者:Patrik Schmuck,Margarita Chli单位:苏黎世联邦理工学院(ETH)期刊:Journal of Field Robotics(JFR)(二区)时间:2019摘要:机器人协作有望提高任务的鲁棒性和效率,在搜救和农业等领域具有巨大的应用潜力。多机器人协作同时定位和建图(SLAM)正是_ccm_slam论文

PCB(layout)常用快捷键_layout快捷键-程序员宅基地

文章浏览阅读1w次,点赞10次,收藏74次。快捷键的实用,极大的提高了大家工作中的效率,因此小编我特意帮大家搜集整理很多关于AD方面的常用快捷键,希望对大家有所帮助。一、PCB中常用快捷键R+L 输出PCB中所有网络的布线长度Ctrl+左键点击对正在布的线完成自动布线连接M+G 可更改铜的形状;按P+T在布线状态下,按Shift+A可直接进行蛇线走线T+R对已布完的线进行蛇线布线E++M+C点击空白出可迅速找到PCB上想要的元件Backsp..._layout快捷键