R高级绘图 | P8 | 最最最最最简单的ROC曲线绘制并计算AUC的方法

不知为何!这两天超多小伙伴们询问ROC曲线相关问题,有的小伙伴觉得ROC曲线很复杂,画起来很麻烦;有的小伙伴提到不同模型训练得到的预测结果进行ROC曲线绘制时各种格式报错;也有来自非生物医学领域的小伙伴们也用到了ROC曲线,所以前来学习!今天,咱们就给大家介绍一种最最最最最最最最最简单的ROC曲线绘制方法!不管你是什么模型跑出来的结果,咱都百搭!不仅简单,而且万能!

前面碎碎念

ROC曲线到底是什么嘞

ROC(Receiver Operating Characteristic)曲线是一种用于评估分类模型性能的工具。它以二分类模型为基础,比如说医学诊断中的正常/异常、信用评分中的违约/不违约等。ROC曲线以真正例率(True Positive Rate,也称为灵敏度)为纵轴,假正例率(False Positive Rate)为横轴绘制而成。

在了解ROC曲线之前,需要先了解两个重要的概念:

  1. 真正例率(True Positive Rate,TPR):指分类器正确地将正例预测为正例的比率,即TPR = TP / (TP + FN),其中TP是真正例(True Positive)的数量,FN是假负例(False Negative)的数量。TPR也被称为“灵敏度”(Sensitivity)或“召回率”(Recall)。
  2. 假正例率(False Positive Rate,FPR):指分类器错误地将负例预测为正例的比率,即FPR = FP / (FP + TN),其中FP是假正例(False Positive)的数量,TN是真负例(True Negative)的数量。FPR也被称为“误报率”(False Alarm Rate)。

其实这些概念已经在之前的文章中详细介绍过啦!如下图所示,有兴趣的小伙伴们可以去看看哟!

大家可以查看:

怎么判断你的模型是好是坏?模型性能评估指标大全!

怎么判断你的模型是好是坏?模型性能评估指标大全!(二)

ROC曲线是根据不同的分类阈值绘制出来的。分类阈值决定了模型将某个样本归为正例还是负例的界限。ROC曲线上的每个点代表着在不同的阈值下模型的TPR和FPR。理想情况下,ROC曲线靠近左上角(0,1),意味着模型在所有阈值下都能实现较高的TPR和较低的FPR,即在保持高灵敏度的同时尽量减少误报率。

ROC曲线有什么用嘞

ROC曲线的应用场景包括但不限于:

  1. 评估分类器性能:ROC曲线能够直观地展示分类器在不同阈值下的性能表现。比较不同模型的ROC曲线可以帮助选择最佳模型。
  2. 选择最佳分类阈值:通过ROC曲线,可以选择最合适的分类阈值,以满足特定的需求。比如在医学诊断中,我们可能更重视减少误报率,而在搜索引擎中可能更重视提高召回率。
  3. 比较不同特征集的效果:通过绘制不同特征集对应的ROC曲线,可以评估不同特征对分类器性能的影响,从而选择最具有区分度的特征集。
  4. 调整不平衡样本的分类器:在处理不平衡样本(正负例数量差异很大)时,ROC曲线能够更好地评估分类器的性能,因为ROC曲线不受类别分布的影响。总的来说,ROC曲线是一种非常有效的工具,可以帮助理解和评估分类模型的性能,并且在各种领域的应用中都有着广泛的应用。

关于ROC的曲线,咱们今天就先介绍到这里啦!毕竟今天最最最最最重要的是,向大家介绍最最最最最最最简单的ROC曲线绘制方法!咱们往下看!

绘图代码

咱们今天主打一个简单高效!所以,只要你手头有预测结果和分组信息,咱就能帮你搞出漂亮的ROC曲线!

今日份绘图所用到的数据我已经上传到了GitHub,大家可以在公众号后台回复ROC,即可获得存放数据的链接。不过我在分享过程中也会把每一步的输入数据和输出结果进行展示,大家可以作为参考并调整自己的数据格式,然后直接用自己的数据跑,也是没有任何问题的!


##################### 最最最最最最简单的ROC曲线绘制方法 ########################

# 加载包,没有的记得安装一下哟!
library(pROC)

# 加载数据
roc_data <- readRDS("./roc_data.rds")

dim(roc_data)
# [1] 1470   81

# 我们所用的数据有:1470行、81列

head(roc_data)[1:4, c(1:3,81)]
#                                      BP10MB[0] BP10MB[1] BP10MB[2] type
# 0040b1b6-b07a-4b6e-90ef-133523eaf412       287        17        17    0
# 00508f2b-36bf-44fc-b66b-97e1f3e40bfa       278         6        14    0
# 005794f1-5a87-45b5-9811-83ddf6924568       314         0         0    0
# 005e85a3-3571-462d-8dc9-2babfc7ace21       305         4         5    0

