or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

calibration.mdclassification.mdindex.mdmetrics.mdregression.mdrisk-control.mdutils.md

calibration.mddocs/

0

# Calibration Methods

1

2

Probability calibration methods for improving the reliability of probabilistic predictions, particularly for multi-class classification problems. MAPIE provides top-label calibration techniques that ensure predicted probabilities accurately reflect the true likelihood of predictions.

3

4

## Capabilities

5

6

### Top-Label Calibrator

7

8

Implements top-label calibration for multi-class classification, focusing on calibrating the probability of the most likely predicted class. This approach is particularly effective for scenarios where the confidence in the top prediction is most important.

9

10

```python { .api }

11

class TopLabelCalibrator:

12

"""

13

Top-label calibration for multi-class classification.

14

15

Parameters:

16

- estimator: ClassifierMixin, base multi-class classifier

17

- calibrator: Union[str, RegressorMixin], calibration method ("sigmoid", "isotonic") or custom regressor

18

- cv: str, cross-validation strategy ("split", "prefit") (default: "split")

19

"""

20

def __init__(self, estimator=None, calibrator=None, cv="split"): ...

21

22

def fit(self, X, y, sample_weight=None, calib_size=0.33, random_state=None, shuffle=True, stratify=None, **fit_params):

23

"""

24

Fit the classifier and calibrator.

25

26

Parameters:

27

- X: ArrayLike, input features

28

- y: ArrayLike, class labels

29

- sample_weight: Optional[ArrayLike], sample weights

30

- calib_size: float, fraction of data for calibration when cv="split" (default: 0.33)

31

- random_state: Optional[int], random seed for data splitting

32

- shuffle: bool, whether to shuffle data before splitting (default: True)

33

- stratify: Optional[ArrayLike], stratification labels (default: None, uses y)

34

- **fit_params: additional parameters passed to estimator.fit()

35

36

Returns:

37

Self

38

"""

39

40

def predict_proba(self, X):

41

"""

42

Predict calibrated class probabilities.

43

44

Parameters:

45

- X: ArrayLike, test features

46

47

Returns:

48

NDArray: calibrated probabilities (shape: n_samples x n_classes)

49

"""

50

51

def predict(self, X):

52

"""

53

Predict class labels using calibrated probabilities.

54

55

Parameters:

56

- X: ArrayLike, test features

57

58

Returns:

59

NDArray: predicted class labels

60

"""

61

62

# Key attributes after fitting

63

classes_: NDArray # Array with class names

64

n_classes_: int # Number of classes

65

single_estimator_: ClassifierMixin # Fitted base classifier

66

calibrators: Dict[Union[int, str], RegressorMixin] # Fitted calibrators per class

67

```

68

69

## Usage Examples

70

71

### Basic Top-Label Calibration

72

73

```python

74

from mapie.calibration import TopLabelCalibrator

75

from sklearn.ensemble import RandomForestClassifier

76

from sklearn.model_selection import train_test_split

77

import numpy as np

78

79

# Prepare multi-class data

80

X, y = load_multiclass_data()

81

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y)

82

83

# Create calibrated classifier

84

calibrated_clf = TopLabelCalibrator(

85

estimator=RandomForestClassifier(n_estimators=100, random_state=42),

86

calibrator="sigmoid", # Platt scaling

87

cv="split"

88

)

89

90

# Fit with automatic calibration split

91

calibrated_clf.fit(X_train, y_train, calib_size=0.3, random_state=42)

92

93

# Get calibrated probabilities

94

y_proba_calibrated = calibrated_clf.predict_proba(X_test)

95

y_pred_calibrated = calibrated_clf.predict(X_test)

96

```

97

98

### Isotonic Calibration

99

100

```python

101

# Use isotonic regression for non-parametric calibration

102

calibrated_clf = TopLabelCalibrator(

103

estimator=LogisticRegression(max_iter=1000),

104

calibrator="isotonic", # Non-parametric calibration

105

cv="split"

106

)

107

108

# Fit with stratified splitting

109

calibrated_clf.fit(

110

X_train, y_train,

111

calib_size=0.4,

112

stratify=y_train, # Ensure balanced calibration set

113

random_state=42

114

)

115

116

# Compare raw vs calibrated probabilities

117

raw_clf = LogisticRegression(max_iter=1000)

118

raw_clf.fit(X_train, y_train)

119

120

y_proba_raw = raw_clf.predict_proba(X_test)

121

y_proba_calibrated = calibrated_clf.predict_proba(X_test)

122

```

