You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Sklearn评分器:计算Top x%预测结果的ROC AUC

解决Top x%样本的ROC AUC/平均精度计算问题

现有代码的问题分析

你的代码存在两个核心问题:

  1. 拼写错误:len(predicitons_df)中的变量名拼错,应为predictions_df,这会导致k值计算错误(比如比例设为1时,k不等于全部样本数量,所以结果和常规ROC AUC不同)。
  2. 逻辑偏差:直接截取Top k样本后调用roc_auc_score,本质是计算这k个样本内部的ROC AUC,而非你需要的「全局排序下Top x%高置信度样本的模型区分能力」。如果Top k样本中类别单一(比如全是正/负样本),函数会始终返回0.5或1.0,这就是你看到“始终返回相同值”的原因。

正确实现方案

Top x% Partial ROC AUC

这个函数基于全局样本的预测概率排序,计算ROC曲线中对应Top x%高置信度样本部分的AUC,精准反映模型在高价值预测区间的性能:

import pandas as pd
from sklearn.metrics import roc_curve

def top_x_roc_auc(y_true, y_score, top_pct=0.25):
    # 按预测得分降序排序所有样本
    sorted_indices = y_score.argsort()[::-1]
    y_true_sorted = y_true[sorted_indices]
    y_score_sorted = y_score[sorted_indices]
    
    n_total = len(y_true)
    k = round(n_total * top_pct)
    if k == 0:
        raise ValueError("Top占比过小,未筛选到有效样本")
    
    # 确定Top k样本的阈值(第k个样本的预测得分)
    threshold_k = y_score_sorted[k-1] if k < n_total else y_score_sorted[-1]
    
    # 计算全局ROC曲线,并筛选出阈值>=threshold_k的部分(对应Top k样本)
    fpr, tpr, thresholds = roc_curve(y_true, y_score, pos_label=1)
    mask = thresholds >= threshold_k
    
    # 补充原点(0,0),确保曲线完整
    fpr_partial = [0.0] + list(fpr[mask])
    tpr_partial = [0.0] + list(tpr[mask])
    
    # 用梯形法计算Partial AUC
    auc_partial = 0.0
    for i in range(1, len(fpr_partial)):
        auc_partial += (fpr_partial[i] - fpr_partial[i-1]) * (tpr_partial[i] + tpr_partial[i-1]) / 2
    
    return auc_partial

Top x% 平均精度(AP)

同理,针对平均精度的Top x%计算,聚焦高置信度样本的查准率-召回率表现:

from sklearn.metrics import precision_recall_curve

def top_x_average_precision(y_true, y_score, top_pct=0.25):
    sorted_indices = y_score.argsort()[::-1]
    y_true_sorted = y_true[sorted_indices]
    
    n_total = len(y_true)
    k = round(n_total * top_pct)
    if k == 0:
        raise ValueError("Top占比过小,未筛选到有效样本")
    
    # 截取Top k样本
    y_true_top = y_true_sorted[:k]
    y_score_top = y_score_sorted[:k]
    
    # 计算前k个样本的查准率-召回率曲线
    precision, recall, _ = precision_recall_curve(y_true_top, y_score_top)
    
    # 用梯形法计算平均精度
    ap = 0.0
    for i in range(1, len(recall)):
        ap += (recall[i-1] - recall[i]) * precision[i]
    
    return ap

验证说明

  • 当top_pct=1.0时,top_x_roc_auc的结果会和sklearn.metrics.roc_auc_score完全一致,符合预期。
  • 若Top x%样本中同时存在正负样本,函数会返回合理的区分度指标;若类别单一,会返回0.5(ROC AUC)或对应类别的精度值(平均精度)。

内容的提问来源于stack exchange,提问作者Kyle Mouly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 15:05:06