SPB Git forge

spb/qc-election

Public
20commits 1branches 0releases
4.9 MBsize
maindefault branch
19 days agolast push
Python 66.6% HTML 24.8% CSS 4.9% JavaScript 3.6%
15.1 KB · 220 lines html
Raw Blame History
1<!DOCTYPE html>2<!--3  QC Élection Forecast — Plateforme de prévision électorale du Québec 20264  Auteur : Simon-Pierre Boucher5  Contact : contact@spboucher.ai6  https://www.qc-election.com7-->8<html lang="fr">9<head>10<script>document.documentElement.dataset.theme=localStorage.getItem("qce-theme")||"dark";</script>11<meta charset="utf-8">12<meta name="viewport" content="width=device-width, initial-scale=1">13<title>Méthodologie — QC Élection Forecast</title>14<link rel="icon" type="image/svg+xml" href="/assets/img/favicon.svg">15<link rel="icon" type="image/png" sizes="64x64" href="/assets/img/favicon-64.png">16<link rel="apple-touch-icon" href="/assets/img/apple-touch-icon.png">17<meta property="og:site_name" content="QC Élection Forecast">18<meta property="og:type" content="website">19<meta property="og:title" content="Méthodologie — QC Élection Forecast">20<meta property="og:description" content="Prévision probabiliste de l'élection générale québécoise du 5 octobre 2026 : 127 circonscriptions, modèle bayésien calibré, sources traçables.">21<meta property="og:image" content="https://www.qc-election.com/assets/img/og.png">22<meta property="og:image:width" content="1200">23<meta property="og:image:height" content="630">24<meta property="og:locale" content="fr_CA">25<meta name="twitter:card" content="summary_large_image">26<meta name="twitter:title" content="Méthodologie — QC Élection Forecast">27<meta name="twitter:image" content="https://www.qc-election.com/assets/img/og.png">28<meta name="theme-color" content="#0a0d14">29<link rel="stylesheet" href="/assets/style.css">30</head>31<body>32<header class="site"></header>33<div class="wrap">34  <div class="hero">35    <h1>Méthodologie</h1>36    <p class="sub">Le système est auditable et reproductible : sources, formules, hypothèses et limites, sans boîte noire.</p>37    <p class="disclaimer" id="version"></p>38  </div>3940  <div class="prose">41    <h2>1. Ce que la plateforme calcule</h2>42    <p>Deux estimations distinctes sont publiées : le <b>nowcast</b> (« si l'élection avait lieu43    aujourd'hui, quelle serait l'intention de vote réelle ? ») et le <b>forecast</b> (« quelle est la44    distribution probable du résultat le jour du scrutin ? »). Le forecast ajoute au nowcast45    l'incertitude liée à l'évolution possible de l'opinion d'ici le vote.</p>4647    <h2>2. Données et provenance</h2>48    <p>Chaque valeur en base conserve sa source, son URL, sa date d'accès, sa valeur brute et sa49    valeur normalisée. Sources actuelles : <b>données ouvertes officielles d'Élections Québec50    (DGEQ)</b> — carte électorale 2026 (GeoJSON des 127 circonscriptions), liste officielle,51    registre des candidatures avec drapeau « député sortant »; agrégation des sondages publics52    (Wikipédia, avec lien vers chaque maison); résultats officiels 2022 par circonscription;53    marchés prédictifs (Polymarket, affichage auxiliaire seulement). Les circonscriptions54    nouvelles (Bellefeuille, Marie-Lacoste-Gérin-Lajoie) reçoivent comme référence la moyenne de55    leurs circonscriptions parentes — approximation documentée dans la fiche de chaque56    circonscription.</p>5758    <h2>3. Pondération des sondages</h2>59    <p>Aucun sondage n'est traité également. Trois facteurs :</p>60    <table class="data">61      <tr><th>Facteur</th><th>Formule</th><th>Rôle</th></tr>62      <tr><td>Récence</td><td><code>0,5^(âge / 12 jours)</code></td><td>demi-vie de 12 jours (la date de terrain compte, pas la date de publication)</td></tr>63      <tr><td>Précision</td><td><code>n_eff = min(n / deff, 2500)</code></td><td>taille effective avec design effect par mode (web 1,30, téléphone 1,20…), plafonnée pour qu'aucun sondage géant ne domine</td></tr>64      <tr><td>Qualité de la maison</td><td><code>×0,6 à ×1,4</code></td><td>selon l'erreur absolue moyenne historique; maison inconnue : ×0,9 et incertitude accrue</td></tr>65    </table>66    <p>À la variance d'échantillonnage s'ajoute une <b>erreur excédentaire</b> de ±1,5 pp67    (erreur totale d'enquête : cadre, non-réponse, pondération du sondeur).</p>6869    <h2>4. Effets maison (house effects)</h2>70    <p>Pour chaque maison, on compare ses sondages des 21 derniers jours des campagnes passées au71    résultat réel. Le biais moyen par parti est <b>rétréci de 50 % vers zéro</b> (on reste incertain72    sur l'estimation du biais) et borné à ±3 pp, puis soustrait des sondages avant l'ajustement du73    modèle. Les cotes sont recalculées à chaque cycle — il n'y a aucune note arbitraire fixe.</p>7475    <h2>5. Modèle latent (state space bayésien)</h2>76    <p>Les intentions de vote sont compositionnelles (somme = 100 %). L'état latent est le vecteur77    des log-ratios additifs <code>y_k = log(p_k / p_CAQ)</code> (5 dimensions pour 6 composantes),78    ce qui garantit la cohérence de la composition et la corrélation négative entre partis :79    si un parti monte, les autres baissent.</p>80    <p>Dynamique : marche aléatoire gaussienne <code>x_t = x_{t−1} + w_t</code>,81    <code>w_t ∼ N(0, q·I)</code>. Chaque sondage est une observation bruitée82    <code>y = alr(parts ajustées)</code> avec covariance multinomiale (méthode delta) sur la taille83    effective. L'inférence est un filtre de Kalman exact (lisseur RTS pour les courbes historiques);84    la variance quotidienne <code>q</code> est estimée par maximum de vraisemblance sur grille,85    bornée à [0,004²; 0,030²].</p>8687    <h2>6. Du nowcast au forecast</h2>88    <p>Le forecast au jour du vote conserve la moyenne du nowcast (martingale) mais ajoute la89    variance de dérive <code>q × jours restants × 1,6</code> — le facteur 1,6 reflète la90    volatilité accrue en campagne, observée sur les cycles québécois passés. Six mois avant le91    scrutin, les intervalles sont donc nettement plus larges que la veille du vote.</p>9293    <h2>6 bis. Au-delà des sondages (v2) — les cinq couches</h2>94    <p>Depuis la version 2.0.0, le forecast n'est plus construit sur les seuls sondages.95    Quatre couches s'ajoutent au modèle de tendance, chacune à poids <b>explicite, borné et96    débrayable</b>, et leur contribution exacte est publiée à chaque run sur la page97    <a href="/signaux">Signaux</a> :</p>98    <table class="data">99      <tr><th>Couche</th><th>Source</th><th>Mécanisme</th><th>Poids</th></tr>100      <tr><td><b>Votes réels</b></td><td>Élections partielles 2022-2026 (DGEQ)</td>101        <td>le swing local observé, rétréci ×0,6 (les partielles exagèrent le mouvement102        national), devient une observation nationale du filtre de Kalman à sa date</td>103        <td>n équivalent ~350, erreur excédentaire ±3 pp</td></tr>104      <tr><td><b>Fondamentaux</b></td><td>Satisfaction envers le gouvernement (Léger, via105        veille web), vote précédent, usure du pouvoir</td>106        <td>régression ridge sur les 8 générales de 1998 à 2022 (validation leave-one-out) →107        prior bayésien combiné au posterior des sondages par pondération de précision</td>108        <td><code>w(t) = min(0,8; (jours/540)^1,3)</code> — décroît vers 0 au scrutin</td></tr>109      <tr><td><b>Médias</b></td><td>Sentiment de presse 14 j (RSS + veille Firecrawl)</td>110        <td>nudge de la moyenne du forecast, saturé par tanh et seuillé par volume</td>111        <td>borné à ±0,35 pp par parti</td></tr>112      <tr><td><b>Marchés prédictifs</b></td><td>Polymarket (probabilités implicites)</td>113        <td>la P(plus de sièges) publiée est une moyenne pondérée modèle/marché,114        renormalisée — les intentions de vote ne sont pas modifiées</td>115        <td>88 % modèle / 12 % marché</td></tr>116    </table>117    <p><b>Signaux web avancés (v2.1)</b> — deux signaux issus de la littérature récente118    complètent les couches : (a) l'<b>attention Wikipédia</b> (pageviews quotidiens des pages119    des partis et des chef·fe·s, API Wikimedia) — la recherche montre qu'elle ajoute du pouvoir120    prédictif au-delà des sondages et fondamentaux (Smith &amp; Gustafson, <i>Public Opinion121    Quarterly</i> 2017); comme un pic peut être bon ou mauvais pour un parti, le signal n'est122    <b>jamais directionnel</b> : un pic global (z ≥ 2) gonfle la variance de dérive du forecast123    (multiplicateur ≤ 1,45) sans toucher aucune moyenne; (b) un <b>sondage synthétique LLM</b>124    (« silicon sampling », 96 strates démographiques du Québec poststratifiées, LLM local ancré125    dans les manchettes réelles de notre veille) — <b>expérimental, poids strictement nul</b> :126    un LLM ne collecte aucune donnée nouvelle (critique McKown-Dawson/Silver 2025); l'écart au127    forecast est publié comme objet d'étude et sera évalué après le 5 octobre.</p>128    <p>Une <b>veille web continue</b> (Firecrawl) alimente ces couches à chaque cycle :129    radar des nouveaux sondages dans la presse (alerte de provenance, aucune ingestion130    automatique de chiffres), extraction du % de satisfaits envers le gouvernement, et131    articles au-delà des flux RSS. Chaque page brute est archivée pour audit.</p>132    <p>Le backtest 2022 rejoue le blend de fondamentaux avec l'information de l'époque133    (sortant CAQ, 1er mandat, satisfaction ~54 %) et publie côte à côte l'erreur v2 et134    l'erreur « sondages seuls » — les partielles et l'ajustement médias, non rejouables135    faute de données 2022, sont exclus du backtest et bornés par construction.</p>136137    <h2>7. Modèle de circonscription</h2>138    <p>Pas de swing uniforme : le swing national est appliqué en espace log-ratio139    (<b>swing proportionnel</b>) à la référence 2022 de chaque circonscription, ce qui respecte les140    planchers et plafonds locaux. S'y ajoutent la tendance régionale (partial pooling : les régions141    pauvres en données empruntent au national), l'historique local, et une pénalité de 0,06 en142    log-ratio (~1,3 pp) au parti sortant quand son député ne se représente pas (48 retraits en 2026).</p>143144    <h2>8. Simulateur Monte Carlo et corrélation des erreurs</h2>145    <p>À chaque mise à jour, 25 000 élections complètes sont simulées avec des erreurs en couches,146    jamais indépendantes :</p>147    <table class="data">148      <tr><th>Couche</th><th>Distribution</th><th>Effet</th></tr>149      <tr><td>Erreur d'opinion</td><td>posterior complet du forecast (Kalman + dérive)</td><td>incertitude sur l'état réel de l'opinion</td></tr>150      <tr><td>Erreur systémique de sondage</td><td><code>N(0, 0,12²)</code> nationale, corrélée entre partis</td><td>toute l'industrie peut se tromper ensemble (2022 : CAQ sous-estimée de ~3 pp) — déplace les 127 circonscriptions simultanément</td></tr>151      <tr><td>Erreur régionale</td><td><code>N(0, 0,14²)</code> par région (13 régions)</td><td>corrélation intrarégionale</td></tr>152      <tr><td>Erreur locale</td><td><code>N(0, 0,20²)</code> par circonscription</td><td>idiosyncrasies locales (candidats, enjeux)</td></tr>153    </table>154    <p>Les écarts-types régionaux et locaux sont <b>calibrés empiriquement</b> sur les résidus du155    backtest 2022 (swing proportionnel 2018→2022), atténués parce que 2022 fut un réalignement156    atypique; l'ajout de la couche systémique fait passer la couverture des intervalles à J−1 de157    20 % à 100 % dans le backtest, sans dégrader le Brier score.</p>158    <p>De chaque simulation on tire les sièges par parti; on publie la moyenne, les percentiles159    P5/P25/P50/P75/P95, la probabilité d'obtenir le plus de sièges, la probabilité de majorité160    (≥ 64/127) et la probabilité de gouvernement minoritaire.</p>161162    <h2>9. Backtesting et calibration</h2>163    <p>Le modèle est rejoué sur l'élection de 2022 à J−120, J−90, J−60, J−30, J−14, J−7 et J−1,164    avec uniquement l'information disponible à chaque date. Mesures : EAM/RMSE du vote, couverture165    des intervalles, EAM des sièges, Brier score, log loss et courbe de calibration166    (voir la page <a href="/backtest">Calibration</a>). La calibration est jugée plus importante167    que la prédiction correcte d'un scrutin donné. Limite connue : en 2022 l'ensemble de168    l'industrie a sous-estimé la CAQ (~3 pp) — l'erreur excédentaire et les couches corrélées du169    simulateur existent précisément pour intégrer ce risque.</p>170171    <h2>10. Sentiment Web et momentum</h2>172    <p>Un moteur indépendant analyse la presse québécoise (flux RSS publics) :173    document → extraction d'entités → détection de stance (pro/anti/neutre/ambigu, avec gestion de174    la négation et des attaques dirigées : « X affirme que Y est incompétent » est négatif envers Y)175    → agrégats quotidiens → détection d'anomalies de volume. Un scoreur LLM optionnel peut raffiner176    la stance. <b>Poids dans le forecast : un ajustement borné à ±0,35 pp par parti</b> (voir §6 bis) —177    le sentiment Web n'est pas représentatif de la population et ne peut jamais devenir un moteur178    du forecast; l'indicateur de momentum reste purement auxiliaire.</p>179180    <h2>11. IA</h2>181    <p>L'IA sert uniquement à l'extraction et au traitement du langage (stance, résumé,182    regroupement de nouvelles) et à la reformulation d'explications déjà calculées. Le cœur du183    forecast est entièrement statistique : on ne demande jamais à un modèle de langage « qui va184    gagner ». La fonction « Interroger le modèle » compose ses réponses à partir des chiffres réels185    des runs (sondages ajoutés, variations de probabilité, événements), toutes traçables.</p>186187    <h2>12. Neutralité et incertitude</h2>188    <p>Les mêmes règles s'appliquent à tous les partis : mêmes formules de pondération, mêmes189    corrections, ordre d'affichage déterminé par les données (probabilité courante), jamais par un190    choix éditorial. La plateforme n'affirme jamais « X va gagner » : toute sortie est une191    probabilité accompagnée de son incertitude.</p>192193    <h2>13. Versions et reproductibilité</h2>194    <p id="model-info">Chaque exécution du modèle est archivée (snapshot complet consultable par195    l'API <code>/api/forecast/history</code> et <code>/api/forecast/run/{id}</code>), ce qui permet196    de vérifier a posteriori ce que le modèle disait à toute date. Code : Python (NumPy/SciPy,197    FastAPI), base SQLite, simulations vectorisées.</p>198199    <h2>Limites connues</h2>200    <ul>201      <li>Sondages régionaux non publics : les écarts régionaux reposent sur la structure 2022 + couche d'erreur régionale.</li>202      <li>Transposition 2022 → carte 2025 approximative pour les circonscriptions modifiées.</li>203      <li>Historique de maisons limité aux élections québécoises récentes; les nouvelles maisons ont un biais supposé nul avec incertitude accrue.</li>204      <li>Le modèle de participation est un outil de scénario (simulateur), pas un modèle de probabilité de vote individuel.</li>205    </ul>206  </div>207</div>208<footer class="site"></footer>209<script src="/assets/app.js"></script>210<script>211(async () => {212  const meta = await initShell("/methodologie");213  document.getElementById("version").textContent =214    `Version du modèle : ${meta.model_version} · dernière mise à jour des données : ` +215    (meta.last_update ? new Date(meta.last_update + "Z").toLocaleString("fr-CA") : "—");216})();217</script>218</body>219</html>220