Labs/Machine Learning/classification
Machine LearningBeginner
~25 min

Classification & Decision Boundaries

Partition feature spaces into discrete category regions using linear decision hyperplanes and non-parametric neighborhood boundaries.

#Logistic Regression#Binary Cross-Entropy (Log-Loss)#Decision Boundaries#Confusion Matrix (TP, FP, TN, FN)#Precision-Recall Trade-off#Class Imbalance & Bayes Error
01

Overview

The Problem Statement

Unlike regression which predicts continuous scalar values, classification assigns observations to discrete categorical classes (e.g. spam vs ham, fraudulent vs legitimate transaction, benign vs malignant). The engineering challenge is learning optimal decision boundaries that maximize classification utility while tolerating noise and class imbalance.

System Invariant:A classification decision boundary represents the geometric locus of points in feature space where the posterior class probability P(y=1|x) equals the decision threshold τ (default τ = 0.5; wᵀx + b = 0 for linear models).
✓ When To Use
  • Discrete decision-making pipelines: fraud detection, content moderation, network intrusion detection.
  • Calibrated probability estimation: calculating the risk score (P(y=1|x)) that an infrastructure node will experience hardware failure within 24 hours.
  • Multi-class categorization: routing customer support tickets to appropriate specialized service teams.
✕ When NOT To Use
  • Predicting continuous numerical quantities without predefined thresholds (use Linear Regression).
  • Rank ordering search results where relative pairwise relevance matters more than class membership (use Learning-to-Rank).
  • Novelty or anomaly detection with virtually zero labeled positive examples (use One-Class SVM or Isolation Forests).
02

Why It Exists

Catastrophic Outage Scenario

A fintech credit card fraud pipeline optimizes an unweighted classifier using standard Accuracy on a dataset with 99.9% legitimate transactions and 0.1% fraud. The trained model learns a trivial majority classifier that outputs 'Legitimate' for every card swipe. The monitoring dashboard displays 99.9% Accuracy. The business incurs $14M in fraudulent chargebacks over the weekend with zero alerts fired, because Recall on the fraud class was precisely 0.0%.

Downstream System Degradation:
  • The Accuracy Paradox: deceptively high accuracy masking zero recall on rare critical events.
  • Threshold misalignment causing excessive false positives that overwhelm human fraud review teams.
  • Severe boundary shift under covariate drift, misclassifying emerging fraud patterns.
  • Bayes error rate limits: inability to separate intrinsically overlapping feature distributions.
03

How It Works

Logistic regression passes the linear combination z = wᵀx + b through the non-linear Sigmoid function: σ(z) = 1 / (1 + e⁻ᶻ), mapping any real number to a calibrated probability p ∈ (0, 1).

The model is trained by minimizing Binary Cross-Entropy (Log-Loss): L(w, b) = - (1/n) ∑ [ yᵢ ln(pᵢ) + (1 - yᵢ) ln(1 - pᵢ) ]. Log-Loss heavily penalizes confident wrong predictions (e.g. predicting p=0.001 when true y=1 incurs huge loss).

The decision boundary is the hyperplane defined by wᵀx + b = ln(τ / (1 - τ)). For default threshold τ = 0.5, this simplifies to the hyperplane wᵀx + b = 0.

Single-Node vs Distributed Reality:

For small to medium tabular datasets, Logistic Regression trains in seconds via L-BFGS or Newton-Raphson (IRLS) on a single CPU core. In massive ad-tech click-through-rate (CTR) prediction with billions of sparse one-hot features, models are trained across distributed clusters using Downpour SGD or parameter servers with FTRL-Proximal (Follow-the-Regularized-Leader).

Logistic Regression (Linear Parametric)

Fits a linear boundary wᵀx + b = 0 using gradient descent on cross-entropy loss. Outputs calibrated class probabilities.

+ Fast O(d) inference; highly interpretable odds-ratio coefficients; convex optimization.
- Can only produce linear (flat) decision boundaries without manual polynomial feature engineering.

K-Nearest Neighbors (KNN - Non-Parametric)

Assigns class by querying the k nearest points in feature space and taking a plurality vote.

+ Zero training time; learns arbitrarily complex non-linear boundaries without assumptions.
- Inference scales with O(N·d); severely degraded by high dimensionality (curse of dimensionality).

Support Vector Machines (SVM with RBF Kernel)

Maximizes the geometric margin between classes using support vectors and projects features into infinite-dimensional Hilbert space.

+ Effective in high-dimensional spaces; robust against non-support vector outliers.
- O(N²) to O(N³) training complexity; does not output native calibrated probabilities.
Engineering Prediction Challenge

Prove It: Predict the System Behavior

Reason before simulating
System State Given

A fraud detection dataset contains 9,900 legitimate transactions (Class 0) and 100 fraudulent transactions (Class 1). An engineer trains a naive classifier that predicts 'Legitimate' for every single input.

Prediction Question:

What are the model's Accuracy and Recall for the fraudulent class?

A

Accuracy: 50.0%, Recall: 50.0%

