gg2
Deploy Iddaai Backend / build-and-deploy (push) Successful in 4m53s

This commit is contained in:
2026-05-24 17:29:31 +03:00
parent 920ae7ce38
commit fa48f87f53
8 changed files with 384 additions and 12 deletions
+19 -8
View File
@@ -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