# 可以看出,行名为样本名,前80列为特征名,最后一列`type`列为类别标签,也就是分组信息
# 这里选用这个数据集是为了给大家展示多条ROC曲线的绘制
# 大家可以把特征列看作是预测得分,就假装咱们这里一共有80个模型得到了80种预测得分
# 当然,也可以理解为每一列都是一个特征,咱们以单个特征为指标进行分类预测

# 绘制 ROC 曲线
plot.roc(
  roc_data$type,              # 通常是实际的类别标签,例如阳性或阴性,这里是`type`列
  roc_data$`BP10MB[1]`,       # 通常是预测的概率或分数,这里我们假设`BP10MB[1]`列为预测得分
  col = "#A31621",            # 曲线的颜色
  percent = TRUE,             # 将 x 轴的刻度标签转换为百分比
  lwd = 2,                    # 曲线的线宽
  print.auc = TRUE,           # 是否打印 AUC 值
  print.auc.cex = 1,          # AUC 文本的大小
  print.auc.pattern = "BP10MB[1]: %.1f%%",      # 打印 AUC 的格式,可以是预测概率或分数,也可以的单个特征指标
  print.auc.y = 50            # 打印 AUC 文本的 y 坐标,也就是 AUC 显示在图中的位置,试试你就知道啦!
)

哎嘿!一条曲线就搞定啦!

那要是有的小伙伴们想在一个图图上展示多条ROC曲线以对比不同模型或特征的预测性能该怎么办嘞!

请继续往下看!

# 咱们添加另一条 ROC 曲线
plot.roc(
  roc_data$type,              # 还是`type`列,咱们的类别标签,也就是分组信息
  roc_data$`SS[>7 & <=8]`,    # 这条 ROC 曲线咱们以`SS[>7 & <=8]`列为预测得分
  col = "#2694ab",
  percent = TRUE,
  lwd = 2,
  print.auc = TRUE,
  print.auc.cex = 1,
  print.auc.pattern = "SS[>7 & <=8]: %.1f%%",
  print.auc.y = 45,
  add = TRUE                  # 添加到已有的图上
)

可以看到图中多了一条线,就是以SS[>7 & <=8]列作为分类依据进行预测的结果。

那我们还想要更多的线该怎么做嘞!超简单!咱们继续往下看!

# 继续添加其他 ROC 曲线,参数与上述相似
plot.roc(roc_data$type, roc_data$`SS[>5 & <=6]`, col = "#8134af",
         percent = T,
         lwd = 2, print.auc = T, print.auc.cex = 1, print.auc.pattern = "SS[>5 & <=6]: %.1f%%",
         print.auc.y = 40, add = T)

plot.roc(roc_data$type, roc_data$`CN[>8]`, col = "#667572",
         percent = T,
         lwd = 2, print.auc = T, print.auc.cex = 1, print.auc.pattern = "CN[>8]: %.1f%%",
         print.auc.y = 35, add = T)

plot.roc(roc_data$type, roc_data$`CN[2]`, col = "#d0a727",
         percent = T,
         lwd = 2, print.auc = T, print.auc.cex = 1, print.auc.pattern = "CN[2]: %.1f%%",
         print.auc.y = 30, add = T)

plot.roc(roc_data$type, roc_data$`CN[1]`, col = "#de4307",
         percent = T,
         lwd = 2, print.auc = T, print.auc.cex = 1, print.auc.pattern = "CN[1]: %.1f%%",
         print.auc.y = 20, add = T)

plot.roc(roc_data$type, roc_data$`CN[4]`, col = "#005995",
         percent = T,
         lwd = 2, print.auc = T, print.auc.cex = 1, print.auc.pattern = "CN[4]: %.1f%%",
         print.auc.y = 25, add = T)

plot.roc(roc_data$type, roc_data$`CNCP[2]`, col = "#051181",
         percent = T,
         lwd = 2, print.auc = T, print.auc.cex = 1, print.auc.pattern = "CNCP[2]: %.1f%%",
         print.auc.y = 15, add = T)

plot.roc(roc_data$type, roc_data$`BPArm[4]`, col = "#8bc24c",
         percent = T,
         lwd = 2, print.auc = T, print.auc.cex = 1, print.auc.pattern = "BPArm[4]: %.1f%%",
         print.auc.y = 10, add = T)

plot.roc(roc_data$type, roc_data$`CNCP[0]`, col = "#ea7070",
         percent = T,
         lwd = 2, print.auc = T, print.auc.cex = 1, print.auc.pattern = "CNCP[0]: %.1f%%",
         print.auc.y = 5, add = T)

喔豁!大功告成!漂亮!

文末碎碎念

那今天的分享就到这里啦!我们下期再见哟!