B

Accuracy: 99.0%, Recall: 0.0%

C

Accuracy: 99.0%, Recall: 99.0%

04

Interactive Visualizer

Interact directly with this distributed system primitive. Experiment with fault injection and observe state transitions.

Classification & Decision Boundaries

Click to place points. Compare linear separation (Logistic) vs non-parametric boundary (KNN).

Add:
Accuracy100.0%
Precision (Class 1)100.0%
Recall (Class 1)100.0%
F1-Score1.000
Feature X₁Feature X₂Class 0 at (2.0, 7.0)Class 0 at (2.5, 8.2)Class 0 at (3.2, 6.5)Class 0 at (3.8, 7.8)Class 0 at (1.8, 5.5)Class 0 at (4.2, 6.0)Class 0 at (2.8, 6.0)Class 1 at (6.5, 3.0)Class 1 at (7.2, 2.2)Class 1 at (8.0, 3.5)Class 1 at (6.0, 4.2)Class 1 at (7.8, 4.5)Class 1 at (8.5, 2.0)Class 1 at (6.8, 1.8)
Class 0
Class 1
Error
2×2 Confusion Matrix
True Neg (TN)7Class 0 Correct
False Pos (FP)0Type I Error
False Neg (FN)0Type II Error
True Pos (TP)7Class 1 Correct
Inject Failure Scenario:
05

Build It Step-by-Step

The engineering blueprint. Expand each sequential milestone to examine requirements, architectural impacts, common pitfalls, and blueprint pseudocode.

1

Sigmoid & Forward Probability Calculation

Evaluate z = wᵀx + b and compute p = 1 / (1 + exp(-clip(z, -15, 15))). Clipping prevents floating point overflow in exp(-z).

def sigmoid(z):
  z = np.clip(z, -15.0, 15.0)
  return 1.0 / (1.0 + np.exp(-z))
2

Compute Binary Cross-Entropy Loss & Gradients

Remarkably, the gradient of Binary Cross-Entropy with Sigmoid has the exact same clean mathematical form as linear regression: ∇_w L = (1/n) Xᵀ(p - y), where p is predicted probability.

error = probas - y
grad_w = (1.0 / n) * (X.T @ error)
grad_b = (1.0 / n) * np.sum(error)
3

Calculate Confusion Matrix & Derived Metrics

Classify samples with threshold τ: pred = (prob >= threshold). Compute Precision = TP / (TP + FP), Recall = TP / (TP + FN), and F1 = 2·P·R / (P + R).

tp = np.sum((pred == 1) & (y == 1))
fp = np.sum((pred == 1) & (y == 0))
fn = np.sum((pred == 0) & (y == 1))
tn = np.sum((pred == 0) & (y == 0))
4

Tune Decision Threshold for Business Costs

In fraud detection, a False Negative (missing $10,000 fraud) is 100x more costly than a False Positive (sending an SMS verification). Lower τ from 0.5 to 0.15 to maximize Recall at the cost of lower Precision.

06

Code Implementation

Production-ready, idiomatic reference implementations across Go, TypeScript, Python, and Java with sticky language switching, copy-to-clipboard, and source download.

Core Architectural Design Decisions

Invariants & Mechanics
Decision 01

Clamped linear logits z to [-15, 15] to prevent float overflow in exp(-z).

Decision 02

Included configurable decision threshold parameter for cost-sensitive optimization.

Algorithmic Complexity:Training: O(epochs · N · d). Inference: O(d) matrix-vector dot product taking < 20ns.
import numpy as np
from typing import Dict, Tuple

class LogisticRegression:
    """
    Vectorized Binary Logistic Regression using Batch Gradient Descent.
    """
    def __init__(self, lr: float = 0.1, max_iter: int = 500, threshold: float = 0.5):
        self.lr = lr
        self.max_iter = max_iter
        self.threshold = threshold
        self.weights: np.ndarray = None
        self.bias: float = 0.0

    def fit(self, X: np.ndarray, y: np.ndarray) -> "LogisticRegression":
        X = np.asarray(X, dtype=np.float64)
        y = np.asarray(y, dtype=np.float64).reshape(-1, 1)
        n_samples, n_features = X.shape

        self.weights = np.zeros((n_features, 1))
        self.bias = 0.0

        for _ in range(self.max_iter):
            # Forward pass: z = Xw + b, p = sigmoid(z)
            z = (X @ self.weights) + self.bias
            z_clipped = np.clip(z, -15.0, 15.0)
            p = 1.0 / (1.0 + np.exp(-z_clipped))

            # Gradients
            error = p - y
            grad_w = (1.0 / n_samples) * (X.T @ error)
            grad_b = float((1.0 / n_samples) * np.sum(error))

            # Update
            self.weights -= self.lr * grad_w
            self.bias -= self.lr * grad_b

        return self

    def predict_proba(self, X: np.ndarray) -> np.ndarray:
        """Returns calibrated probability P(y=1|x)."""
        z = (X @ self.weights) + self.bias
        z_clipped = np.clip(z, -15.0, 15.0)
        return (1.0 / (1.0 + np.exp(-z_clipped))).ravel()

    def predict(self, X: np.ndarray) -> np.ndarray:
        """Returns discrete binary prediction based on decision threshold."""
        return (self.predict_proba(X) >= self.threshold).astype(np.int32)

    def evaluate(self, X: np.ndarray, y: np.ndarray) -> Dict[str, float]:
        """Computes Precision, Recall, Accuracy, and F1 Score."""
        preds = self.predict(X)
        y_true = np.asarray(y, dtype=np.int32).ravel()

        tp = int(np.sum((preds == 1) & (y_true == 1)))
        fp = int(np.sum((preds == 1) & (y_true == 0)))
        fn = int(np.sum((preds == 0) & (y_true == 1)))
        tn = int(np.sum((preds == 0) & (y_true == 0)))

        acc = (tp + tn) / max(1, len(y_true))
        prec = tp / max(1, (tp + fp))
        rec = tp / max(1, (tp + fn))
        f1 = 2 * (prec * rec) / max(1e-9, (prec + rec))

        return {"accuracy": acc, "precision": prec, "recall": rec, "f1": f1}
