17

I have a confusion matrix created with sklearn.metrics.confusion_matrix.

Now, I would like to plot it with sklearn.metrics.plot_confusion_matrix, but the first parameter is the trained classifier, as specified in the documentation. The problem is that I don't have a classifier; the results were obtained doing manual calculations.

Is it still possible to plot the confusion matrix in one line via scikit-learn, or do I have to code it myself with matplotlib?

Irina
  • 1,333
  • 3
  • 17
  • 37

3 Answers3

34

The fact that you can import plot_confusion_matrix directly suggests that you have the latest version of scikit-learn (0.22) installed. So you can just look at the source code of plot_confusion_matrix() to see how its using the estimator.

From the latest sources here, the estimator is used for:

  1. computing confusion matrix using confusion_matrix
  2. getting the labels (unique values of y which correspond to 0,1,2.. in the confusion matrix)

So if you have those two things already, you just need the below part:

import matplotlib.pyplot as plt
from sklearn.metrics import ConfusionMatrixDisplay

disp = ConfusionMatrixDisplay(confusion_matrix=cm,
                              display_labels=display_labels)


# NOTE: Fill all variables here with default values of the plot_confusion_matrix
disp = disp.plot(include_values=include_values,
                 cmap=cmap, ax=ax, xticks_rotation=xticks_rotation)

plt.show()

Do look at the NOTE in comment.

For older versions, you can look at how the matplotlib part is coded here

Massifox
  • 4,369
  • 11
  • 31
Vivek Kumar
  • 35,217
  • 8
  • 109
  • 132
  • ConfusionMatrixDisplay is exactly what I was looking for. Thank you! – Irina Dec 04 '19 at 17:01
  • How would one get a log scaling of the confusion matrix? The context is: `import numpy as np ; from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay; disp = ConfusionMatrixDisplay(confusion_matrix=np.asarray([[13099,7004],[27420,544967]]), display_labels= np.asarray([0,1])) ; disp.plot()` . The scale of the true negatives here dwarfs everything so the colour scaling is sort of pointless here, unless there is a way to scale the colours logarithmically? Thanks in advance! – Thomas Leyshon Jan 20 '21 at 16:24
  • 1
    The problem with this approach is we can't normalize the confusion matrix. – Bilal Chandio Feb 27 '21 at 16:17
  • I cannot normalize the matrix with this approach – Shamsul Arefin Mar 18 '21 at 08:14
  • @ShamsulArefinSajib , can you please explain in more detail. `ConfusionMatrixDisplay` just takes the `cm` matrix to plot it. Are you saying that you cannot pass a normalized `cm` matrix in it? – Vivek Kumar Mar 19 '21 at 09:11
  • I mean the process using `plot_confusion_matrix` has an argument to plot the normalized version of the matrix. This process does not have anything like that. I have to normalize the matrix myself before passing into it. – Shamsul Arefin Mar 20 '21 at 02:55
  • @ShamsulArefinSajib Yes, because we are using the source code of the function to make it work without the estimator. So any changes you want to the confusion matrix must be done manually. – Vivek Kumar Mar 22 '21 at 04:13
4

The below code is to create confusion matrix from true values and predicted values. If you have already created the confusion matrix you can just run the last line below.

import seaborn as sns
from sklearn.metrics import confusion_matrix

cm = confusion_matrix(y_true, y_pred)
f = sns.heatmap(cm, annot=True, fmt='d')
Omar Ismail
  • 160
  • 1
  • 9
0

You could use a one-line "identity classifier" if that fits your use case.

IC = type('IdentityClassifier', (), {"predict": lambda i : i, "_estimator_type": "classifier"})
plot_confusion_matrix(IC, y_pred, y_test, normalize='true', values_format='.2%');

( see my original answer in: plot_confusion_matrix without estimator )

g4s9
  • 1
  • 2
  • 2
    Please avoid leaving link-only answers to other Stack Overflow posts when posting an answer. Instead, please [edit] your answer to include the most important details from the linked post that's relevant and tailored to the question being asked. – Hoppeduppeanut May 26 '21 at 00:08
  • 1
    @Hoppeduppeanut sure., I included the relevant code block here too. thanks – g4s9 May 26 '21 at 04:55