多分类——ROC曲线绘制实例(宏平均法、微平均法)

目录

准备工作:

宏平均大致思路:

宏平均代码实现:

微平均大致思路:

微平均的代码实现:

最后结果:


准备工作:

'''导入数据'''
# 使用的是iris数据,datas为(150,5),前四列均为特征,最后一列为标签y,其中y为三分类
path = "iris.data"
datas = pd.read_table(path, delimiter=',', header=None)

'''数据预处理'''
print(datas.isnull().sum()) # 检查缺失值
label = datas.iloc[:,-1]    # 提取标签
data = datas.iloc[:,0:-1]   # 提取特征
# 将原来的label对应的字符串标签转换成数字标签
label = label.apply(lambda x:x).replace('Iris-setosa',0)
label = label.apply(lambda x:x).replace('Iris-versicolor',1)
label = label.apply(lambda x:x).replace('Iris-virginica',2)
# 划分训练集与测试集
xtrain,xtest,ytrain,ytest = train_test_split(data,label, test_size=0.3, random_state=8)
# 标准化数据(这里使用的是minmax归一法)
transfer = MinMaxScaler()
xtrain_s = transfer.fit_transform(xtrain)
xtest_s = transfer.fit_transform(xtest)

'''建模'''
# 这里用随机森林建模
forest = RandomForestClassifier(n_estimators=100, criterion='gini', bootstrap=True,
                                max_depth=3, random_state=8)
forest = forest.fit(xtrain_s, ytrain)
score = forest.score(xtest_s, ytest)
ytest_proba = forest.predict_proba(xtest_s)  # 获得每个类别对应的概率 (45,3)

# 将y标签转换成one-hot形式
ytest_l = list(np.array(ytest))
ytest_one = label_binarize(ytest_l, classes=[0,1,2])  (45,3)


宏平均大致思路:

        宏平均本质上是将多分类问题转换成了n个二分类的问题(例如在本模型中预测值y的标签为3分类,那么n即为3,也就是将原标签转换成one-hot后,他的每一列代表一个相对于其他类,该样本是否属于该类的一个二分类问题)  ,再分别对这n个二分类的问题求他对应的FPR、TPR(求法和二分类问题一样),再把所有计算出来的FPR放在一起去重、从小到大排序,然后对每一个FPR分别在这三个类中所对应的TPR相加求平均。最后ROC曲线的横坐标即为去重、排序过后的FPR,纵坐标为求完平均后的TPR

宏平均代码实现:

'''宏平均法'''
macro_AUC = {}
macro_FPR = {}
macro_TPR = {}
# 获的每一个类别对应的TPR、FPR、AUC
for i in range(ytest_one.shape[1]):
    macro_FPR[i],macro_TPR[i],thresholds = metrics.roc_curve(ytest_one[:,i], ytest_proba[:,i])
    macro_AUC[i] = metrics.auc(macro_FPR[i],macro_TPR[i])
print(macro_AUC)

# 把所有的FPR合并去重、排序
macro_FPR_final = np.unique(np.concatenate([macro_FPR[i] for i in range(ytest_one.shape[1])]))

# 在每个类别中计算macro_FPR_final对应的TPR 并相加求平均
macro_TPR_all = np.zeros_like(macro_FPR_final)
for i in range(ytest_one.shape[1]):
    macro_TPR_all = macro_TPR_all + np.interp(macro_FPR_final, macro_FPR[i], macro_TPR[i])
macro_TPR_final = macro_TPR_all / ytest_one.shape[1] # 注:当FPR对应多个TPR时,interp会返回最大的那个TPR
macro_AUC_final = metrics.auc(macro_FPR_final, macro_TPR_final)

# 计算最终的AUC
AUC_final = metrics.auc(FPR_final, TPR_final)

微平均大致思路:


        微平均法的本质可以视为是将多分类问题转换成一个二分类问题,通过将转换成one-hot以后的原始标签矩阵以及建模后得到的每个类别的预测概率同时拉平(下面的例子中没放每个类别的预测概率),拉平后的新的标签矩阵将每一个元素(A-1,A-2等)都视为一个样本(如下例中共6*3=18个),同时每个样本下面的所对应的1,0代表是与否(例如新标签矩阵中的A-3就表示A是属于第三类的),最后用得到的新的二分类的标签矩阵求FPR与TPR

