在 SQL 中计算 AUC
Posted
技术标签:
【中文标题】在 SQL 中计算 AUC【英文标题】:Computing AUC in SQL 【发布时间】:2019-06-16 12:23:09 【问题描述】:的最佳方法是什么?
这是我得到的(假设表 T(label, confid) 和 label=0,1):
SELECT sum(cumneg * label) * 1e0 / (sum(label) * sum(1-label)) AS auc
FROM (
SELECT label,
sum(1-label) OVER(ORDER BY confid ROWS UNBOUNDED PRECEDING) (BIGINT) cumneg
FROM T
) t;
我必须在 Teradata 中乘以 1e0 才能得到真正的结果。 Bigint 强制转换对于避免溢出是必要的。
【问题讨论】:
【参考方案1】:下面的伪 SQL 利用 AUC ROC 与预测分数区分随机正标签和随机负标签的概率相同的事实。 SQL 假定两个标签至少有 10000 个元素。计算的 AUC 并不精确,而是随机的。另见the same question for R。
WITH POSITIVE_SCORES AS (
select
score as p_pos
from
TABLE
where label = positive
order by rand()
limit 10000
),
NEGATIVE_SCORES AS (
select
score as p_neg
from
TABLE
where label = negative
order by rand()
limit 10000
)
select
avg(case
when p_pos > p_neg then 1
when p_pos = p_neg then 0.5
else 0
end) as auc
from
POSITIVE_SCORES
cross join
NEGATIVE_SCORES
【讨论】:
嗯,抽样有什么好处,特别是如果它需要通过 rand() 进行完整排序? 采样后有交叉连接。如果不采样,交叉连接可能会爆炸。【参考方案2】:这是我发现的一个稍微不同但可能更简单的解决方案:
SELECT (sum(label*r) - 0.5*sum(label)*(sum(label)+1)) / (sum(label) * sum(1-label)) AS auc
FROM (
SELECT label, row_number() OVER (ORDER BY confid) r
FROM T
) t;
返回与问题中的查询相同的结果。
更新
当有多个具有相同预测(可信)但标签不同的示例时,此 SQL 查询(以及问题中的查询)是不确定的。要使用插值计算确定性 AUC,可以按如下方式修改查询:
SELECT (sum(pos*r) - 0.5*sum(pos)*(sum(pos)+1) - 0.5*sum(pos*neg)) /
(sum(pos) * sum(neg)) AS auc
FROM (
SELECT pos, neg,
sum(pos+neg) OVER (ORDER BY confid ROWS UNBOUNDED PRECEDING) r
FROM (
SELECT confid, sum(label) AS pos, sum(1-label) AS neg
FROM T
GROUP BY confid) t
) t;
在AUC公式中,分母是对的总数(正X负)。分子计算有多少对被正确排列。 sum(pos*r)
计算到目前为止的对总数(基于置信度顺序)。该数字包括正 X 正对,因此第二项减去这些。最后,最后一项减去具有相同预测的正 X 负对的一半。
【讨论】:
你能分享一下基本的数学解释吗? 看看这是否有帮助:stephanosterburg.gitbook.io/scrapbook/data-science/…【参考方案3】:为了计算准确的确定性 AUC 分数,我们应该按“confid”聚合以处理并非所有置信度值都是唯一的情况。然后我们只计算每个唯一置信值的梯形面积并求和。此外,额外检查所有标签为零或一的情况。请注意,类型可能会因为乘法而溢出 - 您可以使用 BIGINT 来防止它。
MS SQL 实现:
select
IIF(SUM(Ones) * SUM(Zeros) <> 0,
SUM(IIF(Zeros * Ones > 0, 0.5 * Zeros * Ones + Height * Ones, Height * Ones)) / (SUM(Ones) * SUM(Zeros)), 0)
from (
select
Zeros,
Ones,
SUM(IIF(Zeros * Ones > 0, 0, Zeros) + IIF(PrevZeros * PrevOnes > 0, PrevZeros, 0)) OVER (ORDER BY PD) as Height
from (
select
confid as PD,
SUM(label) as Ones,
SUM(ABS(1 - label)) as Zeros,
LAG(SUM(label), 1, NULL) OVER (ORDER BY confid) as PrevOnes,
LAG(SUM(ABS(1 - label)), 1, NULL) OVER (ORDER BY confid) as PrevZeros
from T
group by confid
) q1
) q2;
【讨论】:
以上是关于在 SQL 中计算 AUC的主要内容,如果未能解决你的问题,请参考以下文章