The confusion matrix
What it is
A table of counts with actual classes down the rows and predicted classes across the columns. For a binary problem it has four cells: true negatives, false positives, false negatives and true positives. Every classification metric is a ratio of these four numbers.
Why it matters
It is the only classification report that loses no information. Accuracy, precision, recall, F1 and specificity are all summaries of this table, so reading the table first tells you which summary is worth quoting.
In the real world: A fraud model's results laid out: frauds caught, frauds missed, good customers wrongly blocked, and good customers correctly let through.
Visual example
Confusion matrixFour counts. The diagonal is correct, the off-diagonal is the two kinds of mistake — and they rarely cost the same.
Every metric from these four numbers
accuracy = (891 + 45) / 1000 = 0.936
precision = 45 / 74 = 0.608
recall = 45 / 80 = 0.563
specificity = 891 / 920 = 0.968
Why this matters
Quoting one metric hides three. The table is small enough to read in full, and reading it in full is what prevents the accuracy paradox further down this module.
Common misconception
Wrong idea: the confusion matrix is a debugging aid; the metric is the result.
Correct idea: the matrix is the result. Every metric is a lossy compression of it, chosen to match a decision — so pick the compression after seeing the table, not before.
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
cm = confusion_matrix(y_val, clf.predict(X_val))
tn, fp, fn, tp = cm.ravel() # only valid for the binary case
tn, fp, fn, tp
confusion_matrix(y_val, clf.predict(X_val), normalize="true") # row-wise ratesMixing up the order. scikit-learn's rows are the actual class and columns the prediction — the opposite of many textbooks — and ravel() gives tn, fp, fn, tp, not tp first. Reversing it silently swaps precision and recall.
Practise it: Macro and Micro F1, From the Confusion Matrix Alone, Precision, Recall and F1 by Hand