原始标签矩阵(one-hot形式)
样本类别1类别2类别3
A001
B100
C010
D100
E011
F100
新标签矩阵
A-1A-2A-3B-1...F-3
0011...0

微平均的代码实现:

'''微平均法'''
# 将标签、以及建模后得到的每个样本分类的预测概率拉平
micro_ytest_one = np.ravel(ytest_one)
micro_ytest_proba = np.ravel(ytest_proba)
# 计算微平均法下的FPR、TPR
micro_FPR,micro_TPR,mic_thresholds = metrics.roc_curve(micro_ytest_one, micro_ytest_proba)
micro_AUC = metrics.auc(micro_FPR,micro_TPR)

最后结果:

'''画图'''
plt.figure(figsize=(8,6))
plt.plot(macro_FPR[0],macro_TPR[0],'b.-', label='类别1ROC  AUC={:.2f}'.format(macro_AUC[0]), lw=2)
plt.plot(macro_FPR[1],macro_TPR[1],'y.-', label='类别2ROC  AUC={:.2f}'.format(macro_AUC[1]), lw=2)
plt.plot(macro_FPR[2],macro_TPR[2],'r.-', label='类别3ROC  AUC={:.2f}'.format(macro_AUC[2]), lw=2)
plt.plot(macro_FPR_final,macro_TPR_final,'kx-', label='宏平均法ROC  AUC={:.2f}'.format(macro_AUC_final), lw=2)
plt.plot(micro_FPR,micro_TPR,'k|-', label='微平均法ROC  AUC={:.2f}'.format(micro_AUC),lw=2)
plt.plot([0,1], [0,1], 'k--', label='45度参考线')
plt.xlabel('FPR',fontsize=13)
plt.ylabel('TPR',fontsize=13)
plt.title('鸢尾花数据随机森林分类后的ROC和AUC',fontsize=13)
plt.grid(linestyle='-.')
plt.legend(loc='lower right',framealpha=0.8, fontsize=8)
plt.show()

        

参考的文章:

多分类-- ROC曲线 - 静悟生慧 - 博客园 (cnblogs.com)

【多分类ROC曲线 (2) 微平均法-哔哩哔哩】 https://b23.tv/GgRqzUj

注:本人水平有限,主要写来以后复盘看,有理解错的地方还请大佬指正

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是使用Pythonscikit-learn库绘制随机森林多分类模型的ROC曲线的代码示例: ```python from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import roc_curve, auc from sklearn.preprocessing import label_binarize from sklearn.multiclass import OneVsRestClassifier from itertools import cycle import matplotlib.pyplot as plt # 加载数据集并分割成训练集和测试集 X_train, X_test, y_train, y_test = ... # 创建随机森林多分类模型 rf = RandomForestClassifier(n_estimators=100, random_state=42) # 将多分类问题转换为二分类问题 y_train_bin = label_binarize(y_train, classes=[0, 1, 2, ..., n_classes-1]) y_test_bin = label_binarize(y_test, classes=[0, 1, 2, ..., n_classes-1]) # 训练模型并进行预测 rf.fit(X_train, y_train_bin) y_score = rf.predict_proba(X_test) # 计算ROC曲线和AUC值 fpr = dict() tpr = dict() roc_auc = dict() for i in range(n_classes): fpr[i], tpr[i], _ = roc_curve(y_test_bin[:, i], y_score[:, i]) roc_auc[i] = auc(fpr[i], tpr[i]) # 绘制ROC曲线 plt.figure(figsize=(8, 6)) colors = cycle(['blue', 'red', 'green', ..., 'purple']) for i, color in zip(range(n_classes), colors): plt.plot(fpr[i], tpr[i], color=color, lw=2, label='ROC curve of class {0} (area = {1:0.2f})' ''.format(i, roc_auc[i])) plt.plot([0, 1], [0, 1], 'k--', lw=2) 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 Curve') plt.legend(loc="lower right") plt.show() ``` 其,`n_classes`是类别数,`X_train`、`X_test`、`y_train`和`y_test`是训练集和测试集的特征和目标变量。在代码,使用`label_binarize`将多分类问题转换为二分类问题,使用`OneVsRestClassifier`可以将多分类模型转化为多个二分类模型,但这里直接使用随机森林多分类模型进行了训练和预测。最后,使用`roc_curve`函数计算ROC曲线和AUC值,并使用`matplotlib`库绘制ROC曲线
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值