Implementation Strategy: High-performance vectorized NumPy implementation. Demonstrates numerical safety via exponential clipping and computes full confusion matrix metrics.
Training: O(epochs · N · d). Inference: O(d) matrix-vector dot product taking < 20ns.
07

Edge Cases & Failure Modes

Investigate real-world production incidents. Expand each failure mode to analyze symptoms, root causes, and defensive engineering mitigations.

Scenario: Extreme Class Imbalance (e.g. 99.9% / 0.1%)
Consequence: Standard loss minimization results in a dummy majority classifier with high accuracy but 0% recall on the rare target class.
Engineering Solution: Use class-weighted loss (scale minority class loss by N_majority / N_minority), tune decision threshold τ, or apply SMOTE / Focal Loss.
Scenario: Linearly Inseparable Data with Bayes Error Overlap
Consequence: True data distributions physically overlap in feature space. No boundary can achieve 100% accuracy without overfitting noise.
Engineering Solution: Accept irreducible Bayes error, engineer non-linear features, or collect additional orthogonal signals that separate the overlapping clusters.
Scenario: Perfect Linear Separation (Separation Invariant)
Consequence: If classes are completely separable, weights w grow toward ±infinity to push Sigmoid outputs to exactly 0 and 1, causing floating-point overflow.
Engineering Solution: Apply L2 regularization (Ridge penalty λ ||w||²) which bounds weight magnitudes strictly.
08

Production Considerations

Production checklist covering observability metrics, horizontal sharding, reliability fail-open patterns, and client identity security.

Scaling to 10x / 100x Traffic:
  • In high-throughput microservices (>50k RPS), precompute logistic weights into fixed-point integer dot products or deploy compiled C++ kernels with AVX-512 vectorization.
  • For KNN on large datasets, replace naive linear scan O(N) with Approximate Nearest Neighbors (ANN) indexing using Hierarchical Navigable Small World (HNSW) graphs (e.g. Faiss / Milvus).
Telemetry & Observability:
PROMETHEUS METRICS:
classifier_prediction_class_distribution{class_id} (counter)
classifier_confidence_histogram (histogram)
classifier_fallback_invocations_total (counter)
DISTRIBUTED TRACES & LOGS:
OpenTelemetry span for 'classifier.score' with duration and predicted category tags.
09

Trade-offs

Select an algorithm below to dynamically compare memory footprints, burst tolerance, boundary precision, and distributed suitability.

ApproachAdvantagesDisadvantagesUse When
Logistic RegressionFastest scoring (<20ns); output calibrated probabilities; highly interpretable coefficients.Cannot model non-linear boundaries or feature interactions without manual feature engineering.Latency-critical API serving and regulated applications requiring auditability.
K-Nearest Neighbors (KNN)Naturally models complex non-linear manifolds; zero training overhead.Extremely slow inference O(N); memory scales with dataset size; fails in high dimensions.Small datasets (<5,000 samples) with non-linear clustering and low inference frequency.
Gradient Boosted Trees (XGBoost / LightGBM)State-of-the-art tabular accuracy; handles missing values and non-linearities automatically.Higher inference latency (~1-5ms); opaque decision structures.Tabular business data where accuracy supersedes sub-microsecond latency.
10

Further Reading

Authoritative industry references, IETF RFC standards, and systems engineering papers.

BOOKChristopher M. Bishop (Pattern Recognition and Machine Learning)

Logistic Regression and Cross-Entropy Optimization

Comprehensive mathematical derivation of logistic models and maximum likelihood.

Read Paper / Source ➔
PAPERHaibo He, Edwardo A. Garcia (IEEE TKDE)

A Survey of Predictive Performance in Class Imbalance

In-depth analysis of Precision, Recall, ROC-AUC, and sampling remedies for imbalanced datasets.

Read Paper / Source ➔