多类别ROC曲线绘制遇‘too many indices’等报错求助
解决多类别ROC曲线绘制的两个报错问题
我来帮你搞定这两个报错,顺便把多类别ROC曲线的绘制逻辑梳理清楚~
先分析你遇到的两个核心问题
IndexError: too many indices for array
你的Score变量是从df['Probability']提取的一维数组(每个样本只保留了最高概率的那个值),但你尝试用Score[:, i]这种二维数组的索引方式访问,自然会报错。更关键的是:计算多类别ROC时,我们需要每个样本对应所有类别的置信度得分,不是只取最高的那个概率值。ValueError: multilabel-indicator format is not supported
roc_curve函数不能直接接收完整的多类别二值化标签矩阵,必须针对每个类别单独传入该类别的真实标签(二值化后的单列)和对应类别的置信度得分,你去掉索引后传入整个矩阵,就触发了这个格式错误。
另外,你的代码里还有个隐藏问题:actual变量没有定义!计算混淆矩阵和ROC都需要真实标签,你得先从Excel里提取出真实的Intent列(比如假设列名叫Actual_Intent,你要根据自己的表格调整)。
修正后的完整代码
下面是适配你Excel数据结构的调整版代码,我加上了详细注释:
import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.preprocessing import label_binarize from sklearn.metrics import roc_curve, auc from itertools import cycle # ---------------------- 1. 数据读取与预处理 ---------------------- # 读取Excel文件 df = pd.read_excel('C:\\test.xlsx') # ********* 关键:替换成你Excel里真实Intent标签的列名 ********* actual_labels = df['Actual_Intent'].values # 真实标签 # 提取所有置信度列(假设列名以"Conf_"开头,比如Conf_intent1、Conf_intent2...) conf_cols = [col for col in df.columns if col.startswith('Conf_')] # 每个样本对应所有类别的置信度得分(二维数组:n_samples × n_classes) scores = df[conf_cols].values # 获取所有唯一的Intent类别 unique_intents = np.unique(actual_labels) n_classes = len(unique_intents) # 对真实标签进行二值化处理:n_samples × n_classes的矩阵,每个样本对应类别为1,其余为0 actual_binarized = label_binarize(actual_labels, classes=unique_intents) # ---------------------- 2. 计算每个类别的ROC曲线与AUC ---------------------- fpr = dict() tpr = dict() roc_auc = dict() # 循环每个类别计算ROC for i in range(n_classes): # 传入当前类别的真实二值标签和对应类别的置信度得分 fpr[i], tpr[i], _ = roc_curve(actual_binarized[:, i], scores[:, i]) roc_auc[i] = auc(fpr[i], tpr[i]) # ---------------------- 3. 绘制ROC曲线 ---------------------- # 设置颜色循环,区分不同类别 colors = cycle(['aqua', 'darkorange', 'cornflowerblue', 'green', 'red', 'purple']) plt.figure(figsize=(10, 8)) for i, color in zip(range(n_classes), colors): plt.plot(fpr[i], tpr[i], color=color, lw=2, label='ROC curve of {0} (area = {1:0.2f})' ''.format(unique_intents[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('Multi-Class Receiver Operating Characteristic') plt.legend(loc="lower right") plt.show() # 如果需要单独绘制每个类别的ROC曲线,可以用下面的循环 # for i in range(n_classes): # plt.figure() # plt.plot(fpr[i], tpr[i], lw=2, label=f'ROC curve (area = {roc_auc[i]:0.2f})') # plt.plot([0, 1], [0, 1], 'k--') # plt.xlim([0.0, 1.0]) # plt.ylim([0.0, 1.05]) # plt.xlabel('False Positive Rate') # plt.ylabel('True Positive Rate') # plt.title(f'ROC Curve for Intent: {unique_intents[i]}') # plt.legend(loc="lower right") # plt.show()
关键改动说明
数据提取逻辑修正:
- 不再使用单个
Probability列,而是提取所有类别对应的置信度列,得到二维的得分矩阵,确保每个类别都有对应的置信度数据。 - 明确了真实标签的提取(请务必把
Actual_Intent改成你Excel里实际的真实标签列名)。
- 不再使用单个
ROC计算逻辑修正:
- 对真实标签做二值化,得到每个类别对应的二值标签列。
- 循环每个类别时,传入该类别的真实二值标签和对应类别的置信度得分,完全符合
roc_curve的参数要求。
可视化优化:
- 增加了颜色循环,方便区分不同类别的ROC曲线;如果70个类别放在同一张图太拥挤,建议使用代码里注释的“单独绘制每个类别”的方式。
内容的提问来源于stack exchange,提问作者think-maths
相关产品推荐
相关产品推荐

