The problem
When a model says it is 80% sure, is it right 80% of the time? A model whose confidence matches its accuracy is calibrated. Modern networks are often overconfident: they say 95% and are right 75% of the time. The ECE (expected calibration error) measures the mismatch with one number.
For predictions with confidences (the probability of the predicted class) and correctness , split into equal-width bins and compare, in each bin, the accuracy (the fraction right) with the mean confidence:
where is the set of predictions in bin , its size, and each gap is weighted by how many predictions the bin holds.
The bins
Bin (counting from 0) holds the confidences in : the left end is excluded and the right end included, and confidence exactly 0 goes in bin 0. So with : is in bin 0, in bin 5, in bin 9. The bin of a confidence is , clipped to (so that 0 does not give ).
Example. Six predictions with bins of width : confidences and correctness .
- 2: — holds: ; count: 2; accuracy: ; mean confidence: ; gap:
- 1: — holds: ; count: 1; accuracy: ; mean confidence: ; gap:
- 4: — holds: ; count: 3; accuracy: ; mean confidence: ; gap:
(Bins 0 and 3 are empty: count 0, accuracy and confidence 0, no contribution.) ECE .
What to implement
bin_index(conf, n_bins): the bin of each confidence.reliability(conf, correct, n_bins): three arrays of length : the count, the accuracy and the mean confidence of each bin (accuracy and confidence are 0 for empty bins).ece(conf, correct, n_bins=15): the expected calibration error. Empty bins contribute nothing.
Requirements
- No loops over predictions.
Hint
np.ceil(conf * n_bins) - 1, as an integer and clipped to , gives the bin; np.bincount(bins, weights=values, minlength=n_bins) sums values per bin, and without weights it counts.