的训练过程_模型训练过程中累计auc

当测试集规模达到十亿级别时,使用sklearn.metrics.roc_auc_score计算AUC会因内存开销过大而受限。为解决此问题,可以采取对连续得分进行分桶,统计各桶内正负例数量的方式,以此计算AUC,降低内存需求。这种方法尤其适用于大规模样本的AUC计算。以下是基于PaddlePaddle代码实现的Python示例。
摘要由CSDN通过智能技术生成

37e85415c66895376be31efda093b86a.png

在平时计算auc的时候,大都是使用 sklearn.metrics.roc_auc_score 来计算。一般操作是将每个batch预测出来的结果 拼接起来,然后扔到该函数中计算。

但是如果测试集量级过大(比如 10亿量级),每个样本的预测结果拼接起来之后至少需要 3G内存。这个开销显然不是我们想要的。有什么方法可以不用拼接batch预测出来的结果就可以计算auc呢?

回想auc的概率含义:从正例采出一个样本,从负例采出一个样本,这两个样本的模型预测值,正例排在负例前面的概率。对应下面这个公式

一个比较简单的方法,我们对连续的score进行分桶,然后统计 每个桶里的 正负例 数量,经过计算就可以得到auc。这个方法的好处是,因为只需要统计 每个桶里的正负例数量,所以就不用保存每个样本的预测值。很适合 样本量级很大的 auc计算。python代码如下(翻译自paddlepaddle计算auc的代码~)。

import numpy as np
import sklearn.metrics as sklearn_metrics


class Auc(object):
    def __init__(self, num_buckets):
        self._num_buckets = num_buckets
        self._table = np.zeros(shape=[2, self._num_buckets])

    def Reset(self):
        self._table = np.zeros(shape=[2, self._num_buckets])

    def Update(self, labels: np.ndarray, predicts: np.ndarray):
        """
        :param labels: 1-D ndarray
        :param predicts: 1-D ndarray
        :return: None
        """
        labels = labels.astype(np.int)
        predicts = self._num_buckets * predicts

        buckets = np.round(predicts).astype(np.int)
        buckets = np.where(buckets < self._num_buckets,
                           buckets, self._num_buckets-1)

        for i in range(len(labels)):
            self._table[labels[i], buckets[i]] += 1

    def Compute(self):
        tn = 0
        tp = 0
        area = 0
        for i in range(self._num_buckets):
            new_tn = tn + self._table[0, i]
            new_tp = tp + self._table[1, i]
            # self._table[1, i] * tn + self._table[1, i]*self._table[0, i] / 2
            area += (new_tp - tp) * (tn + new_tn) / 2
            tn = new_tn
            tp = new_tp
        if tp < 1e-3 or tn < 1e-3:
            return -0.5  # 样本全正例,或全负例
        return area / (tn * tp)


if __name__ == '__main__':
    label = np.random.randint(low=0, high=2, size=[1000])
    predict = np.random.uniform(0, 1, size=[1000])
    auc = Auc(num_buckets=102400)
    auc.Update(label, predict)
    print(auc.Compute())
    print(sklearn_metrics.roc_auc_score(label, predict))

参考资料

https://github.com/PaddlePaddle/Paddle/blob/v1.8.5/paddle/fluid/framework/fleet/box_wrapper.h#L51

https://github.com/PaddlePaddle/Paddle/blob/v1.8.5/paddle/fluid/framework/fleet/box_wrapper.cc#L32

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值