~/blog

Logistic Regression: Math Intuition

Jun 26, 202612 min readBy Mohammed Vasim
Machine LearningAIData Science

You're a loan officer who just learned that linear regression can't produce valid probabilities for classification. The fix is a function called the sigmoid — but the story doesn't end there. Once you replace the linear output with , you need a new loss function (MSE doesn't work for probabilities), a new way to interpret the coefficients (log-odds rather than raw scores), and a gradient that connects all the pieces. Each piece has a formula, and each formula has a concrete number attached to it.

This post traces the full path from raw score to gradient update on six loan applications. Every formula lands on a specific number from this dataset — nothing is symbolic.

What Logistic Regression Does

Logistic regression takes a linear score and passes it through the sigmoid function to produce a probability. The coefficients are interpreted in log-odds: a unit change in a feature multiplies the odds of the outcome by . The loss function — binary cross-entropy — penalizes wrong confidence, not wrong predictions. And the gradient of this loss with respect to the weights has exactly the same form as linear regression's gradient, but with probabilities in place of raw predictions.

The Plan — Four Steps from Linear Score to Gradient Update

We'll start with a single linear score and convert it to a probability using the sigmoid. We'll reinterpret that probability as log-odds to understand what the coefficients mean. We'll compute the cross-entropy loss to see why MSE is wrong. And finally we'll run one gradient descent step to see how the weights update. Each step is computed on the same six samples.


Anchor dataset: Loan default prediction (6 samples for hand-trace clarity).

python
import numpy as np

X = np.array([25, 32, 45, 75, 95, 110]).reshape(-1, 1)
y = np.array([1,   1,  1,  0,  0,   0])

# Weights after fitting (used for trace — not starting weights):
# w₀ = 8.12, w₁ = -0.094

Step 1: Linear Score → Sigmoid → Probability

The raw linear score is computed the same way as in linear regression:

The sigmoid function converts this to a probability:

The model predicts , which is the probability of default given income.

Trace for all 6 samples with , :

IncomePredicted
258.12 − 2.35 = 5.77 = 0.99711 ✓
328.12 − 3.01 = 5.11 = 0.99411 ✓
458.12 − 4.23 = 3.89 = 0.98011 ✓
758.12 − 7.05 = 1.07 = 0.74510 ✗
958.12 − 8.93 = −0.81 = 0.30700 ✓
1108.12 − 10.34 = −2.22 = 0.09800 ✓

At decision threshold 0.5: income = 75 gives — predicted as default (wrong). These weights are illustrative; the true MLE solution would correctly separate this dataset.

z (linear score) σ(z) = P(y=1) 0.5 0 1 0 25k 32k 45k 75k 95k 110k decision boundary σ = 0.5

Green dots are correctly classified; the red dot at income=75k sits above the 0.5 line but is a non-defaulter (y=0). The S-shape ensures all outputs stay within (0, 1).

Step 1 complete. The linear score ranges from 5.77 (income=25k) to −2.22 (income=110k). After sigmoid, each maps to a valid probability in . The S-shaped curve guarantees that no input produces an output outside the probability range.

Step 2: Log-Odds (Logit) Interpretation

The ratio of default probability to non-default probability is the odds:

Taking the log of odds recovers the linear score exactly:

The log-odds (logit) is linear in the features. This means logistic regression is a linear model — it draws a straight boundary in feature space — just applied to log-odds rather than probability directly.

Log-odds trace for 3 anchor samples:

IncomeOdds
250.9970.003332.3
750.7450.2552.92
1100.0980.9020.109

Interpreting : Each additional $1k in income changes the log-odds of default by . In odds terms, it multiplies the odds of default by:

A 9% reduction in the odds of default for each $1k of additional income.

Income ($k) log-odds = z 0 +6 −3 25 75 110 z=5.77 (default) z=1.07 (boundary zone) z=−2.22 (no default) decision boundary (z=0)

Log-odds is linear in income. The boundary income (z=0) is where the line crosses zero — every sample to the left has positive log-odds (predicted default), every sample to the right has negative log-odds (predicted no default).

Step 2 complete. The log-odds equals the linear score : . Each additional e^{-0.094} = 0.91$ — a 9% reduction per unit. Logistic regression IS a linear model in log-odds space.

Step 3: Binary Cross-Entropy Loss

Why not MSE? Consider predicting with (correct, very confident). MSE loss = — nearly zero. Now predict with (correct, barely). MSE = . The nearly-random prediction is penalized 250,000× more than the confident correct one — backward.

