如何在Python中计算FDR=0.02%时的TDR(%)?兼论TDR与TPR的差异
核心概念差异:TPR@FPR vs TDR@FDR
- TPR@%FPR:以负样本总数为统计基准,固定假阳性率(FPR=假阳性数/负样本总数)时的真阳性率(TPR=真阳性数/正样本总数),这是ROC曲线直接提供的对应关系。
- TDR@%FDR:以模型判定的阳性样本总数为统计基准,固定假发现率(FDR=假阳性数/(真阳性数+假阳性数))时的真发现率(TDR=真阳性数/(真阳性数+假阳性数),即查准率/Precision)。两者核心差异在于统计基准不同:FPR关注负样本中的误判比例,FDR关注模型输出阳性结果中的误判比例。
如何获取FDR和TDR数组
要计算FDR和TDR数组,需要结合真实标签、模型预测得分(或已有的阈值数组),遍历每个阈值统计对应混淆矩阵指标:
- 对每个阈值,生成模型预测标签:
y_pred = (y_score >= threshold) - 统计真阳性数(TP)、假阳性数(FP)
- 计算FDR和TDR:
FDR = FP / (TP + FP)(当TP+FP=0时,可设为NaN或0,依需求处理)TDR = TP / (TP + FP)(等价于1 - FDR)
Python代码示例:
import numpy as np # 示例数据:真实标签、模型得分、阈值数组 y_true = np.array([1, 0, 1, 0, 1, 1, 0, 0]) y_score = np.array([0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2]) thresholds = np.sort(y_score)[::-1] # 按得分降序排列阈值 fdr_list = [] tdr_list = [] for thresh in thresholds: y_pred = (y_score >= thresh).astype(int) TP = np.sum((y_true == 1) & (y_pred == 1)) FP = np.sum((y_true == 0) & (y_pred == 1)) total_pos_pred = TP + FP if total_pos_pred == 0: fdr, tdr = np.nan, np.nan else: fdr = FP / total_pos_pred tdr = TP / total_pos_pred fdr_list.append(fdr) tdr_list.append(tdr) # 转换为数组 fdr_array = np.array(fdr_list) tdr_array = np.array(tdr_list)
计算FDR=0.02%时的TDR
由于FDR数组中未必存在刚好等于0.02%(即0.0002)的点,需通过线性插值获取对应TDR:
- 过滤FDR为NaN的无效数据点
- 按FDR升序排序有效数据
- 使用
np.interp进行线性插值,得到目标FDR对应的TDR
Python代码示例:
# 过滤无效值 valid_idx = ~np.isnan(fdr_array) valid_fdr = fdr_array[valid_idx] valid_tdr = tdr_array[valid_idx] # 按FDR升序排序 sort_idx = np.argsort(valid_fdr) sorted_fdr = valid_fdr[sort_idx] sorted_tdr = valid_tdr[sort_idx] # 目标FDR:0.02% = 0.0002 target_fdr = 0.0002 # 线性插值(若目标FDR超出范围,自动取边界值) target_tdr = np.interp(target_fdr, sorted_fdr, sorted_tdr) # 转换为百分比输出 target_tdr_percent = target_tdr * 100 print(f"当FDR=0.02%时,TDR为{target_tdr_percent:.2f}%")
内容的提问来源于stack exchange,提问作者Amal
相关产品推荐
相关产品推荐

