技术标签: 机器学习
一、auc选特征的原理
在优化模型的时候,我们期望能够加入足够多有典型区分度的特征。特征有良好的区分度,有助于在筛选广告阶段进行准确的排序。准确的排序意味着,在排序好的候选广告中,可以选择top1,或者top2等这样高预估ctr的广告进行展现。也就是说,加入的特征能够触发高ctr高的广告排在前面。
二、ctr的auc计算方法
(1)定义法:
根据discrimination threshold阈值,每次在一个pCTR
上进行划分,取划分这个pCTR
为阈值,高于这个阈值的是预估的正样本,低于这个阈值,是预估的负样本。在这种情况下,计算当前这个划分的tpr
和fpr
。得到一个点对(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)
文章浏览阅读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
文章浏览阅读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 没有反应
文章浏览阅读1.5k次。xrandr 显示所有支持的分辨率 xrandr -s 0 选择第一个分辨率 xrandr 命令行可以很方便地切换双屏,常用方式如下,其他的可以自己探索: xrandr --output VGA --same-as LVDS --auto 打开外接显示器(最高分辨率),与笔记本液晶屏幕显示同样内容(克隆) xrandr --output..._ubuntu 链接 极米
文章浏览阅读3.4k次,点赞18次,收藏92次。这是一个简单的小项目,但对于我这小白来说,也是写了好几天才完成,中间心态炸裂n次,但最后还是 搞定了!!!说了那麽多,还是分享一下吧!目录主页面(登录页面)登录页面的后台操作注册页面注册页面的后台操作实验环境是phpstudy2018。在phpstudy的www目录里,创建一个新文件夹test。文件里有:index.php 主页面(登陆页面)login.php 登录页面的后台操作register.html 注册页面register.php 注册页面的后台操作_html css注册登录
文章浏览阅读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
文章浏览阅读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函数输出
文章浏览阅读125次。对于一个年薪 40W 的 Java 开发人员来说,需要掌握哪些知识点呢?经过我自己的总结,我列出了下面的思维导图:从上面的图片我们可以看出大致分为三个部分:JDK 源码、JVM 原理、框架源码。一、JDK源码JDK 源码是一切的基础,许多框架都参考了 JDK 源码的实现思路,因此弄懂 JDK 源码是一件非常重要的事情。而 JDK 源码又可以分为下面 5 大块:集合源码 并..._40万年薪java
文章浏览阅读1.1k次。Vue上传图片并预览(好)_vue上传图片并预览
文章浏览阅读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_交易猫源码链接生成
文章浏览阅读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论文
文章浏览阅读1w次,点赞10次,收藏74次。快捷键的实用,极大的提高了大家工作中的效率,因此小编我特意帮大家搜集整理很多关于AD方面的常用快捷键,希望对大家有所帮助。一、PCB中常用快捷键R+L 输出PCB中所有网络的布线长度Ctrl+左键点击对正在布的线完成自动布线连接M+G 可更改铜的形状;按P+T在布线状态下,按Shift+A可直接进行蛇线走线T+R对已布完的线进行蛇线布线E++M+C点击空白出可迅速找到PCB上想要的元件Backsp..._layout快捷键