如何用Python按不同特征分段计算AUC值
按日期+特征分段计算AUC值
问题背景
现有数据集包含id、datetime、多维度模型特征(feature1/feature2/feature3等)、真实标签label和预测概率probability,数据结构如下:
id datetime feature1 feature2 feature3 ... label probability 001 2023-01-01 a1 b3 c1 ... Rejected 0.98 002 2023-01-04 a2 b1 c1 ... Approved 0.28 003 2023-01-04 a1 b2 c1 ... Rejected 0.81 004 2023-01-08 a2 b3 c2 ... Rejected 0.97 005 2023-01-09 a2 b1 c1 ... Approved 0.06 ...
需要计算每日每个特征不同取值分段下的AUC值,期望输出格式:
datetime features value AUC 2023-01-01 feature1 a1 0.98 2023-01-01 feature1 a2 ... 2023-01-01 feature2 b1 ... 2023-01-04 feature1 a1 ... ...
曾尝试用stack转置数据框,但因数据集规模过大导致运行失败。
现有代码(月度整体AUC计算)
已实现按月份分组计算整体AUC,代码如下:
def group_auc(x, col_tar, col_scr): from sklearn import metrics return metrics.roc_auc_score(x[col_tar], x[col_scr]) def map_y(x): if x == 'Rejected': return 1 elif x == 'Approved': return 0 return x ## 示例处理 y_name = 'label' df[y_name] = df[y_name].apply(map_y) # 移除含缺失标签的行 df = df.dropna(subset = [y_name]) df['Month_Year'] = df['datetime'].dt.to_period('M') group_data_monthly = df.groupby('Month_Year').apply(group_auc, y_name, 'probability').reset_index().rename(columns={0:'AUC'})
解决方案(低内存版)
针对大数据量场景,避免宽表转长表的内存开销,采用逐个特征循环处理的方式,每次仅对单个特征做分组计算,最终合并结果:
1. 预处理优化
先完成标签映射和日期提取(确保按天分组):
def group_auc(x, col_tar, col_scr): from sklearn import metrics return metrics.roc_auc_score(x[col_tar], x[col_scr]) def map_y(x): return 1 if x == 'Rejected' else 0 if x == 'Approved' else x # 数据预处理 y_name = 'label' df[y_name] = df[y_name].apply(map_y) df = df.dropna(subset=[y_name]) # 提取日期(若原datetime含时分秒,转换为纯日期格式) df['date'] = df['datetime'].dt.date
2. 循环计算各特征分段AUC
import pandas as pd # 定义需要分析的特征列表(根据实际数据集修改) feature_cols = ['feature1', 'feature2', 'feature3'] # 初始化结果容器 result_list = [] for feat in feature_cols: # 按日期+当前特征取值分组,计算AUC auc_result = df.groupby(['date', feat]).apply(group_auc, y_name, 'probability').reset_index() # 调整列名和顺序,匹配期望格式 auc_result.columns = ['datetime', 'value', 'AUC'] auc_result['features'] = feat auc_result = auc_result[['datetime', 'features', 'value', 'AUC']] # 将当前特征的结果加入列表 result_list.append(auc_result) # 合并所有特征的结果 final_result = pd.concat(result_list, ignore_index=True)
方案优势
- 避免了
stack操作带来的内存爆炸问题,单个特征分组计算的内存占用仅为原数据的一小部分 - 逻辑清晰,便于针对单个特征做调试或扩展
- 计算结果完全匹配期望的输出格式
内容的提问来源于stack exchange,提问作者Jiayu Zhang
相关产品推荐
相关产品推荐

