Accuracy hides which mistakes a model makes, and different mistakes usually cost different amounts.
Accuracy is the share of correct predictions: accuracy_score(y_true, y_pred). It is easy to read but treats every error alike and is misleading when classes are imbalanced.
The confusion matrix shows the full picture. confusion_matrix(y_true, y_pred) returns a square array where row i is the true class and column j the predicted class, rows and columns ordered by sorted label (or by the labels= you pass). For binary problems with labels 0 and 1 the layout is:
- top-left: true negatives (TN), top-right: false positives (FP),
- bottom-left: false negatives (FN), bottom-right: true positives (TP).
confusion_matrix(...).ravel() unpacks it as tn, fp, fn, tp. ConfusionMatrixDisplay.from_predictions(y_true, y_pred) plots it with matplotlib, and normalize="true" turns rows into per-class rates.
Metric functions follow the convention metric(y_true, y_pred): true values first. Swapping them silently changes asymmetric metrics like precision and recall.
Note the difference between an estimator's score and the metric functions: score uses a default metric (accuracy for classifiers, R² for regressors), while sklearn.metrics lets you compute anything on predictions you already have.
Example
from sklearn.metrics import accuracy_score, confusion_matrix
y_true = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1]
y_pred = [0, 0, 0, 0, 1, 0, 1, 0, 0, 1]
print(accuracy_score(y_true, y_pred)) # 0.7
print(confusion_matrix(y_true, y_pred))
# [[5 1]
# [2 2]]
tn, fp, fn, tp = confusion_matrix(y_true, y_pred).ravel()
print(tn, fp, fn, tp) # 5 1 2 2
print(confusion_matrix(y_true, y_pred, normalize="true").round(2))
# [[0.83 0.17]
# [0.5 0.5 ]]Remember
- Rows are true classes, columns are predicted classes
- Binary
ravel()order is tn, fp, fn, tp - Metric functions take
(y_true, y_pred)in that order
Watch out for
- Swapping y_true and y_pred, which transposes the matrix and swaps precision with recall.