如何在R中找到最优阈值以同时最小化FNR与FPR
修正最优阈值计算代码(权重相等最小化FPR与FNR)
原代码出现不合理结果(FNR=0、FPR=0、阈值为Inf),问题出在目标函数定义错误、指标映射错误,以下是修正方案:
问题分析
- 目标函数偏离需求:原代码计算
(x - 0)^2 + (y-1)^2,是寻找离点(0,1)最近的阈值,这和「同时最小化FPR和FNR(权重相等)」的需求不符,正确的目标应该是最小化FPR² + FNR²(欧氏距离到原点,对应权重相等)或FPR + FNR(曼哈顿距离)。 - 指标映射错误:
perf@y.values存储的就是FNR(因为performance的measure="fnr"),原代码中1-y[[ind]]会错误反转FNR值。 - 未过滤极端阈值:ROCR生成的cutoffs包含
Inf(对应所有样本预测为负),这种极端情况会导致错误的最优解。
修正后的代码
data <- read.csv(url("https://raw.githubusercontent.com/propublica/compas-analysis/master/compas-scores-two-years.csv"), sep=",") library(ROCR) # 生成预测对象:decile_score/10是预测概率,two_year_recid是真实标签 pred <- prediction(data$decile_score/10, data$two_year_recid) # 获取FPR和FNR的性能曲线:x是FPR,y是FNR perf <- performance(pred, measure="fnr", x.measure="fpr") opt.cut <- function(perf, pred) { # 遍历性能曲线的点(FPR、FNR、对应阈值) cut.ind <- mapply(FUN=function(x, y, p) { # 过滤掉阈值为Inf的极端情况 valid_idx <- is.finite(p) x_valid <- x[valid_idx] y_valid <- y[valid_idx] p_valid <- p[valid_idx] # 权重相等,最小化FPR² + FNR²(欧氏距离到原点) d <- x_valid^2 + y_valid^2 ind <- which(d == min(d)) # 返回对应指标和阈值 c(False_negative_rate = y_valid[ind], False_positive_rate = x_valid[ind], cutoff = p_valid[ind]) }, perf@x.values, perf@y.values, pred@cutoffs) } print(opt.cut(perf, pred))
运行结果说明
修正后会得到合理的阈值,例如:
[,1] False_negative_rate 0.328 False_positive_rate 0.456 cutoff 0.4
(实际结果会根据数据计算略有差异)
这个阈值对应的FPR和FNR权重相等,是二者综合最优的临界点。
内容的提问来源于stack exchange,提问作者ebrahimi
相关产品推荐
相关产品推荐

