SythraOpen app

Confusion Matrix, Precision, Recall, and F1 Score in Python Explained

A Confusion Matrix categorizes classification predictions into True Positives, True Negatives, False Positives, and False Negatives, forming the mathematical basis for Precision, Recall, and F1 Score evaluation.

Sythra

8 min read

XLinkedIn
Confusion Matrix, Precision, Recall, and F1 Score in Python Explained — cover illustration

A Confusion Matrix is a cross-tabulated contingency table that evaluates the performance of a classification model by categorizing its predictions into four distinct quadrants: True Positives (TPTP), True Negatives (TNTN), False Positives (FPFP), and False Negatives (FNFN). Core evaluation metrics including Accuracy, Precision, Recall, and the F1F_1 Score are derived directly from these four counts.

Imagine an airport baggage screening scanner. Every scanned bag has exactly four possible diagnostic outcomes: correctly flagging a bag with prohibited items (TPTP), correctly passing a safe bag (TNTN), raising a false alarm on a harmless suitcase (FPFP), or mistakenly allowing a dangerous bag through (FNFN). Evaluating a classifier requires understanding the specific frequency and real-world cost of each mistake.

1. The Accuracy Paradox (Why Accuracy Fails on Imbalanced Data)

In fraud detection or rare disease diagnosis where only 0.1%0.1\% (1 in 1,000) of samples are positive, a trivial model that always predicts negative achieves 99.9%99.9\% Accuracy while catching zero fraud cases (Recall=0.0Recall = 0.0). Relying on accuracy alone conceals severe model failure.

2. Classification Metric Taxonomy Matrix

MetricMathematical FormulaCore Question AnsweredOptimal Application
AccuracyTP+TNTP+TN+FP+FN\frac{TP + TN}{TP + TN + FP + FN}What overall fraction of predictions was correct?Balanced datasets where false alarms and misses have equal cost.
Precision (PPV)TPTP+FP\frac{TP}{TP + FP}When the model flags a positive, how often is it right?Spam filters, search engines, automated customer loan approvals.
Recall (Sensitivity)TPTP+FN\frac{TP}{TP + FN}What fraction of all actual positive cases was caught?Cancer screening, credit card fraud, disease outbreak tracking.
Specificity (TNR)TNTN+FP\frac{TN}{TN + FP}What fraction of actual negative cases was identified?Baseline clinical testing, establishing non-disease certainty.
F1F_1 Score2×Precision×RecallPrecision+Recall2 \times \frac{\text{Precision} \times \text{Recall}}{\text{Precision} + \text{Recall}}Harmonic balance between Precision and Recall.Imbalanced datasets where both precision and recall matter equally.

3. The Mathematical Formulations

1. The 2x2 Binary Confusion Matrix

Ground Truth / PredictionPredicted Positive (1)Predicted Negative (0)
Actual Positive (1)True Positive (TPTP): Correct CatchFalse Negative (FNFN): Missed Threat (Type II Error)
Actual Negative (0)False Positive (FPFP): False Alarm (Type I Error)True Negative (TNTN): Correct Rejection

2. Why the Harmonic Mean for F1F_1?

The arithmetic average of Precision=1.0Precision = 1.0 and Recall=0.01Recall = 0.01 equals 0.5050.505, falsely indicating acceptable performance. The harmonic mean gives:

F1=2×1.0×0.011.0+0.01=0.021.010.0198F_1 = 2 \times \frac{1.0 \times 0.01}{1.0 + 0.01} = \frac{0.02}{1.01} \approx 0.0198

The harmonic mean penalizes extreme imbalances harshly, ensuring that F1F_1 is high only when both Precision and Recall are strong.

3. The Generalized FβF_\beta Score

When business requirements prioritize Recall over Precision (or vice versa), the FβF_\beta Score assigns weight β\beta to Recall:

Fβ=(1+β2)Precision×Recall(β2Precision)+RecallF_\beta = (1 + \beta^2) \frac{\text{Precision} \times \text{Recall}}{(\beta^2 \cdot \text{Precision}) + \text{Recall}}

  • F2F_2 Score (β=2\beta = 2): Weights Recall twice as heavily as Precision (medical diagnosis, fault detection).
  • F0.5F_{0.5} Score (β=0.5\beta = 0.5): Weights Precision twice as heavily as Recall (marketing outreach, auto-spam delete).

4. Worked Numerical Example (By Hand)

