Expected Calibration Error (ECE)
Background
A model's predicted probabilities are calibrated when they match observed frequencies — among the predictions it gives confidence 0.7, 70% should turn out to be positive. Modern neural networks are often accurate but badly miscalibrated: their AUC is great while their probabilities are systematically too high (or too low). That gap matters for downstream auctions, multi-task fusion, and A/B test interpretation — every system that uses the probability, not just the ranking, breaks when calibration drifts. Expected Calibration Error (ECE) is the standard scalar measure of that gap.
Problem statement
Implement expected_calibration_error(probs, labels, n_bins=10). Bin the predicted probabilities into n_bins equal-width bins over , then for each non-empty bin compute the absolute gap between empirical positive rate () and average predicted probability (), and take the sample-weighted average:
where is the -th bin, is the number of predictions in that bin, is the mean of the binary labels in the bin, and is the mean of the predicted probabilities in the bin.
Input
probs— array-like of floats in , the predicted probability of the positive class (length ).labels— array-like of ground-truth labels, same length asprobs.n_bins—int, number of equal-width bins on (default ).
Output
Returns a Python float in — the expected calibration error. Empty bins contribute (they are skipped, not divided by zero).
Examples
Example 1 — perfectly calibrated
Input: probs = [0.5, 0.5], labels = [0, 1], n_bins = 10
Output: 0.0
Explanation: both predictions land in bin 5. Empirical positive rate exactly matches average confidence , so the gap is .
Example 2 — hand-computed two-bin case
Input: probs = [0.2, 0.3, 0.7, 0.8], labels = [0, 1, 0, 1], n_bins = 2
Output: 0.25
Explanation: bin 0 has with labels : , , contribution . Bin 1 has with labels : , , contribution . Total .
Example 3 — worst-case overconfidence
Input: probs = [0.9, 0.9, 0.9, 0.9], labels = [0, 0, 0, 0], n_bins = 10
Output: 0.9
Explanation: all four predictions fall in bin 9. , , contribution .
Constraints
- Bins are equal width on : bin covers , except the last bin which is closed on the right so lands in bin (no
IndexError). - Empty bins contribute — skip them rather than dividing by zero.
- The result is a plain Python
float, not a 0-d numpy array. - Tests compare with tolerance
atol ≈ 1e-9.
Notes
- Why ECE and not just AUC. AUC is rank-invariant — it cannot detect the systematic over- or under-confidence ECE measures. A model can have AUC and ECE at the same time; the second breaks every downstream auction and fusion.
- Bin count is a knob. is the most-cited default after the original paper (Guo et al., 2017); is a common textbook choice. Adaptive (equal-mass) binning is a separate variant — out of scope here.
▶ 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.
- •Perfectly calibrated reference example
- •Sample two-bin hand case
- •Reference worst-case overconfidence