Classical ML Phase B · Lecture 5 of 12
Part II — Linear Models · Lecture 5

Logistic Regression and Softmax

The workhorse classifier, and the one whose mathematics you must own completely — because the output layer of every classification network is exactly this, and its pathologies are the ones you will meet in every training run.

By the end you can

  • Explain why fitting a linear model to \(\{0,1\}\) labels with squared error is the wrong thing
  • Derive the gradient \(\mX^\top(\hat{\vp}-\vy)\) and the Hessian \(\mX^\top\mathbf{S}\mX\)
  • Prove the loss is convex, and say what that buys you
  • Diagnose the separable-data pathology and fix it
  • Separate the model's probability from the decision threshold, and calibrate both

Assumed

  • Phase A, Lecture 5: the chain rule and σ′ = σ(1−σ)
  • Phase A, Lecture 12: gradients, Hessians, the second derivative test
  • Phase B, Lecture 4: losses from likelihoods, the GLM gradient

1Why not just run linear regression on the labels?

You could. Code \(y\in\{0,1\}\) and fit \(\hat y=\vw^\top\vx\) by least squares. Three things go wrong, in increasing order of seriousness.

  1. The output leaves \([0,1]\). Nothing stops \(\hat y = 1.7\) or \(-0.4\). If you wanted a probability you have not got one, and if you clip you have made the model non-differentiable.
  2. The noise model is wrong. \(y\) is Bernoulli, so \(\Var(y\mid\vx)=p(1-p)\) — largest at \(p=\tfrac12\), vanishing at the extremes. Squared error assumes constant variance. Lecture 04's funnel, guaranteed.
  3. Outlying correct points move the boundary. This is the one that really bites. A point deep inside its own class, far from the boundary, has a large residual under squared error (\(\hat y=3\) when \(y=1\)) and therefore a large gradient — so the fit contorts to reduce it, dragging the decision boundary away from where it belongs. A confidently correct point should exert no force at all.
Least squares versus logistic on the same labelsInteractive
least squares fitlogistic fitdatathreshold 0.5
3.0
6
Both models see labels of 0 on the left and 1 on the right. Push the far cluster to the right: these are points the classifier already gets right, with total confidence. The logistic curve does not move. The least-squares line tilts to reduce their large residuals, and its 0.5 crossing — the implied decision boundary — slides right, eventually misclassifying points near the middle that it used to get correct.

2The model

Logistic regression

\[ P(y=1\mid\vx;\vw) = \hat p(\vx) = \sigma\big(\vw^\top\vx\big) = \frac{1}{1+e^{-\vw^\top\vx}}, \qquad y\mid\vx \sim \text{Bernoulli}(\hat p). \]

Equivalently, and more revealingly, the log-odds are linear:

\[ \operatorname{logit}\hat p = \log\frac{\hat p}{1-\hat p} = \vw^\top\vx. \]

The negative log-likelihood is binary cross-entropy:

\[ \mathcal{L}(\vw) = -\sum_{i=1}^{n}\Big[y_i\log\hat p_i + (1-y_i)\log(1-\hat p_i)\Big]. \]

The second form is the honest statement of the modelling assumption. It is not "probability is linear in \(\vx\)" — that would be impossible to keep in \([0,1]\). It is "log-odds are linear in \(\vx\)", and \(\sigma\), being the inverse of the logit (Phase A Lecture 2), converts back. Everything about the model follows from choosing that link.

3The decision boundary

Predict class 1 when \(\hat p\ge\tfrac12\). Since \(\sigma(z)\ge\tfrac12 \iff z\ge0\), the boundary is

\[\{\vx : \vw^\top\vx = 0\}\]

— a hyperplane through the origin (or, with a bias term, an affine hyperplane). Two immediate readings, both worth internalising because they recur in SVMs in Lecture 12:

