前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >常用tools中auc实现简单调研

常用tools中auc实现简单调研

作者头像
锅逗逗
发布2022-08-01 14:55:56
1480
发布2022-08-01 14:55:56
举报
文章被收录于专栏:锅逗逗的杂学笔记

输入:预测值prob和标签label

输出:auc

xgboost

xgboost基于“从集合中任意选择一个正样本和负样本,正样本预测值大于负样本预测值的概率”实现了带weight的auc。

xgboost_release_0.72

将待计算的items按prob由高至低排列,根据排列后的items来统计共有多少个正pair(即满足正样本prob值大于负样本prob值的pair)。用sumpos和sumneg分别记录当前正负例个数,若第i个item的label为负,则增加了sumpos个正pair,依次类推。

代码语言:javascript
复制
def eval_auc(items):
    items.sort(key=lambda e: e.prob, reverse=True)
    auc, sum_pos, sum_neg = 0.0, 0.0
    for item in items:
        if item.label > 0:
            sum_pos += 1
        else:
            auc += sum_pos
            sum_neg += 1
    auc = auc / (sum_pos + sum_neg)
    return auc

这样的实现缺少考虑存在若干个item具有相同prob不同label的情况,需要设计一个buf来处理,bufpos和bufneg用于记录当前具有相同prob的正负例个数,此时增加了0.5 · bufneg · bufpos个正pair,修正后的python代码如下:

代码语言:javascript
复制
def eval_auc(items):
    items.sort(key=lambda e: e.prob, reverse=True)
    auc, sum_pos, sum_neg, buf_pos, buf_neg = 0.0, 0.0, 0.0, 0.0, 0.0
    for i, item in enumerate(items):
        if (i != 0 and item.prob != items[i - 1].prob):
            auc += buf_neg * (sum_pos + buf_pos * 0.5)
            sum_pos += buf_pos
            sum_neg += buf_neg
            buf_pos = buf_neg = 0.0
        if item.label > 0:
            buf_pos +=1
        else:
            buf_neg +=1
    auc += buf_neg * (sum_pos + buf_pos * 0.5)
    sum_pos += buf_pos
    sum_neg += buf_neg
    auc = auc / (sum_pos * sum_neg)

sklearn.metrics.roc_auc_score

sklearn通过计算roc曲线下的面积得到auc的值。由于测试样本有限,auc曲线呈现阶梯形状,当多个测试样本的prob相等且label不完全相同时,auc在该区域表现为梯形。首先将prob由高至低排序,根据item的label计算得到TPR和FPR值,并用distinct_value_indices进行过滤,最后计算以TPR为y轴,FPR为x轴的roc曲线下方的梯形面积。

代码语言:javascript
复制
def eval_auc(items):
    items.sort(key=lambda e: e.prob, reverse=True)
    probs = np.ravel(list(map(lambda e: e.prob, items)))
    labels = np.ravel(list(map(lambda e: e.label, items)))
    distinct_value_indices = np.where(np.diff(probs))[0]
    threshold_idxs = np.r_[distinct_value_indices, len(labels) - 1]
    sum_pos = np.sum(labels)
    sum_neg = np.sum(1 - labels)
    true_positive_count = np.cumsum(labels, dtype=np.float64)[
        threshold_idxs]
    false_positive_count = np.cumsum(
        1 - labels, dtype=np.float64)[threshold_idxs]
    true_positive_rate = np.r_[0, true_positive_count] / sum_pos # TPR
    false_positive_rate = np.r_[0, false_positive_count] / sum_neg # FPR
    return np.trapz(true_positive_rate, false_positive_rate)

可以看到sklearn和xgboost的实现实际上是等价的。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • xgboost
  • sklearn.metrics.roc_auc_score
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档