# QC Élection Forecast — Plateforme de prévision électorale du Québec 2026 # Auteur : Simon-Pierre Boucher # Contact : contact@spboucher.ai # https://www.qc-election.com """Pondération des sondages : temps, taille effective d'échantillon, sondeur. Le filtre de Kalman intègre déjà le temps (structure d'état) et la précision (variance d'observation). Les poids calculés ici servent : 1. à moduler la variance d'observation (qualité du sondeur, design effect); 2. à afficher de façon transparente le poids relatif de chaque sondage. """ from __future__ import annotations import math from datetime import date from ..config import settings def effective_n(sample_size: int | None, mode: str) -> float: """Taille effective : n / design effect, plafonnée (anti-domination).""" n = sample_size or 600 # défaut prudent si taille inconnue deff = settings.design_effects.get(mode, settings.design_effects["unknown"]) return min(n / deff, float(settings.max_effective_n)) def time_weight(field_end: date, as_of: date) -> float: age = max(0, (as_of - field_end).days) return 0.5 ** (age / settings.time_decay_halflife_days) def sample_weight(sample_size: int | None, mode: str) -> float: return math.sqrt(effective_n(sample_size, mode) / 1000.0) def display_weight(field_end: date, as_of: date, sample_size: int | None, mode: str, pollster_multiplier: float = 1.0) -> float: """Poids relatif affiché dans le Poll Explorer (0–1, normalisé côté API).""" return time_weight(field_end, as_of) * sample_weight(sample_size, mode) * pollster_multiplier