The boundary, the confidence gradient, and what ‖w‖ controlsInteractive
class 0class 1decision boundaryw (normal vector)
30
2.0
0.00
Background shading is the predicted probability. The boundary is where it passes through 0.5. Turn ‖w‖ down and the transition becomes a gentle gradient — an uncertain model. Turn it up and it becomes a hard edge — a confident one. The BOUNDARY DOES NOT MOVE. Direction sets where the line is, magnitude sets only how sure the model claims to be, and nothing in the accuracy metric can tell them apart.

4The gradient and the Hessian

Differentiating cross-entropy — and the cancellation that makes it work0 / 6
\[\ell_i = -\big[y_i\log \hat p_i + (1-y_i)\log(1-\hat p_i)\big], \qquad \hat p_i=\sigma(z_i),\ z_i=\vw^\top\vx_i\]
One example at a time. We will differentiate through the composition \(\vw\to z\to\hat p\to\ell\) using the chain rule (Phase A Lecture 5).
\[\frac{\partial \ell_i}{\partial \hat p_i} = -\frac{y_i}{\hat p_i}+\frac{1-y_i}{1-\hat p_i} = \frac{\hat p_i-y_i}{\hat p_i(1-\hat p_i)}\]
Outer derivative. Combine over the common denominator: \(-y(1-\hat p)+\hat p(1-y) = -y+y\hat p+\hat p-\hat p y = \hat p-y\). Note the denominator — it is about to be cancelled, and that cancellation is the reason this loss behaves so well.
\[\frac{d\hat p_i}{dz_i} = \sigma'(z_i) = \hat p_i(1-\hat p_i)\]
Sigmoid derivative, from Phase A Lecture 5. The same \(\hat p(1-\hat p)\) that appeared in the denominator above.
\[\frac{\partial\ell_i}{\partial z_i} = \frac{\hat p_i-y_i}{\hat p_i(1-\hat p_i)}\cdot \hat p_i(1-\hat p_i) = \hat p_i - y_i\]
The cancellation. Everything messy disappears and we are left with the raw prediction error. This is not luck — it is the exponential-family theorem of Lecture 04, and it happens precisely because the sigmoid is the canonical link for the Bernoulli.
\[\grad_{\vw}\mathcal{L} = \sum_{i=1}^n (\hat p_i-y_i)\,\vx_i = \mX^\top(\hat{\vp}-\vy)\]
Chain rule once more, with \(\partial z_i/\partial\vw = \vx_i\), and stack. Identical in form to the least-squares gradient. Consequence worth noticing: a confidently correct point has \(\hat p_i\approx y_i\), so it contributes essentially nothing to the gradient — exactly the behaviour that squared error failed to provide in the first figure.
\[\mH = \grad^2\mathcal{L} = \sum_i \hat p_i(1-\hat p_i)\,\vx_i\vx_i^\top = \mX^\top\mathbf{S}\mX, \quad \mathbf{S}=\operatorname{diag}\big(\hat p_i(1-\hat p_i)\big)\]
Differentiate again. \(\frac{\partial}{\partial\vw}(\hat p_i - y_i) = \sigma'(z_i)\vx_i^\top = \hat p_i(1-\hat p_i)\vx_i^\top\), and the outer \(\vx_i\) gives the outer product. Note \(\mathbf{S}\) depends on \(\vw\) — unlike least squares, where the Hessian was the constant \(2\mX^\top\mX\).
Theorem — the loss is convex

\(\mathcal{L}(\vw)\) is convex, and strictly convex if \(\rank(\mX)=d\) and \(0<\hat p_i<1\).

Proof. For any \(\vv\in\RR^d\),

\[ \vv^\top\mH\vv = \vv^\top\mX^\top\mathbf{S}\mX\vv = (\mX\vv)^\top\mathbf{S}(\mX\vv) = \sum_i \hat p_i(1-\hat p_i)\,(\mX\vv)_i^2 \;\ge\; 0, \]

since \(\hat p_i\in(0,1)\) makes every weight \(\hat p_i(1-\hat p_i)>0\) and every square non-negative. So \(\mH\succeq0\) everywhere and by Phase A Lecture 12, \(\mathcal{L}\) is convex. If \(\mX\) has full column rank then \(\mX\vv\neq\vzero\) for \(\vv\neq\vzero\), making the sum strictly positive and the loss strictly convex. ∎

Where this shows up in ML

Convexity is why logistic regression is a solved problem in a sense that neural networks are not. There is one basin. Gradient descent with a sensible step size finds the global optimum, the answer does not depend on initialisation or random seed, and there is no "try more seeds".

Note precisely where it comes from: the loss is convex in \(\vw\) because \(z=\vw^\top\vx\) is linear in \(\vw\) and cross-entropy is convex in \(z\). Replace the linear map with a neural network and the composition is no longer convex — composition does not preserve convexity (Phase A Lecture 7). The output layer of a classification network is logistic/softmax regression; it is everything underneath that destroys the guarantee.

5The separability pathology

Phase A Lecture 7's exercise 4 showed that for a single separable point the logistic loss has no minimiser. The same holds in general, and it is common enough in practice that you must recognise it.

Theorem — no MLE on separable data

If there exists \(\vw_0\) with \(\vw_0^\top\vx_i>0\) for every \(i\) with \(y_i=1\) and \(\vw_0^\top\vx_i<0\) for every \(i\) with \(y_i=0\) (the classes are linearly separable), then \(\mathcal{L}\) has no finite minimiser.

Proof. Consider \(\vw = c\,\vw_0\) for \(c>0\). For a positive example, \(\hat p_i = \sigma(c\,\vw_0^\top\vx_i)\to1\) as \(c\to\infty\), since \(\vw_0^\top\vx_i>0\); for a negative example \(\hat p_i\to0\). Hence every term of \(\mathcal{L}\) tends to \(0\), so \(\mathcal{L}(c\vw_0)\to0\). But \(\mathcal{L}>0\) strictly for any finite \(\vw\), because \(\hat p_i\in(0,1)\) always. So the infimum \(0\) is approached and never attained: the optimiser drives \(\|\vw\|\to\infty\). ∎

What you observe: training loss creeping towards zero while \(\|\vw\|\) grows without bound; the model reporting probabilities of 0.99999 for everything; wild sensitivity to a single data point near the boundary; and coefficients that are meaningless. Separability is more likely, not less, when \(d\) is large relative to \(n\) — in high dimensions almost any labelling is separable.

Watching ‖w‖ diverge — and regularisation stopping itInteractive
‖w‖, unregularised‖w‖, with L2training loss, unregularisedtraining loss, with L2
1.50
-2.00
2000
With a positive gap the classes are separable and the blue ‖w‖ climbs without limit — it is still climbing at step 4000, and would still be climbing at step 4,000,000. Its loss approaches zero, which looks like success and is not. Drag the gap negative so the classes overlap and the blue curve settles: an MLE now exists. The purple regularised run always settles, whatever the gap.

6Probabilities and decisions are different things

The model outputs \(\hat p\). Turning that into an action requires a threshold, and \(0.5\) is a choice, not a law. It is the right choice only when false positives and false negatives cost the same and the classes are balanced — which is almost never.

The cost-optimal threshold0 / 3
\[\text{cost of predicting 1} = (1-\hat p)\,C_{\text{FP}}, \qquad \text{cost of predicting 0} = \hat p\,C_{\text{FN}}\]
Expected cost of each action. If we predict 1, we are wrong with probability \(1-\hat p\), incurring the false-positive cost. If we predict 0, we are wrong with probability \(\hat p\).
\[\text{predict } 1 \iff (1-\hat p)C_{\text{FP}} < \hat p\, C_{\text{FN}}\]
Choose the cheaper action. This is decision theory in one line: minimise expected cost, not error rate.
\[\boxed{\ \hat p \;>\; \frac{C_{\text{FP}}}{C_{\text{FP}}+C_{\text{FN}}}\ }\]
Rearrange. Equal costs give the familiar \(0.5\). If missing a positive is 9× worse than a false alarm (\(C_{\text{FN}}=9C_{\text{FP}}\)) the threshold drops to \(0.1\) — you should act on much weaker evidence. The threshold depends only on the costs, not on the class balance. Class imbalance affects the probabilities the model outputs, not the threshold you should apply to them.
Common trap

This is why rebalancing your training data is usually the wrong fix for class imbalance. Oversampling the minority class distorts \(\hat p\) away from the true posterior, so your model no longer outputs probabilities you can reason about. If you have a well-calibrated model, the imbalance problem is entirely handled by moving the threshold — a decision you make afterwards, at zero cost, and can change without retraining.

(There are legitimate reasons to resample: extreme imbalance can make optimisation difficult, and some losses genuinely need it. But do it knowingly, and correct the probabilities afterwards — for a prior shift from \(\pi\) to \(\pi'\), the correction to the odds is a factor of \(\frac{\pi'/(1-\pi')}{\pi/(1-\pi)}\).)

Check yourself
Your fraud classifier has 99.2% accuracy. Fraud occurs in 0.5% of transactions. Is the model good?
Correct. Correct, and the comparison to the trivial baseline is the first thing to compute for any imbalanced problem. Predicting the majority class always gives 99.5% accuracy while catching zero fraud, so 99.2% means the model is actively worse than doing nothing by that metric.

What to report instead: precision and recall at your operating threshold, the precision-recall curve (not ROC — with 0.5% positives, ROC-AUC looks impressive while precision is terrible), and expected cost using your actual \(C_{\text{FP}}\) and \(C_{\text{FN}}\).

And note the base-rate connection. Phase A Lecture 14: even a very good detector produces mostly false positives when the base rate is 0.5%, because the 99.5% of legitimate transactions vastly outnumber the fraudulent ones. If your review team can handle 100 alerts a day, the question is not "accuracy" but "what fraction of the top 100 scored transactions are actually fraud" — precision at \(k\).
Not quite. Accuracy is meaningless without the base rate to compare it against. Always compute the majority-class baseline first. Here it is 99.5%, so the model is below it. A metric that a constant function beats is not measuring what you care about.
Not quite. Rebalancing addresses a symptom and creates a new problem: the model's output probabilities are now calibrated to a 50/50 world that does not exist, so \(\hat p = 0.6\) no longer means anything about the real likelihood of fraud. The direct fix is to keep the true class balance, get calibrated probabilities, and then choose the threshold from the costs — as derived above. Resampling is a tool for optimisation difficulties, not a substitute for decision theory.
Logistic regression from scratch, with Newton's method and a calibration checkPython · NumPy

7Exercises

★

A logistic model gives \(\hat p = \sigma(0.5 + 1.2x_1 - 0.8x_2)\).

  1. Where is the decision boundary, as an equation in \(x_1,x_2\)?
  2. Interpret the coefficient \(1.2\) precisely.
  3. If \(x_1\) increases by 1 with \(x_2\) fixed, by what factor do the odds change?
  4. At \(x_1=x_2=0\), what is \(\hat p\)? What if we double every coefficient?

1. \(0.5+1.2x_1-0.8x_2=0\), i.e. \(x_2 = \frac{0.5+1.2x_1}{0.8} = 0.625+1.5x_1\). A straight line with the normal vector \(\vw=(1.2,-0.8)\) pointing towards the positive class.

2. Holding \(x_2\) fixed, a one-unit increase in \(x_1\) increases the log-odds by 1.2. It does not increase the probability by any fixed amount — the effect on \(\hat p\) depends on where you start, being largest near \(\hat p=0.5\) (where \(\sigma'\) peaks at 0.25) and negligible in the tails. This is why "a one-unit change in \(x_1\) raises the probability by 30%" is almost always a misstatement.

3. Log-odds increase by 1.2, so the odds multiply by \(e^{1.2}=3.32\). Odds ratios are the natural currency of logistic regression precisely because they are constant across the range, unlike probability differences. If the odds were 1:4 (\(\hat p = 0.2\)) they become 3.32:4, i.e. \(\hat p=0.454\).

4. \(\hat p=\sigma(0.5)=0.6225\). Doubling everything gives \(\sigma(1.0)=0.7311\).

The boundary does not move — \(2(0.5+1.2x_1-0.8x_2)=0\) has exactly the same solution set — but every prediction becomes more extreme. Accuracy is unchanged; cross-entropy and calibration change completely. That is the \(\|\vw\|\) effect from the second figure, and it is why regularisation on \(\|\vw\|\) is a statement about confidence, not about the decision rule.

★★

Show that at the optimum of unregularised logistic regression with an intercept, the average predicted probability equals the observed base rate: \(\frac1n\sum_i\hat p_i = \frac1n\sum_i y_i\).

What is the analogous statement for each non-intercept feature? Why does this make logistic regression "self-calibrating", and why does adding L2 regularisation break it?

Proof. At the optimum \(\grad\mathcal{L}=\mX^\top(\hat{\vp}-\vy)=\vzero\), i.e. the residual vector \(\hat{\vp}-\vy\) is orthogonal to every column of \(\mX\). Applying this to the intercept column \(\mathbf{1}\):

\[\mathbf{1}^\top(\hat{\vp}-\vy) = \sum_i(\hat p_i-y_i) = 0 \;\Longrightarrow\; \frac1n\sum_i\hat p_i = \frac1n\sum_i y_i. \qquad\blacksquare\]

Exactly the structure of "residuals sum to zero" for OLS (Lecture 02, exercise 2) — same normal equations, same consequence.

For a general feature \(j\): \(\sum_i x_{ij}\hat p_i = \sum_i x_{ij}y_i\). The probability-weighted total of feature \(j\) matches its label-weighted total. For a binary feature this says within that subgroup, average predicted probability equals the observed rate — calibration holds within every group defined by a feature in the model.

Why "self-calibrating". Calibration in the aggregate is not something you have to check for — it is forced by the first-order conditions, on the training set, for every direction the model can see. This is a real advantage of logistic regression over, say, an SVM or a boosted tree, whose raw scores have no such guarantee and genuinely need a post-hoc Platt scaling or isotonic step.

Two caveats. It holds on training data, not automatically on test data — though for a well-specified model with enough data the two agree. And it holds only in directions spanned by the features: a subgroup not encoded as a feature can be badly miscalibrated while every aggregate looks perfect. That is precisely the mechanism behind many fairness failures.

Why L2 breaks it. The regularised optimality condition is \(\mX^\top(\hat{\vp}-\vy) + \lambda\begin{bmatrix}0\\ \vw_{1:}\end{bmatrix} = \vzero\). The intercept row is unpenalised, so \(\sum_i(\hat p_i - y_i)=0\) survives — aggregate calibration is preserved. But the feature rows now read \(\sum_i x_{ij}(\hat p_i-y_i) = -\lambda w_j \neq 0\), so per-feature calibration is deliberately sacrificed. The shrinkage pulls predictions towards \(\hat p = \sigma(w_0)\), making the model systematically under-confident. Usually a good trade; worth knowing you made it.

This also explains why you should never regularise the intercept. Doing so would break aggregate calibration too, biasing every prediction towards \(0.5\) for no benefit.

★★

Derive the softmax gradient. With \(\vz=\mW\vx\), \(\hat\pi_k = e^{z_k}/\sum_j e^{z_j}\) and cross-entropy \(\ell=-\sum_k y_k\log\hat\pi_k\) for one-hot \(\vy\):

  1. Show \(\dfrac{\partial\hat\pi_k}{\partial z_m} = \hat\pi_k(\delta_{km}-\hat\pi_m)\).
  2. Show \(\dfrac{\partial\ell}{\partial z_m} = \hat\pi_m - y_m\).
  3. Show that adding any constant \(c\) to every \(z_k\) leaves \(\hat{\boldsymbol\pi}\) unchanged, and say what that means for the number of free parameters.

1. Write \(S=\sum_j e^{z_j}\), so \(\hat\pi_k = e^{z_k}/S\) and \(\partial S/\partial z_m = e^{z_m}\). Quotient rule:

\[\frac{\partial\hat\pi_k}{\partial z_m} = \frac{\delta_{km}e^{z_k}S - e^{z_k}e^{z_m}}{S^2} = \frac{e^{z_k}}{S}\left(\delta_{km}-\frac{e^{z_m}}{S}\right) = \hat\pi_k(\delta_{km}-\hat\pi_m). \qquad\blacksquare\]

(\(\delta_{km}=1\) if \(k=m\), else 0.) Note this is the softmax Jacobian \(\operatorname{diag}(\hat{\boldsymbol\pi})-\hat{\boldsymbol\pi}\hat{\boldsymbol\pi}^\top\), which is symmetric positive semi-definite with the all-ones vector in its null space — the redundancy of part 3, in matrix form.

2. Chain rule through every \(k\):

\[\frac{\partial\ell}{\partial z_m} = -\sum_k \frac{y_k}{\hat\pi_k}\cdot\hat\pi_k(\delta_{km}-\hat\pi_m) = -\sum_k y_k(\delta_{km}-\hat\pi_m) = -y_m + \hat\pi_m\sum_k y_k = \hat\pi_m - y_m,\]

using \(\sum_k y_k=1\) for a one-hot target. ∎ The \(\hat\pi_k\) cancels exactly, as in the binary case, and for the same exponential-family reason.

3. Replacing \(z_k\) with \(z_k+c\):

\[\frac{e^{z_k+c}}{\sum_j e^{z_j+c}} = \frac{e^c e^{z_k}}{e^c\sum_j e^{z_j}} = \hat\pi_k.\]

Softmax is shift-invariant, hence not injective — the observation from Phase A Lecture 1, now proved.

Consequences. With \(K\) classes there are only \(K-1\) free directions: the loss has a flat direction along \(\vw_1=\cdots=\vw_K\), so the Hessian is singular and the MLE is not unique. You can fix the redundancy by setting \(\vw_K=\vzero\) (which recovers binary logistic regression exactly when \(K=2\)), or simply leave it — L2 regularisation selects the minimum-norm representative, and gradient descent from zero initialisation never leaves the identifiable subspace anyway.

The practical payoff is the numerical one: shift-invariance lets you subtract \(\max_k z_k\) before exponentiating, which is exactly the log-sum-exp trick and is what makes softmax safe for large logits (Phase A Lecture 2).

★★★

Coding. Investigate calibration under three kinds of stress.

  1. Fit a well-specified logistic model and produce a reliability diagram plus the expected calibration error (ECE). Confirm it is well calibrated.
  2. Now misspecify: generate data with a quadratic true boundary and fit a linear model. What happens to calibration, and is it worse than the accuracy drop would suggest?
  3. Now over-regularise (\(\lambda = 100\)). Which direction does the miscalibration go, and why?
  4. Implement Platt scaling — fit \(\hat q = \sigma(a\,\text{logit}(\hat p)+b)\) on a held-out set — and show it repairs cases 2 and 3. What can it not repair?
import numpy as np
rng = np.random.default_rng(0)
sig = lambda z: 1/(1+np.exp(-np.clip(z,-500,500)))

def fit(X, y, lam=1e-6, T=30000, lr=0.05):
    w = np.zeros(X.shape[1])
    for _ in range(T):
        g = X.T @ (sig(X@w) - y) / len(y)
        g[1:] += lam*w[1:]
        w -= lr*g
    return w

def ece(p, y, B=10):
    e, idx = 0.0, np.clip(np.digitize(p, np.linspace(0,1,B+1))-1, 0, B-1)
    for b in range(B):
        m = idx==b
        if m.sum(): e += m.sum()/len(y)*abs(p[m].mean()-y[m].mean())
    return e

def make(kind, n):
    Z = rng.normal(size=(n,2))
    X = np.column_stack([np.ones(n), Z])
    z = 1.5*Z[:,0] - 2*Z[:,1] + 0.3 if kind=="linear" else 2.0*(Z[:,0]**2 + Z[:,1]**2 - 1.6)
    return X, (rng.random(n) < sig(z)).astype(float)

for kind in ("linear", "quadratic"):
    Xtr, ytr = make(kind, 4000); Xte, yte = make(kind, 8000)
    for lam, tag in ((1e-6, "unreg"), (100.0, "lam=100")):
        w = fit(Xtr, ytr, lam)
        p = sig(Xte@w)
        acc = ((p>=0.5)==yte).mean()
        print(f"{kind:10s} {tag:8s} acc {acc:.4f}  ECE {ece(p,yte):.4f}  "
              f"mean p {p.mean():.4f} vs base rate {yte.mean():.4f}  "
              f"p range [{p.min():.3f},{p.max():.3f}]")

# Platt scaling on a calibration split
Xtr, ytr = make("quadratic", 4000); Xca, yca = make("quadratic", 4000)
Xte, yte = make("quadratic", 8000)
w = fit(Xtr, ytr)
lg = lambda p: np.log(np.clip(p,1e-9,1-1e-9)/np.clip(1-p,1e-9,1))
Zc = np.column_stack([np.ones(len(yca)), lg(sig(Xca@w))])
ab = fit(Zc, yca, lam=1e-8)
p_raw = sig(Xte@w)
p_cal = sig(ab[0] + ab[1]*lg(p_raw))
print(f"\\nquadratic, raw    ECE {ece(p_raw,yte):.4f}  acc {((p_raw>=.5)==yte).mean():.4f}")
print(f"quadratic, Platt  ECE {ece(p_cal,yte):.4f}  acc {((p_cal>=.5)==yte).mean():.4f}")
print("Platt parameters a, b =", np.round(ab[::-1], 4))

1. The well-specified linear case gives ECE around \(0.005\) — essentially perfect, for the reason proved in exercise 2: the first-order conditions force it.

2. The quadratic truth with a linear model is a disaster, and much worse than accuracy suggests. The true boundary is a circle; the best linear separator is nearly useless, so accuracy lands near the base rate. But the calibration failure is qualitatively different: the model has no direction in which it can express the real structure, so its predicted probabilities collapse into a narrow band around the base rate. It is simultaneously uninformative and, in the aggregate, still calibrated — because the intercept condition still holds. Aggregate calibration and usefulness are independent properties: a model that always outputs the base rate is perfectly calibrated and worthless. This is why ECE alone is never sufficient; report a proper scoring rule (log loss or Brier score), which penalises both miscalibration and lack of resolution.

3. With \(\lambda=100\) the coefficients are crushed towards zero, so \(\hat p\to\sigma(w_0)\approx\) the base rate, and the predicted range narrows drastically (something like \([0.42,0.58]\) instead of \([0.01,0.99]\)). The model is under-confident — it never commits. Aggregate ECE may still look small because the mean is right; the failure is in the spread.

4. Platt scaling fits a one-dimensional logistic recalibration on the model's own logit, using a held-out split (using the training split would fit \(a=1,b=0\) and do nothing). It repairs case 3 essentially completely — the fitted \(a\) comes out well above 1, undoing the shrinkage — and improves case 2's calibration.

What it cannot repair: Platt scaling is a monotone transformation of the score, so it cannot change the ranking of examples, and therefore cannot change accuracy, AUC, or which points fall on which side of any given quantile. If the model's ordering is wrong — as it is for the quadratic case, where the linear score is nearly uninformative — no post-hoc calibration can help. Calibration fixes the numbers, never the model. The fix for case 2 is to add quadratic features, i.e. change the inductive bias.


Next: we have used L2 regularisation three times now as a patch. Lecture 06 gives it a proper treatment — ridge, LASSO and elastic net as MAP estimates, the geometry of sparsity, and the regularisation path.