MLE / Research · ML Coding / Fundamentals

TikTok AUC-ROC:排序配对、同分半票与单类边界

用正负配对概率推导分组统计,解释阈值与不平衡局限,避免同分顺序影响分数。

题目重点:用正负配对概率推导分组统计,解释阈值与不平衡局限,避免同分顺序影响分数。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练二分类,score越大越像正类;AUC无样本权重,标签0/1,必须同时有正负。
  • score有限,同分算0.5;单类返回错误而非编造0或1。

解题路线

  1. ROC点由阈值产生TPR=TP/(TP+FN)和FPR=FP/(FP+TN),AUC可解释为随机正样本分数高于随机负样本的概率,加同分一半。它主要评价排序,不直接选业务阈值。
  2. 暴力枚举P×N正负配对作为明确基线。优化先按score升序分组,维护此前负样本数below;本组p个正、n个负贡献p·below+0.5pn。
  3. 整组一次更新below,避免同分项的排序先后决定胜负。最后除总P·N;反转score方向通常让AUC变为1−AUC,同分贡献保持。
  4. AUC对严格单调score变换不变,但不说明概率校准正确;两个模型相同排序可有非常不同概率值。低FPR区域、precision或PR曲线对稀少正例业务可能更相关。
  5. 只有一种标签时没有正负对,AUC未定义;空输入、NaN和标签错误需明确。跨batch局部AUC平均也不一定等于全量AUC,配对会跨batch。
  6. 测试全同分、完美/反向排序、重复分数、单类和小整数穷举,对照全配对不用另一个排序算法。线上按群组计算时还要报告样本数量和单类缺值。

手动走一遍

正score=0.8、负=0.2,AUC1;同为0.5则0.5;正低负高为0。labels=[0,1]同分不能因排序稳定性变成0或1。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

from math import isfinite


def roc_auc(labels, scores):
    if not labels or len(labels) != len(scores) or any(y not in (0, 1) for y in labels):
        raise ValueError('matching binary labels required')
    if any(not isfinite(s) for s in scores):
        raise ValueError('finite scores required')
    positive = sum(labels)
    negative = len(labels) - positive
    if not positive or not negative:
        raise ValueError('AUC undefined without both classes')
    ordered = sorted(zip(scores, labels))
    wins, below, i = 0.0, 0, 0
    while i < len(ordered):
        j = i
        p = n = 0
        while j < len(ordered) and ordered[j][0] == ordered[i][0]:
            if ordered[j][1]:
                p += 1
            else:
                n += 1
            j += 1
        wins += p * below + 0.5 * p * n
        below += n
        i = j
    return wins / (positive * negative)

复杂度

n样本排序O(n log n),分组O(n),排序存储O(n);暴力oracle O(PN)。输出1个数但需全排序或其他统计结构。

易错点与追问

容易失分的边界

  • 同分按0或1取决于顺序。
  • 单类随便返回0.5。
  • AUC高便概率校准好。
  • 平均batch AUC当全量。

继续深挖

  • 加样本权重如何计配对?
  • 分布式怎么合并全局排序信息?
  • 业务为何看低FPR区间?
✓已复制微信号!