#358Platt ScalingMedium

Platt Scaling

Background

Post-hoc calibration via Platt scaling fits a 2-parameter logistic on top of raw model scores so the resulting probabilities match observed frequencies. It is the cheapest, most-cited fix for the canonical "AUC is great but the probabilities are wrong" failure mode: held-out scores in, calibrated probabilities out, no retrain.

Problem statement

Implement platt_fit(scores, labels, n_iter=500, lr=0.5) that fits parameters (a,b)(a, b) minimising binary cross-entropy:

p^i  =  σ(asi+b),L(a,b)  =  1Ni[yilnp^i+(1yi)ln(1p^i)]\hat{p}_i \;=\; \sigma(a\,s_i + b), \qquad \mathcal{L}(a, b) \;=\; -\frac{1}{N}\sum_i \bigl[y_i \ln \hat{p}_i + (1 - y_i)\ln(1 - \hat{p}_i)\bigr]

via gradient descent. Return (a, b) as two Python floats. Initialise (a,b)=(1,0)(a, b) = (1, 0).

Input

  • scores - array-like of floats, raw model scores (any real range).
  • labels - array-like of {0,1}\{0, 1\}, same length as scores.
  • n_iter - int, gradient steps (default 500500).
  • lr - float, learning rate (default 0.50.5).

Output

  • (a, b) - tuple of plain Python floats.

Examples

Example 1 - perfectly separable labels -> large |a|, b shifts to threshold

Input:  scores = [-3, -2, -1, 1, 2, 3], labels = [0, 0, 0, 1, 1, 1]
Output: (a, b) such that sigmoid(a*s + b) ~= labels

Constraints

  • scores and labels must be the same length, length 2\ge 2.
  • Use the numerically stable sigmoid for negative arguments: 1 - sigmoid(-z) for z<0z < 0, or equivalently np.where(z >= 0, 1/(1+exp(-z)), exp(z)/(1+exp(z))). Tests use long-tailed scores that overflow naive exp.
  • Tests check that after fitting, the mean of p^\hat{p} matches the mean of yy to within 0.050.05 and that the predictions correctly order the classes on the separable example.

Notes

  • Why (1,0)(1, 0) init. Starting at the identity (a=1,b=0a = 1, b = 0) means the first iteration's gradient is dominated by the score-label mismatch, not by an arbitrary scale.
  • Newton vs gradient descent. Production Platt fits use a Newton step (the Hessian is 2x2 and trivially invertible) - convergence in 5-10 iterations vs hundreds for plain GD. The contract here uses GD for clarity; the variants section names Newton as the upgrade.
Python
Loading...

▶ Run executes the 3 visible sample tests below in your browser. Submit runs the full suite — including hidden tests — on the server for an official verdict.

  • Example: separable data fit parameters
  • Reference: mixed labels fit parameters
  • Sample: five-point fit parameters