123

124

### Pre-fitted Estimator Calibration

125

126

```python

127

# Use pre-fitted estimator

128

base_clf = RandomForestClassifier(n_estimators=50)

129

base_clf.fit(X_train, y_train)

130

131

# Calibrate pre-fitted estimator

132

calibrated_clf = TopLabelCalibrator(

133

estimator=base_clf,

134

calibrator="sigmoid",

135

cv="prefit" # Use pre-fitted estimator

136

)

137

138

# Fit calibrator only (estimator already fitted)

139

calibrated_clf.fit(X_calib, y_calib) # Separate calibration data

140

```

141

142

### Custom Calibration Regressor

143

144

```python

145

from sklearn.linear_model import Ridge

146

147

# Use custom regressor for calibration

148

custom_calibrator = Ridge(alpha=1.0)

149

150

calibrated_clf = TopLabelCalibrator(

151

estimator=RandomForestClassifier(),

152

calibrator=custom_calibrator,

153

cv="split"

154

)

155

156

calibrated_clf.fit(X_train, y_train)

157

```

158

159

## Calibration Methods

160

161

### Sigmoid Calibration (Platt Scaling)

162

163

Fits a sigmoid function to map predicted probabilities to calibrated probabilities. Assumes calibration curve has sigmoid shape.

164

165

```python

166

calibrator="sigmoid"

167

```

168

169

**Mathematical Form:**

170

```

171

P_calibrated = 1 / (1 + exp(A * P_raw + B))

172

```

173

174

**Advantages:**

175

- Parametric method with interpretable parameters

176

- Works well when calibration curve is sigmoid-shaped

177

- Requires relatively few calibration samples

178

179

**Best for:**

180

- Small calibration datasets

181

- When the miscalibration follows a sigmoid pattern

182

- Naive Bayes and SVM classifiers

183

184

### Isotonic Calibration

185

186

Non-parametric method that fits a monotonic function to map probabilities to calibrated values.

187

188

```python

189

calibrator="isotonic"

190

```

191

192

**Advantages:**

193

- Non-parametric, no assumptions about calibration curve shape

194

- More flexible than sigmoid calibration

195

- Can handle complex calibration patterns

196

197

**Best for:**

198

- Larger calibration datasets

199

- Tree-based models (Random Forest, Gradient Boosting)

200

- When calibration curve is not sigmoid-shaped

201

202

## Advanced Usage

203

204

### Analyzing Calibration Quality

205

206

```python

207

from sklearn.calibration import calibration_curve

208

import matplotlib.pyplot as plt

209

210

# Compute calibration curves

211

fraction_pos_raw, mean_pred_raw = calibration_curve(

212

y_test, y_proba_raw[:, 1], n_bins=10

213

)

214

215

fraction_pos_cal, mean_pred_cal = calibration_curve(

216

y_test, y_proba_calibrated[:, 1], n_bins=10

217

)

218

219

# Plot calibration curves

220

plt.figure(figsize=(10, 6))

221

plt.plot([0, 1], [0, 1], 'k--', label='Perfect calibration')

222

plt.plot(mean_pred_raw, fraction_pos_raw, 's-', label='Raw probabilities')

223

plt.plot(mean_pred_cal, fraction_pos_cal, 's-', label='Calibrated probabilities')

224

plt.xlabel('Mean predicted probability')

225

plt.ylabel('Fraction of positives')

226

plt.legend()

227

plt.title('Calibration Plot')

228

plt.show()

229

```

230

231

### Using Calibration Metrics

232

233