最后顺便给自己推荐一下嘿嘿嘿!

如果我的分享对你有用的话,欢迎关注点赞在看转发分享阿巴阿巴阿巴阿巴巴巴!这可是我的第一原动力!

蟹蟹你们的喜欢和支持!!!

### 如何绘制和解释逻辑回归模型的ROC曲线 #### 构建逻辑回归模型绘制单次ROC曲线 为了展示如何构建逻辑回归模型以及绘制ROC曲线,可以使用`scikit-learn`库中的工具。以下是具体实现方法: ```python from sklearn.datasets import make_classification from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.metrics import roc_curve, auc import matplotlib.pyplot as plt # 创建模拟数据集 X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, weights=[0.9], flip_y=0) # 划分训练集与测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.5, stratify=y, random_state=42) # 训练逻辑回归分类器 clf = LogisticRegression().fit(X_train, y_train) # 预测概率值 y_pred_proba = clf.predict_proba(X_test)[::, 1] # 获取FPR(假正率), TPR(真正率) 和阈值用于画图 fpr, tpr, _ = roc_curve(y_test, y_pred_proba) roc_auc = auc(fpr, tpr) plt.figure() lw = 2 plt.plot(fpr, tpr, color='darkorange', lw=lw, label=f'ROC curve (area = {roc_auc:.2f})') plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--') # 对角线代表随机猜测的情况 plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('Receiver Operating Characteristic example') plt.legend(loc="lower right") plt.show() ``` 这段代码展示了如何创建一个简单的二元分类问题的数据集,通过逻辑回归模型对其进行拟合。接着预测样本属于某一类别的概率,利用这些概率来计算接收者操作特征(ROC曲线下面积(AUC),最终绘制成图形[^1]。 #### 解释ROC曲线及其意义 ROC曲线反映了不同决策边界下的真阳性和假阳性之间的权衡关系。当调整分类器的阈值时,会得到一系列不同的(TPR,FPR)坐标点;连接所有这样的点就构成了完整的ROC曲线。理想情况下,希望尽可能多地捕获真正的正例而少误报负例,因此越靠近左上角越好,即TPR接近于1的同时保持较低水平的FPR。AUC度量了整个ROC空间下区域大小,取值范围通常介于0到1之间,数值越大表示性能更优[^2]。 #### 使用交叉验证绘制平均ROC曲线 考虑到单一拆分可能导致结果不稳定,在实际应用中往往采用K折交叉验证的方式评估模型表现。对于每一次迭代都重复上面的过程收集各个折叠上的(FPR,TPR),之后求均值得到总体趋势更为稳定的估计值。这有助于减少由于特定分割方式带来的偏差影响。 ```python from scipy import interp from sklearn.model_selection import StratifiedKFold cv = StratifiedKFold(n_splits=5) tprs = [] aucs = [] mean_fpr = np.linspace(0, 1, 100) fig, ax = plt.subplots() for i, (train, test) in enumerate(cv.split(X, y)): probas_ = clf.fit(X[train], y[train]).predict_proba(X[test]) fpr, tpr, thresholds = roc_curve(y[test], probas_[:, 1]) tprs.append(interp(mean_fpr, fpr, tpr)) tprs[-1][0] = 0.0 roc_auc = auc(fpr, tpr) aucs.append(roc_auc) ax.plot( fpr, tpr, lw=1, alpha=0.3, label=f"Fold {i} ROC fold (AUC = %0.2f)" % roc_auc, ) ax.plot([0, 1], [0, 1], linestyle="--", lw=2, color="r", label="Chance", alpha=0.8) mean_tpr = np.mean(tprs, axis=0) mean_tpr[-1] = 1.0 mean_auc = auc(mean_fpr, mean_tpr) std_auc = np.std(aucs) ax.plot( mean_fpr, mean_tpr, color="b", label=r"Mean ROC (AUC = %0.2f $\pm$ %0.2f)" % (mean_auc, std_auc), lw=2, alpha=0.8, ) std_tpr = np.std(tprs, axis=0) tprs_upper = np.minimum(mean_tpr + std_tpr, 1) tprs_lower = np.maximum(mean_tpr - std_tpr, 0) ax.fill_between( mean_fpr, tprs_lower, tprs_upper, color="grey", alpha=0.2, label=r"$\pm$ 1 std. dev.", ) ax.set( xlim=[-0.05, 1.05], ylim=[-0.05, 1.05], title="Receiver operating characteristic example", ) ax.legend(loc="lower right") plt.show() ``` 此部分扩展了之前的方法论,引入了多次重采样的概念以获得更加稳健的结果。通过对多个子样本执行相同的操作将它们汇总起来形成一条平滑且具有统计显著性的ROC曲线
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

生信小白要知道

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值