Suppose a diagnostic model tests 100100 patients (1010 actually have the disease, 9090 are healthy):

  • Matrix Counts: TP=7,FN=3,FP=8,TN=82TP = 7, \quad FN = 3, \quad FP = 8, \quad TN = 82.
  • Accuracy: 7+82100=0.89\frac{7 + 82}{100} = 0.89 (89%89\% overall accuracy).
  • Precision: 77+8=7150.467\frac{7}{7 + 8} = \frac{7}{15} \approx 0.467 (53.3%53.3\% of flagged patients are false alarms).
  • Recall: 77+3=710=0.70\frac{7}{7 + 3} = \frac{7}{10} = 0.70 (30%30\% of diseased patients were missed).
  • F1F_1 Score: 2×0.467×0.700.467+0.70=0.65381.1670.5602 \times \frac{0.467 \times 0.70}{0.467 + 0.70} = \frac{0.6538}{1.167} \approx 0.560.

5. Multi-Class Averaging: Macro vs. Micro vs. Weighted

Averaging MethodCalculation MechanicsBest Used For
Macro AverageUnweighted arithmetic average of metric across all classes.Highlighting performance on small, rare minority classes.
Micro AverageAggregates total TP,FP,FNTP, FP, FN globally across all classes.Measuring overall global volume correctness.
Weighted AverageAverages metrics weighted by the number of true instances in each class.Accounting for class distribution support in imbalanced data.

6. Code: Implementation From Scratch & Scikit-Learn

1. NumPy Matrix & Metric Calculations From Scratch

import numpy as np

# 10 diseased (1s), 90 healthy (0s)
y_true = np.array([1]*10 + [0]*90)
# Model catches 7 of 10 positives, makes 8 false alarms on negatives
y_pred = np.array([1]*7 + [0]*3 + [1]*8 + [0]*82)

def compute_confusion_matrix(y_true, y_pred):
    tp = np.sum((y_true == 1) & (y_pred == 1))
    tn = np.sum((y_true == 0) & (y_pred == 0))
    fp = np.sum((y_true == 0) & (y_pred == 1))
    fn = np.sum((y_true == 1) & (y_pred == 0))
    return tp, tn, fp, fn

def evaluate_classification(y_true, y_pred, beta=1.0):
    tp, tn, fp, fn = compute_confusion_matrix(y_true, y_pred)
    
    accuracy = (tp + tn) / (tp + tn + fp + fn)
    precision = tp / (tp + fp) if (tp + fp) > 0 else 0.0
    recall = tp / (tp + fn) if (tp + fn) > 0 else 0.0
    specificity = tn / (tn + fp) if (tn + fp) > 0 else 0.0
    
    # F-beta formula
    f_beta = (1 + beta**2) * (precision * recall) / ((beta**2 * precision) + recall)
    
    return {
        "TP": tp, "TN": tn, "FP": fp, "FN": fn,
        "Accuracy": round(accuracy, 3),
        "Precision": round(precision, 3),
        "Recall": round(recall, 3),
        "Specificity": round(specificity, 3),
        "F1": round(f_beta, 3)
    }

results = evaluate_classification(y_true, y_pred)
for metric, val in results.items():
    print(f"{metric}: {val}")

2. Production Scikit-Learn Report

from sklearn.metrics import confusion_matrix, classification_report

cm = confusion_matrix(y_true, y_pred)
print("Scikit-Learn Confusion Matrix [[TN, FP], [FN, TP]]:\n", cm)
print("\nClassification Report:\n", classification_report(y_true, y_pred, digits=3))

Summary

  • The Confusion Matrix partitions classification outputs into True Positives, True Negatives, False Positives, and False Negatives.
  • Accuracy is misleading on imbalanced datasets — always inspect Precision, Recall, and the Confusion Matrix.
  • Precision measures positive prediction reliability, while Recall measures detection completeness.
  • F1F_1 Score calculates the harmonic mean of Precision and Recall, while FβF_\beta allows custom weighting based on business costs.

Common questions

Why is accuracy misleading for imbalanced datasets?

When one class dominates (e.g. 99% negative cases), a naive model that always predicts negative achieves 99% accuracy while failing to identify any positive samples. Precision, Recall, and F1 score expose this failure.

What is the difference between Precision and Recall?

Precision measures what proportion of positive predictions was actually correct (TP / (TP + FP)). Recall measures what proportion of all actual positive cases the model successfully detected (TP / (TP + FN)).

Why does the F1 Score use the harmonic mean instead of an arithmetic mean?

The harmonic mean heavily penalizes extreme disparities between Precision and Recall, ensuring the F1 score is high only when both metrics perform well simultaneously.

When should you use the F2 Score instead of F1?

Use the F2 score (beta=2) when false negatives are far more dangerous than false positives (such as disease diagnosis, fraud screening, and search & rescue operations) where Recall is prioritized.