如何在Python中从ROC曲线获取最优阈值?
在Python中从ROC曲线获取最优阈值(替代R的
coords()函数) Hey, I get it—you're looking for an equivalent to R's coords() function to grab the optimal threshold from a ROC curve in Python. While there's no direct out-of-the-box function with that exact name, scikit-learn gives us all the tools we need to calculate it easily, and we can even integrate it right into your existing plotting code.
核心思路:常用的最优阈值判定方法
最常用的两种判定逻辑是:
- Youden指数最大化:计算
TPR - FPR(真阳性率减假阳性率),取这个值最大时对应的阈值,这是临床和统计场景中很常用的指标。 - 距离左上角最近:ROC曲线的左上角
(0,1)代表完美分类(FPR=0,TPR=1),我们找曲线上离这个点欧氏距离最近的点对应的阈值。
整合到你的ROC绘图函数中
下面是修改后的代码,加入了最优阈值的计算、可视化标记,还会返回最优阈值及对应FPR/TPR:
import numpy as np from sklearn import metrics import matplotlib.pyplot as plt def plot_roc_curve(fpr, tpr, thresholds): plt.figure() plt.plot(fpr, tpr, color='darkorange', label='ROC curve (area = %0.2f)' % metrics.auc(fpr, tpr)) plt.plot([0, 1], [0, 1], color='navy', linestyle='--') plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') # --- 计算最优阈值(Youden指数法,推荐) --- youden_index = tpr - fpr best_idx = np.argmax(youden_index) best_threshold = thresholds[best_idx] best_fpr = fpr[best_idx] best_tpr = tpr[best_idx] # 如果你想用距离法,替换上面的代码为: # distances = np.sqrt((1 - tpr)**2 + (0 - fpr)**2) # best_idx = np.argmin(distances) # best_threshold = thresholds[best_idx] # best_fpr = fpr[best_idx] # best_tpr = tpr[best_idx] # 在ROC曲线上标记最优阈值点 plt.scatter(best_fpr, best_tpr, color='green', s=100, zorder=5, label=f'Optimal Threshold: {best_threshold:.2f}\n(TPR={best_tpr:.2f}, FPR={best_fpr:.2f})') # 创建阈值轴(保留你原来的逻辑) ax2 = plt.gca().twinx() ax2.plot(fpr, thresholds, markeredgecolor='r', linestyle='dashed', color='r') ax2.set_ylabel('Threshold', color='r') ax2.set_ylim([thresholds[-1], thresholds[0]]) ax2.set_xlim([fpr[0], fpr[-1]]) plt.legend(loc="lower right") plt.savefig('roc_and_threshold.png') plt.close() # 返回最优结果 return best_threshold, best_fpr, best_tpr
使用说明
- 调用
plot_roc_curve(fpr, tpr, thresholds)时,它会自动计算并返回最优阈值,同时在生成的ROC图上用绿色大圆点标记出这个最优点,还会显示对应的TPR和FPR。 - 两种阈值判定方法可以按需切换,注释掉其中一种即可。
- 注意:scikit-learn的
roc_curve()返回的thresholds是按降序排列的,和你绘图时的逻辑一致,所以索引对应不会出错。
内容的提问来源于stack exchange,提问作者morty
相关产品推荐
相关产品推荐