```python

234

from mapie.metrics.calibration import (

235

expected_calibration_error,

236

top_label_ece,

237

kolmogorov_smirnov_statistic

238

)

239

240

# Expected Calibration Error (ECE)

241

ece_raw = expected_calibration_error(y_test, y_proba_raw[:, 1])

242

ece_calibrated = expected_calibration_error(y_test, y_proba_calibrated[:, 1])

243

244

print(f"ECE before calibration: {ece_raw:.4f}")

245

print(f"ECE after calibration: {ece_calibrated:.4f}")

246

247

# Top-label ECE for multi-class

248

top_ece_raw = top_label_ece(y_test, y_proba_raw)

249

top_ece_calibrated = top_label_ece(y_test, y_proba_calibrated)

250

251

print(f"Top-label ECE before: {top_ece_raw:.4f}")

252

print(f"Top-label ECE after: {top_ece_calibrated:.4f}")

253

254

# Kolmogorov-Smirnov test

255

ks_stat_raw = kolmogorov_smirnov_statistic(y_test, y_proba_raw[:, 1])

256

ks_stat_calibrated = kolmogorov_smirnov_statistic(y_test, y_proba_calibrated[:, 1])

257

```

258

259

### Multi-Class Calibration Analysis

260

261

```python

262

# Analyze per-class calibration

263

n_classes = len(calibrated_clf.classes_)

264

265

plt.figure(figsize=(15, 5))

266

for i in range(n_classes):

267

plt.subplot(1, n_classes, i+1)

268

269

# Binary indicator for class i

270

y_binary = (y_test == calibrated_clf.classes_[i]).astype(int)

271

272

# Calibration curve for class i

273

fraction_pos, mean_pred = calibration_curve(

274

y_binary, y_proba_calibrated[:, i], n_bins=10

275

)

276

277

plt.plot([0, 1], [0, 1], 'k--', alpha=0.5)

278

plt.plot(mean_pred, fraction_pos, 's-')

279

plt.xlabel(f'Mean predicted prob (Class {calibrated_clf.classes_[i]})')

280

plt.ylabel('Fraction of positives')

281

plt.title(f'Calibration - Class {calibrated_clf.classes_[i]}')

282

283

plt.tight_layout()

284

plt.show()

285

```

286

287

### Sample Weight Support

288

289

```python

290

# Use sample weights during fitting

291

sample_weights = compute_sample_weight('balanced', y_train)

292

293

calibrated_clf = TopLabelCalibrator(

294

estimator=RandomForestClassifier(),

295

calibrator="sigmoid"

296

)

297

298

# Pass sample weights to fit

299

calibrated_clf.fit(

300

X_train, y_train,

301

sample_weight=sample_weights,

302

calib_size=0.3

303

)

304

```

305

306

## Best Practices

307

308

### Choosing Calibration Method

309

310

- **Use sigmoid** when:

311

- Small calibration dataset (< 1000 samples)

312

- Base classifier is Naive Bayes or SVM

313

- Calibration curve appears sigmoid-shaped

314

315

- **Use isotonic** when:

316

- Larger calibration dataset (> 1000 samples)

317

- Base classifier is tree-based (Random Forest, XGBoost)

318

- Calibration curve has complex shape

319

320

### Calibration Set Size

321

322

```python

323

# Rule of thumb: 20-40% for calibration

324

calib_sizes = [0.1, 0.2, 0.3, 0.4, 0.5]

325

ece_scores = []

326

327

for calib_size in calib_sizes:

328

clf = TopLabelCalibrator(estimator=RandomForestClassifier())

329

clf.fit(X_train, y_train, calib_size=calib_size)

330

y_proba = clf.predict_proba(X_test)

331

ece = expected_calibration_error(y_test, y_proba[:, 1])

332

ece_scores.append(ece)

333

334

# Find optimal calibration set size

335

optimal_size = calib_sizes[np.argmin(ece_scores)]

336

print(f"Optimal calibration size: {optimal_size}")

337

```

338

339

### Cross-Validation for Calibration

340

341

```python

342

from sklearn.model_selection import cross_val_score

343

344

# Evaluate calibration with cross-validation

345

def calibration_score(estimator, X, y):

346

"""Custom scoring function for calibration quality."""

347

y_proba = estimator.predict_proba(X)

348

return -expected_calibration_error(y, y_proba[:, 1]) # Negative ECE

349

350

calibrated_clf = TopLabelCalibrator(

351

estimator=RandomForestClassifier(),

352

calibrator="isotonic"

353

)

354

355

scores = cross_val_score(

356

calibrated_clf, X, y,

357

cv=5,

358

scoring=calibration_score

359

)

360

361

print(f"Average calibration score: {np.mean(scores):.4f} ± {np.std(scores):.4f}")

362

```