为何无法展示多数投票集成模型的混淆矩阵?
解决集成模型混淆矩阵的多标签/多分类格式不匹配问题
我基于预训练模型构建了一个采用多数投票法的集成模型,代码如下:
from sklearn.metrics import classification_report, confusion_matrix import numpy as np # Make predictions using the ensemble method with max voting ensemble_predictions = [model1.predict(X_test), model2.predict(X_test), model3.predict(X_test), model4.predict(X_test), model5.predict(X_test)] ensemble_predictions = np.array(ensemble_predictions) ensemble_predictions = np.mean(ensemble_predictions, axis=0) ensemble_predictions = np.round(ensemble_predictions) # ensemble_predictions = np.argmax(ensemble_predictions) print(ensemble_predictions.shape) print(y_test.shape) # Print the classification report for the ensemble predictions print(classification_report(y_test, ensemble_predictions))
当前代码可正常运行并输出分类报告,但尝试生成混淆矩阵时触发错误:
ValueError: Classification metrics can't handle a mix of multiclass and multilabel-indicator targets
错误原因
这个问题的核心是**y_test与ensemble_predictions的格式不兼容**。classification_report对格式兼容性较强,但confusion_matrix要求两者必须是同一类型的目标格式:要么都是单标签类别索引(如[0,1,2]),要么都是多标签二进制指示器(如[[1,0],[0,1]])。你的代码中用np.mean()+np.round()的处理,可能让预测结果变成了多标签格式,而y_test是单标签多分类格式,导致不匹配。
解决方法
方法1:针对多分类任务(单标签),使用真正的多数投票逻辑
如果你的任务是每个样本仅属于一个类别,不要用均值+取整的方式,直接统计每个样本被各模型预测最多的类别:
import numpy as np from sklearn.metrics import classification_report, confusion_matrix from scipy.stats import mode # 按样本维度统计出现次数最多的类别 ensemble_predictions = np.array([model1.predict(X_test), model2.predict(X_test), model3.predict(X_test), model4.predict(X_test), model5.predict(X_test)]) # mode返回值为(众数数组, 次数数组),取众数部分 ensemble_predictions, _ = mode(ensemble_predictions, axis=0) # 展平成一维数组,与y_test格式对齐 ensemble_predictions = ensemble_predictions.flatten() # 生成混淆矩阵 print(confusion_matrix(y_test, ensemble_predictions)) print(classification_report(y_test, ensemble_predictions))
方法2:针对多标签任务,统一为二进制指示器格式
如果你的任务是每个样本可属于多个类别,需要把y_test也转换成二进制指示器格式,和预测结果匹配:
from sklearn.preprocessing import MultiLabelBinarizer from sklearn.metrics import multilabel_confusion_matrix # 将y_test转换为二进制指示器格式 mlb = MultiLabelBinarizer() y_test_binarized = mlb.fit_transform(y_test) # 保留你的原预测逻辑(针对多标签) ensemble_predictions = np.array([model1.predict(X_test), model2.predict(X_test), model3.predict(X_test), model4.predict(X_test), model5.predict(X_test)]) ensemble_predictions = np.mean(ensemble_predictions, axis=0) ensemble_predictions = np.round(ensemble_predictions).astype(int) # 生成多标签混淆矩阵 print(multilabel_confusion_matrix(y_test_binarized, ensemble_predictions))
其他模型输出可视化方法
除了混淆矩阵,还可以用这些方式直观展示模型效果:
- 标签分布对比直方图:
import matplotlib.pyplot as plt plt.figure(figsize=(10,5)) # 真实标签分布 plt.subplot(1,2,1) plt.hist(y_test, bins=np.unique(y_test).shape[0], alpha=0.5, label='True') plt.title('真实标签分布') plt.legend() # 预测标签分布 plt.subplot(1,2,2) plt.hist(ensemble_predictions, bins=np.unique(ensemble_predictions).shape[0], alpha=0.5, label='Predicted') plt.title('预测标签分布') plt.legend() plt.show() - 混淆矩阵热力图:
import seaborn as sns cm = confusion_matrix(y_test, ensemble_predictions) plt.figure(figsize=(8,6)) sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=mlb.classes_, yticklabels=mlb.classes_) plt.xlabel('预测类别') plt.ylabel('真实类别') plt.title('混淆矩阵') plt.show() - ROC曲线:二分类任务可直接绘制ROC-AUC曲线,多分类任务可绘制每个类别的ROC曲线。
内容的提问来源于stack exchange,提问作者Rezuana Haque
相关产品推荐
相关产品推荐

