python绘制ROC曲线 如何绘制ROC曲线!来看!

最近画ROC曲线遇到了些困难,解决后留个档,分享一下,希望能帮助到有同样问题的大家~

问题

画出来的ROC图像只有一个折点(图1),但正确的ROC曲线应该是看起来圆润的(图2),那么如何画正确的图像?

问题所在:要用预测的score分数(选择正类概率),而非预测的标签与真实标签进行ROC计算!

 先以逻辑回归为例:

from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) # 分数据集
model = LogisticRegression()
model.fit(X_train, y_train)
y_scores = model.predict_proba(X_test)[:, 1] # 选择正类的概率!
fpr1, tpr1, thread1 = roc_curve(y_test, y_scores) # 注意用的是y_scores!
roc_auc = auc(fpr1, tpr1)
# 绘图
plt.figure()
lw = 2
plt.plot(fpr1, tpr1, color='darkred',
 lw=lw, label='ROC curve (area = %0.2f)' % roc_auc)
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('ROC')
plt.legend(loc="lower right")
plt.savefig('roc.png')
plt.show()

这里的y_scores是概率哦,后续再绘图就是正确的啦。

再多算几个SVM、随机森林的score:

# SVM
from sklearn.svm import SVC
svm_model = SVC(probability=True)
svm_model.fit(X_train, y_train)
y_scores_svm = svm_model.predict_proba(X_test)[:, 1] # 选择正类的概率!
y_pred_svm = svm_model.predict(X_test) # 计算准确率
print("SVM Accuracy:", accuracy_score(y_test, y_pred_svm))
# 随机森林
from sklearn.ensemble import RandomForestClassifier
rf_model = RandomForestClassifier(random_state=0)
rf_model.fit(X_train, y_train)
y_scores_rf = rf_model.predict_proba(X_test)[:, 1] # 选择正类的概率!
y_pred_rf = rf_model.predict(X_test) # 计算准确率
print("Random Forest Accuracy:", accuracy_score(y_test, y_pred_rf))

深度学习也是一样,举个小例子:

import torch 
import numpy as np 
from torch.utils.data import DataLoader 
import seaborn as sns 
import matplotlib.pyplot as plt 
from sklearn.metrics import roc_curve, auc
 
# 加载模型 
device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 调到GPU 
model = net(hidden_size=512) # 调模型
weight = torch.load('./model.pth', map_location=device) # 训练的最佳参数权重
model.load_state_dict(weight,strict=False) 
model = model.to(device)
model.eval() # 将模型设置为评估模式 
 
# 存储预测分数概率
y_score = []
with torch.no_grad(): # 不需要计算梯度 
 for data, target in dataloader_test: 
 data = data.to(device) # 将数据移到正确的设备上 
 output = model(data) # 获取模型的输出 
 y_score.extend(output.cpu().numpy()) # 存储分数概率
# 计算ROC
fpr, tpr, thread = roc_curve(y_test, y_score)
roc_auc = auc(fpr, tpr)
# 后续绘图同上

如果想在一张图上同时绘制多条ROC曲线:

# 绘图
plt.figure()
lw = 2
plt.plot(fpr, tpr, color='darkorange',
 lw=lw, label='SVM ROC curve (area = %0.2f)' % roc_auc1)
plt.plot(fpr1, tpr1, color='green',
 lw=lw, label='Random forest ROC curve (area = %0.2f)' % roc_auc2)
plt.plot(fpr,tpr,color = 'darkred',label = 'deproc area:(%0.2f)'%auc)
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()

这里由于数据量较少原因,图也没有特别特别圆润哈哈,依然存在折线,不过也是正确的!

未来遇到其代码问题,也将持续分享~希望能帮助到大家!加油!

作者:私人认证的科研小天才原文地址:https://blog.csdn.net/qq_61854787/article/details/140867656

%s 个评论

要回复文章请先登录注册