【问题标题】:Seaborn Confusion Matrix (heatmap) 2 color schemes (correct diagonal vs wrong rest)Seaborn 混淆矩阵(热图)2 种配色方案(正确的对角线与错误的休息)
【发布时间】:2021-02-24 05:27:03
【问题描述】:

背景

在混淆矩阵中,对角线表示预测标签与正确标签匹配的情况。所以对角线是好的,而所有其他的单元格都是坏的。为了澄清非专家在 CM 中什么是好的和什么是坏的,我想给对角线一个与其他颜色不同的颜色。我想通过 Python 和 Seaborn 实现这一目标。

基本上我正在尝试实现这个问题在 R 中的作用 (ggplot2 Heatmap 2 Different Color Schemes - Confusion Matrix: Matches in Different Color Scheme than Missclassifications)

带有热图的普通 Seaborn 混淆矩阵

import numpy as np
import seaborn as sns

cf_matrix = np.array([[50, 2, 38],
                      [7, 43, 32],
                      [9,  4, 76]])

sns.heatmap(cf_matrix, annot=True, cmap='Blues')  # cmap='OrRd'

这会导致此图像:

目标

我想用例如颜色为非对角单元格着色cmap='OrRd'。所以我想会有 2 个颜色条,1 个蓝色用于对角线,1 个用于其他单元格。最好两个颜色条的值都匹配(例如,0-70 而不是 0-70 和 0-40)。 我该如何处理?

以下不是用代码做的,而是用照片编辑软件做的:

【问题讨论】:

    标签: python matplotlib seaborn heatmap confusion-matrix


    【解决方案1】:

    您可以在对heatmap() 的调用中使用mask= 来选择要显示的单元格。对对角线和 off_diagonal 单元格使用两个不同的掩码,您可以获得所需的输出:

    import numpy as np
    import seaborn as sns
    
    cf_matrix = np.array([[50, 2, 38],
                          [7, 43, 32],
                          [9,  4, 76]])
    
    vmin = np.min(cf_matrix)
    vmax = np.max(cf_matrix)
    off_diag_mask = np.eye(*cf_matrix.shape, dtype=bool)
    
    fig = plt.figure()
    sns.heatmap(cf_matrix, annot=True, mask=~off_diag_mask, cmap='Blues', vmin=vmin, vmax=vmax)
    sns.heatmap(cf_matrix, annot=True, mask=off_diag_mask, cmap='OrRd', vmin=vmin, vmax=vmax, cbar_kws=dict(ticks=[]))
    

    如果你想变得花哨,你可以使用 GridSpec 创建坐标轴以获得更好的布局:

    将 numpy 导入为 np 将 seaborn 导入为 sns

    fig = plt.figure()
    gs0 = matplotlib.gridspec.GridSpec(1,2, width_ratios=[20,2], hspace=0.05)
    gs00 = matplotlib.gridspec.GridSpecFromSubplotSpec(1,2, subplot_spec=gs0[1], hspace=0)
    
    ax = fig.add_subplot(gs0[0])
    cax1 = fig.add_subplot(gs00[0])
    cax2 = fig.add_subplot(gs00[1])
    
    sns.heatmap(cf_matrix, annot=True, mask=~off_diag_mask, cmap='Blues', vmin=vmin, vmax=vmax, ax=ax, cbar_ax=cax2)
    sns.heatmap(cf_matrix, annot=True, mask=off_diag_mask, cmap='OrRd', vmin=vmin, vmax=vmax, ax=ax, cbar_ax=cax1, cbar_kws=dict(ticks=[]))
    

    【讨论】:

    • 可以对彩条进行注释,以说明好坏的含义(在底部添加):cax2.set_title("X | O ", loc='right')。还有一些额外的轴标签和标题:ax.set(xlabel='Predicted label', ylabel='True label', title="Confusion Matrix")
    【解决方案2】:

    您可以先用颜色图“OrRd”绘制热图,然后用颜色图“蓝色”的热图覆盖它,将上下三角形值替换为 NaN,请参见以下示例:

    def diagonal_heatmap(m):
    
        vmin = np.min(m)
        vmax = np.max(m)    
        
        sns.heatmap(cf_matrix, annot=True, cmap='OrRd', vmin=vmin, vmax=vmax)
    
        diag_nan = np.full_like(m, np.nan, dtype=float)
        np.fill_diagonal(diag_nan, np.diag(m))
        
        sns.heatmap(diag_nan, annot=True, cmap='Blues', vmin=vmin, vmax=vmax, cbar_kws={'ticks':[]}) 
    
    
    
    
    cf_matrix = np.array([[50, 2, 38],
                          [7, 43, 32],
                          [9,  4, 76]])
    
    diagonal_heatmap(cf_matrix)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-23
      • 2020-12-08
      • 1970-01-01
      • 1970-01-01
      • 2020-07-25
      • 1970-01-01
      • 1970-01-01
      • 2014-07-09
      相关资源
      最近更新 更多