如何在没有颜色编码的情况下绘制混淆矩阵
how to plot confusion matrix without color coding
我在 Whosebug 上看到的所有答案中,例如 1, 2 and 3 都是颜色编码的。
在我的例子中,我不希望它是彩色的,特别是因为我的数据集在很大程度上是不平衡的,少数 类 总是以浅色显示。相反,我更希望它在每个单元格中显示 actual/predicted 的数量。
目前,我使用:
def plot_confusion_matrix(cm, classes, title,
normalize=False,
file='confusion_matrix',
cmap=plt.cm.Blues):
if normalize:
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
cm_title = "Normalized confusion matrix"
else:
cm_title = title
# print(cm)
plt.imshow(cm, interpolation='nearest', cmap=cmap)
plt.title(cm_title)
plt.colorbar()
tick_marks = np.arange(len(classes))
plt.xticks(tick_marks, classes, rotation=45)
plt.yticks(tick_marks, classes)
fmt = '.3f' if normalize else 'd'
thresh = cm.max() / 2.
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
plt.text(j, i, format(cm[i, j], fmt),
horizontalalignment="center",
color="white" if cm[i, j] > thresh else "black")
plt.tight_layout()
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.tight_layout()
plt.savefig(file + '.png')
输出:
所以我只想要显示的数字。
您可以使用只有一种颜色的 ListedColormap
颜色图。使用 Seaborn 会自动执行很多事情,包括:
- 在正确的位置设置注释,黑色或白色取决于单元格的暗度
- 设置分割线的一些参数
- 设置刻度标签的参数
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np
import pandas as pd
import seaborn as sns
def plot_confusion_matrix(cm, classes, title,
normalize=False, file='confusion_matrix', background='aliceblue'):
if normalize:
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
plt.title("Normalized confusion matrix")
else:
plt.title(title)
fmt = '.3f' if normalize else 'd'
sns.heatmap(np.zeros_like(cm), annot=cm, fmt=fmt,
xticklabels=classes, yticklabels=classes,
cmap=ListedColormap([background]), linewidths=1, linecolor='navy', clip_on=False, cbar=False)
plt.tick_params(axis='x', labelrotation=30)
plt.tight_layout()
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.tight_layout()
plt.savefig(file + '.png')
cm = np.random.randint(1, 20000, (5, 5))
plot_confusion_matrix(cm, [*'abcde'], 'title')
对灰度色图使用 seaborn.heatmap
并设置 vmin=0, vmax=0
:
import seaborn as sns
sns.heatmap(cm, fmt='d', annot=True, square=True,
cmap='gray_r', vmin=0, vmax=0, # set all to white
linewidths=0.5, linecolor='k', # draw black grid lines
cbar=False) # disable colorbar
# re-enable outer spines
sns.despine(left=False, right=False, top=False, bottom=False)
完整功能:
def plot_confusion_matrix(cm, classes, title,
normalize=False,
file='confusion_matrix',
cmap='gray_r',
linecolor='k'):
if normalize:
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
cm_title = 'Confusion matrix, with normalization'
else:
cm_title = title
fmt = '.3f' if normalize else 'd'
sns.heatmap(cm, fmt=fmt, annot=True, square=True,
xticklabels=classes, yticklabels=classes,
cmap=cmap, vmin=0, vmax=0,
linewidths=0.5, linecolor=linecolor,
cbar=False)
sns.despine(left=False, right=False, top=False, bottom=False)
plt.title(cm_title)
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.tight_layout()
plt.savefig(f'{file}.png')
我在 Whosebug 上看到的所有答案中,例如 1, 2 and 3 都是颜色编码的。
在我的例子中,我不希望它是彩色的,特别是因为我的数据集在很大程度上是不平衡的,少数 类 总是以浅色显示。相反,我更希望它在每个单元格中显示 actual/predicted 的数量。
目前,我使用:
def plot_confusion_matrix(cm, classes, title,
normalize=False,
file='confusion_matrix',
cmap=plt.cm.Blues):
if normalize:
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
cm_title = "Normalized confusion matrix"
else:
cm_title = title
# print(cm)
plt.imshow(cm, interpolation='nearest', cmap=cmap)
plt.title(cm_title)
plt.colorbar()
tick_marks = np.arange(len(classes))
plt.xticks(tick_marks, classes, rotation=45)
plt.yticks(tick_marks, classes)
fmt = '.3f' if normalize else 'd'
thresh = cm.max() / 2.
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
plt.text(j, i, format(cm[i, j], fmt),
horizontalalignment="center",
color="white" if cm[i, j] > thresh else "black")
plt.tight_layout()
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.tight_layout()
plt.savefig(file + '.png')
输出:
所以我只想要显示的数字。
您可以使用只有一种颜色的 ListedColormap
颜色图。使用 Seaborn 会自动执行很多事情,包括:
- 在正确的位置设置注释,黑色或白色取决于单元格的暗度
- 设置分割线的一些参数
- 设置刻度标签的参数
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np
import pandas as pd
import seaborn as sns
def plot_confusion_matrix(cm, classes, title,
normalize=False, file='confusion_matrix', background='aliceblue'):
if normalize:
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
plt.title("Normalized confusion matrix")
else:
plt.title(title)
fmt = '.3f' if normalize else 'd'
sns.heatmap(np.zeros_like(cm), annot=cm, fmt=fmt,
xticklabels=classes, yticklabels=classes,
cmap=ListedColormap([background]), linewidths=1, linecolor='navy', clip_on=False, cbar=False)
plt.tick_params(axis='x', labelrotation=30)
plt.tight_layout()
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.tight_layout()
plt.savefig(file + '.png')
cm = np.random.randint(1, 20000, (5, 5))
plot_confusion_matrix(cm, [*'abcde'], 'title')
对灰度色图使用 seaborn.heatmap
并设置 vmin=0, vmax=0
:
import seaborn as sns
sns.heatmap(cm, fmt='d', annot=True, square=True,
cmap='gray_r', vmin=0, vmax=0, # set all to white
linewidths=0.5, linecolor='k', # draw black grid lines
cbar=False) # disable colorbar
# re-enable outer spines
sns.despine(left=False, right=False, top=False, bottom=False)
完整功能:
def plot_confusion_matrix(cm, classes, title,
normalize=False,
file='confusion_matrix',
cmap='gray_r',
linecolor='k'):
if normalize:
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
cm_title = 'Confusion matrix, with normalization'
else:
cm_title = title
fmt = '.3f' if normalize else 'd'
sns.heatmap(cm, fmt=fmt, annot=True, square=True,
xticklabels=classes, yticklabels=classes,
cmap=cmap, vmin=0, vmax=0,
linewidths=0.5, linecolor=linecolor,
cbar=False)
sns.despine(left=False, right=False, top=False, bottom=False)
plt.title(cm_title)
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.tight_layout()
plt.savefig(f'{file}.png')