Scikit-Learn:混淆矩阵中的标签不匹配

Posted

技术标签:

【中文标题】Scikit-Learn:混淆矩阵中的标签不匹配【英文标题】:Scikit-Learn: Labels don't match in Confusion Matrix 【发布时间】:2020-05-30 07:23:44 【问题描述】:

假设我有一个包含(可能)43 个不同值的数组,例如

import pandas as pd
Y_test = pd.Series([4,4,4,42,42,0,1,1,19], dtype=int)
Y_hat = pd.Series([4,4,2,32,42,0,5,5,19], dtype=int)

每当我尝试绘制混淆矩阵时:

def create_conf_mat(index, y_test, y_hat):
    cm = confusion_matrix(y_test, y_hat)
    fig = plt.figure()
    ax = fig.add_subplot(111)
    cax = ax.matshow(cm)
    plt.title(f'Confusion Matrix (index features, 1 outcome)')
    fig.colorbar(cax)
    plt.xlabel('Predicted')
    plt.ylabel('Actual')
    plt.savefig(f'confm_index.png')
    plt.savefig(f'confm_index.svg')
    plt.savefig(f'confm_index.pdf')
    return

我没有得到标签 [0, 1, 2, 4, 5, 19, 32, 42] 而是 [0, 1, 2, 3, 4, 5, 6, 7]。 我试图通过使用 y_test/y_hat 中的唯一值作为标签参数来明确设置标签,但它也不起作用。我什至尝试将整数值转换为字符串,但这样做,sklearn 抱怨至少有一个标签必须在 y_true 中。 有谁知道我如何将 y_test 和 y_pred 中的实际值绘制为混淆矩阵中的标签?

【问题讨论】:

可以在return语句前加上以下两行plt.xticks(range(len(y_test)), y_test)plt.yticks(range(len(y_hat)), y_hat) 【参考方案1】:

正如documentation 中所暗示的,关于labels 参数到confusion_matrix

如果给出 None ,则在 y_true 或 y_pred 中至少出现一次的将按排序顺序使用。

所以,我们需要同时抓取两个列表,并提取唯一数字列表:

labels = np.unique(np.concatenate([y_test.values, y_hat.values]))
plt.xticks(range(len(labels)), labels)
plt.yticks(range(len(labels)), labels)

请注意,最新版本的 'scikit-learn' 现在包括 integrated function to plot a confusion matrix 和 example code。

【讨论】:

这个答案有帮助吗? 这行得通,非常感谢!但是,标题和 X 标签现在重叠,并且设置 va/verticalalignment='bottom' 不会打印混淆矩阵底部的 xticks。你知道任何解决方法吗? :) 使用 plt.title(..., fontsize=..., pad=20) 之类的东西来控制标题和 x 刻度标签之间的距离。要获取底部的刻度,请使用 ax.xaxis.tick_bottom()

以上是关于Scikit-Learn:混淆矩阵中的标签不匹配的主要内容,如果未能解决你的问题,请参考以下文章

scikit-learn 多分类混淆矩阵

混淆矩阵中的 Scikit-learn 变化阈值

混淆矩阵(Confusion matrix)的原理及使用(scikit-learn 和 tensorflow)

Scikit-learn ValueError:使用混淆矩阵时不支持未知

如何标准化混淆矩阵?

使用没有分类器的 scikit-learn 绘制混淆矩阵