This commit is contained in:
@@ -149,10 +149,15 @@ class Calibrator:
|
||||
except Exception as e:
|
||||
print(f"[Calibrator] Warning: Failed to load metrics for {market}: {e}")
|
||||
|
||||
# Below this sample count, blend isotonic with raw_prob to dampen overfit jumps.
|
||||
# Above this count, trust isotonic fully.
|
||||
TRUSTED_SAMPLE_FLOOR = 30
|
||||
TRUSTED_SAMPLE_CEILING = 200
|
||||
# Below this sample count, the isotonic model is treated as untrained
|
||||
# (raw_prob is returned). Between MIN and FLOOR we ramp from 0 to ~15%
|
||||
# trust. Between FLOOR and CEILING we ramp to full trust.
|
||||
# Rationale: 12-sample calibrators are statistical noise; even 30%
|
||||
# blending on them propagates the noise into the confidence value the
|
||||
# betting_brain reads downstream.
|
||||
HARD_MIN_SAMPLES = 50
|
||||
TRUSTED_SAMPLE_FLOOR = 100
|
||||
TRUSTED_SAMPLE_CEILING = 400
|
||||
# Hard cap on how far calibration can move probability in either direction.
|
||||
MAX_DELTA = 0.20
|
||||
|
||||
@@ -198,15 +203,21 @@ class Calibrator:
|
||||
# Sparse models barely move probability; mature models dominate.
|
||||
metrics = self.metrics.get(market_key)
|
||||
n_samples = metrics.sample_count if metrics else 0
|
||||
if n_samples < self.HARD_MIN_SAMPLES:
|
||||
# Below 50 samples isotonic fit is unreliable — bypass it
|
||||
# entirely and return raw_prob. The heuristic shrinkage
|
||||
# below would still apply a model-version multiplier elsewhere.
|
||||
return float(np.clip(raw_prob, 0.01, 0.99))
|
||||
if n_samples >= self.TRUSTED_SAMPLE_CEILING:
|
||||
iso_weight = 1.0
|
||||
elif n_samples <= self.TRUSTED_SAMPLE_FLOOR:
|
||||
# Very sparse: at least 30% trust to surface the signal
|
||||
iso_weight = max(0.30, n_samples / self.TRUSTED_SAMPLE_CEILING)
|
||||
# Linear ramp from 0% at HARD_MIN_SAMPLES to ~25% at FLOOR
|
||||
span = self.TRUSTED_SAMPLE_FLOOR - self.HARD_MIN_SAMPLES
|
||||
iso_weight = 0.25 * (n_samples - self.HARD_MIN_SAMPLES) / span
|
||||
else:
|
||||
# Linearly ramp 30% → 100% between floor and ceiling
|
||||
# Linearly ramp 25% → 100% between floor and ceiling
|
||||
span = self.TRUSTED_SAMPLE_CEILING - self.TRUSTED_SAMPLE_FLOOR
|
||||
iso_weight = 0.30 + 0.70 * (n_samples - self.TRUSTED_SAMPLE_FLOOR) / span
|
||||
iso_weight = 0.25 + 0.75 * (n_samples - self.TRUSTED_SAMPLE_FLOOR) / span
|
||||
blended = iso_weight * iso_pred + (1.0 - iso_weight) * raw_prob
|
||||
|
||||
# Cap delta to avoid huge swings on noisy calibrators
|
||||
|
||||
Reference in New Issue
Block a user