Binary cross-entropy (BCE) penalizes wrong confidence, not wrong predictions:

Three cases:

  • Correct and confident: , (tiny)
  • Correct and unconfident: , (meaningful signal)
  • Wrong and confident: , (large penalty, )

Per-sample loss for the 6-sample anchor:

Income
2510.997
3210.994
4510.980
7500.745
9500.307
11000.098
Avg loss

The sample at income=75 dominates the loss (1.367) because the model is confidently wrong: it predicts (likely default) for a non-defaulter. This is exactly where gradient descent will push the decision boundary.

Loss when y=1 Loss when y=0 p (predicted probability) p (predicted probability) 0 1 0 1 -log(p) low loss high loss →∞ -log(1-p) low loss high loss →∞

Left panel (): loss approaches infinity as (confidently wrong). Right panel (): loss approaches infinity as . In both cases, confident correct predictions have loss near zero.

Step 3 complete. Binary cross-entropy penalizes wrong confidence, not wrong predictions. The sample at income=75k dominates the total loss (1.367 of 0.311 average) because the model is confidently wrong — exactly where the gradient needs to push hardest.

Step 4: Gradient Descent Update

The total cost over samples:

The gradients work out elegantly — the same form as linear regression but with sigmoid probabilities:

One gradient step from , , :

With all weights zero: for every sample, so .

Prediction errors :

Income
250.51−0.5
320.51−0.5
450.51−0.5
750.50+0.5
950.50+0.5
1100.50+0.5

Computing gradients:

Weight updates:

The gradient is zero because the dataset is balanced (3 defaulters, 3 non-defaulters) — symmetry cancels. The gradient is positive (14.83) because higher incomes are associated with non-default (), so the gradient pushes negative — exactly right. After this one step, the model already knows to decrease as income increases.

Income ($k) P(default) 0.5 1.0 0.0 Before: w₁=0, P=0.5 for all income After: w₁=−0.148 P decreases with income 25 45 75 95 110

Before (flat line): all probabilities = 0.5, model has no information. After one step: the curve tilts — low income → higher P(default), high income → lower P(default). The direction is correct on step one.

Step 4 complete. From with all , one gradient step gives . The negative already knows that higher income should decrease default probability — correct direction from a single update.

Key Formulas Reference

StepFormulaPurpose
Linear scoreRaw activation
SigmoidMaps probability
Log-oddsLinear interpretation
Per-sample lossPenalizes wrong confidence
GradientSame form as linear regression

The BCE gradient has exactly the same structure as the OLS gradient for linear regression — the only difference is (from sigmoid) instead of (from the linear prediction). This is not a coincidence: both emerge from the chain rule applied through the output activation. Understanding this post requires comfort with the chain rule and what makes a function convex. It unlocks regularization (appending to adds to each gradient), multiclass softmax (the same BCE structure generalizes to classes), and neural network training (replace sigmoid with other activations, BCE becomes cross-entropy over softmax output).

Honest Limitations

At initialization , every sample has . Gradient descent is guaranteed to find the global minimum because BCE is convex in the weights — the loss surface has no local minima. This property disappears the moment you stack layers: a two-layer network with sigmoid activations is no longer convex. A second limitation: MLE for logistic regression does not have a finite solution when the data is perfectly linearly separable. The weights diverge toward infinity, trying to push all probabilities to exactly 0 or 1. sklearn's default L2 regularization (C=1.0) prevents divergence by adding a penalty, but it changes the optimization from pure MLE to a penalized version — the resulting weights are biased toward zero.

Test Your Understanding

  1. The gradient at initialization because the dataset is balanced. If you added one more defaulter (making 4 defaulters, 3 non-defaulters), what sign would have, and what does that mean for 's update?

  2. At income=75, the loss is 1.367 — the largest single-sample loss. After one gradient step (), compute the new for income=75 and the new . Did the loss for this sample decrease?

  3. The gradient of BCE with respect to weights has the form — identical in structure to the linear regression gradient. Why does the same form emerge from a completely different loss function?

  4. At (the approximate fitted weights), the decision boundary (income where ) is at . Compute this boundary income value. Does it match your intuition from the data?

  5. The log-odds interpretation says each $1k income multiplies the odds of default by . If income doubles from 50 to 100, what is the ratio of the odds at 100 to the odds at 50?

Comments (0)

No comments yet. Be the first to comment!

Leave a comment