Linear & Logistic Regression with Gradient Descent

The foundation of machine learning. Learn linear regression (model, mean squared error, closed-form least squares), gradient descent (gradients, learning rate, convergence, batch/mini-batch/stochastic), feature scaling, polynomial features, regularisation (L2 ridge, L1 lasso), logistic regression for classification (sigmoid, log-loss/cross-entropy, decision boundary, probability calibration), softmax for multiclass — with runnable NumPy code implementing both models from scratch and checking against least squares.

Linear models are simple, fast and interpretable — and they introduce every core idea of ML: a parametric model, a loss function, and an optimiser that adjusts parameters to reduce loss.

Neural networks are essentially stacks of linear models with non-linear activations, trained with exactly the same gradient-descent idea.

An analogy

Gradient descent is like walking downhill in fog: you can't see the valley, but you can feel the slope under your feet and take a step downhill. The learning rate is your step size — too small and you crawl, too large and you overshoot and bounce around.

Fitting a line

Linear regression finds the line (or hyperplane) that minimises the average squared distance to the data points. Squared error penalises big mistakes heavily and gives a smooth bowl-shaped loss with a single minimum, which can be solved exactly (normal equation) or iteratively (gradient descent).

Gradient descent in practice

Key choices:

Logistic regression

For classification, pass the linear score through a sigmoid to get a probability; train with log-loss (cross-entropy), whose gradient is simply (p − y)·x. The decision boundary wx + b = 0 is linear; non-linear boundaries need feature engineering (polynomials, interactions) or non-linear models. Softmax generalises to many classes.

Regularisation and interpretation

With many features, models overfit; ridge (L2) shrinks weights smoothly, lasso (L1) drives some to exactly zero (feature selection), elastic net combines both. Coefficients are interpretable (effect per unit of feature, or log-odds for logistic) — valued in finance, medicine and policy. Watch for multicollinearity, outliers (use Huber loss), and non-linearity (check residual plots). Generalised linear models extend to counts (Poisson) and more.

Formulas

Worked example: One gradient step

Given: x = 2, y = 7, w = 1, b = 0, η = 0.1 (single sample, MSE)

Find: New w.

Answer: w = 3

Worked example: Sigmoid

Given: z = 0.42 + 3.5 × 0.5

Find: p.

Answer: 0.897

Worked example: Log-loss

Given: y = 1, p = 0.9

Find: Loss.

Answer: 0.105 (p = 0.1 would give 2.30)

Linear and logistic regression from scratch

import numpy as np
# Linear regression by gradient descent, then logistic regression for classification
rng = np.random.default_rng(0)
X = rng.uniform(0, 10, 100)
y = 3.0 * X + 5.0 + rng.normal(0, 2.0, 100)
w, b, lr = 0.0, 0.0, 0.01
for epoch in range(2000):
    pred = w * X + b
    err = pred - y
    w -= lr * 2 * np.mean(err * X)
    b -= lr * 2 * np.mean(err)
mse = np.mean((w * X + b - y) ** 2)
print(f"gradient descent: w = {w:.3f}, b = {b:.3f}, MSE = {mse:.2f}")
A = np.c_[X, np.ones_like(X)]
print("closed form (least squares):", np.round(np.linalg.lstsq(A, y, rcond=None)[0], 3))
# Logistic regression on a 1-D problem
Xc = rng.normal(0, 1, 200); yc = (Xc + rng.normal(0, 0.5, 200) > 0).astype(float)
wc, bc = 0.0, 0.0
for _ in range(3000):
    p = 1 / (1 + np.exp(-(wc * Xc + bc)))
    wc -= 0.1 * np.mean((p - yc) * Xc); bc -= 0.1 * np.mean(p - yc)
acc = np.mean(((1 / (1 + np.exp(-(wc * Xc + bc)))) > 0.5) == yc)
print(f"logistic: w = {wc:.2f}, b = {bc:.2f}, training accuracy {acc:.3f}")
# gradient descent: w = 2.974, b = 4.985, MSE = 3.76
# closed form (least squares): [2.974 4.985]
# logistic: w = 3.50, b = 0.42, training accuracy 0.865

Gradient descent recovers the true slope (3) and intercept (5) within noise and matches the exact least-squares solution. MSE ≈ 3.76 is close to the noise variance (2² = 4) — the irreducible error. The logistic model learns a steep sigmoid; 86.5% accuracy reflects the label noise built into the data.

Common mistakes

Applications

Key takeaways

Going further