File size: 21,121 Bytes
19657de 46f9144 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
---
title: Bdv
emoji: 🌍
colorFrom: green
colorTo: green
sdk: gradio
sdk_version: 6.2.0
app_file: app.py
pinned: false
---
# Elections Sète - Prévision municipales
Pipeline complet pour harmoniser les données électorales, construire un dataset panel sans fuite temporelle, entraîner des modèles multi-blocs, charger l'historique dans PostgreSQL et exposer des résultats via Gradio.
## Installation
- Python 3.10+ recommandé.
- `python3 -m venv .venv && source .venv/bin/activate`
- `pip install -r requirements.txt`
## Fichiers YAML (configuration)
### `config/communes.yaml`
Ce fichier définit **les communes à inclure** (codes INSEE). Il est consommé par le pipeline (`src.pipeline.run_full_pipeline`) pour filtrer les données au niveau commune.
Formats acceptés (les codes sont normalisés en 5 chiffres) :
```yaml
communes:
"34301": "Sète"
"34172": "Frontignan"
```
ou
```yaml
communes:
- code_insee: "34301"
nom: "Sète"
- "34172"
```
Si tu modifies ce fichier, il faut **relancer le pipeline** pour régénérer les données filtrées.
### `config/raw_sources.yaml`
Description des fichiers bruts et de leur structure (colonnes, séparateur, métadonnées).
C'est **le point d'entrée** pour ajouter un nouveau CSV au pipeline.
Exemple (copie d'une election precedente + ajustements) :
```yaml
24_L_T1.csv:
copy_from: 22_L_T1.csv
date_scrutin: "2024-06-30"
code_bv_cols: ["Code commune", "Code BV"]
rename_map:
Nuance Liste: code_candidature
Libellé Abrégé Liste: nom_candidature
```
### `config/nuances.yaml`
Mapping des nuances vers les blocs politiques (avec overrides).
Par défaut, le mapping CSV historique est réutilise et on peut **surcharger** ou **ajouter** des nuances :
```yaml
base_mapping: data/mapping_candidats_blocs.csv
overrides:
- code_candidature: "XYZ"
nom_candidature: "Exemple"
blocs: [gauche_modere, centre]
```
### `docker-compose.yml`
Fichier YAML pour démarrer PostgreSQL (et éventuellement pgAdmin). Utilisé par :
```bash
docker-compose up -d postgres
docker-compose --profile admin up
```
## 1. Prétraitement (harmonisation)
```bash
# Harmonisation des CSV bruts -> data/interim/elections_long.parquet
python -m src.data.preprocess --raw-dir data/raw --output-dir data/interim
```
Par défaut, le prétraitement lit `config/raw_sources.yaml`. Tu peux surcharger via `--meta-config`.
## 2. Pipeline communes + features (optionnel mais recommandé si tu filtres par communes)
Le pipeline applique le filtre `config/communes.yaml` et génère `data/processed/elections_blocs.*`.
À lancer depuis un notebook ou un petit script :
```bash
python3 - <<'PY'
from pathlib import Path
from src.pipeline import run_full_pipeline
run_full_pipeline(
elections_long_path=Path("data/interim/elections_long.parquet"),
mapping_path=Path("config/nuances.yaml"),
output_dir=Path("data/processed"),
target_communes_path=Path("config/communes.yaml"),
)
PY
```
## 3. Construction du panel (features + cibles)
```bash
python -m src.features.build_features \
--elections-long data/interim/elections_long.parquet \
--mapping config/nuances.yaml \
--output data/processed/panel.parquet
```
Le dictionnaire de données est généré dans `data/processed/data_dictionary.md`.
Note : `src.features.build_features` **ne filtre pas** via `config/communes.yaml`. Si tu veux limiter l'entraînement à certaines communes, filtre `elections_long` en amont ou adapte le pipeline.
## 4. Base PostgreSQL
```bash
cp .env.example .env
docker-compose up -d postgres # pgAdmin en option: `docker-compose --profile admin up`
# Ingestion du panel dans le schéma normalisé
python -m src.db.ingest --input data/processed/panel.parquet
```
Le schéma est défini dans `src/db/schema.py`.
## 5. Entraînement & évaluation
Commande demandée (CV stricte par scrutin) :
```bash
python3 -m src.model.train --cv-splits 4 --models hist_gradient_boosting
```
Options principales :
- `--panel` : chemin du panel (`data/processed/panel.parquet` par défaut).
- `--models-dir` / `--reports-dir` : sorties modèles et rapports.
- `--train-end-year`, `--valid-end-year`, `--test-start-year` : split temporel.
- `--cv-splits` : nb de folds temporels (par scrutin).
- `--no-tune` : désactive la grille d'hyperparamètres.
- `--max-trials` : limite le nombre d'essais par modèle.
- `--models` : liste de modèles à tester (ex: `ridge`, `hist_gradient_boosting`, `lightgbm`, `xgboost`, `two_stage_hgb`, `catboost`).
Sorties :
- Modèle + preprocessor : `models/<nom>.joblib` et `models/feature_columns.json`
- Modèle sélectionné : `models/best_model.json`
- Rapport métriques : `reports/metrics.json` et `reports/metrics.md`
- CV détaillée : `reports/cv_summary.csv`
- Figure : `reports/figures/mae_per_category.png`
- Model card : `models/model_card.md`
## 6. Génération de prédictions hors ligne
```bash
python -m src.model.predict \
--model-path models/hist_gradient_boosting.joblib \
--target-election-type municipales \
--target-year 2026 \
--commune-code 34301
# -> predictions/pred_municipales_2026_sete.csv
```
Cette commande produit des **parts (%)** et des deltas vs législatives et municipales 2020.
## 7. Application Gradio
```bash
python -m app.gradio_app
```
Comportement :
- Backend PostgreSQL si disponible, sinon fallback fichiers locaux.
- **Historique** : consultation bureau par bureau (pas de ML).
- **Prédiction** : parts par bloc converties en **comptes** (personnes) + `blancs`, `nuls`, `abstentions`.
- `inscrits` peut être fourni par l'utilisateur (sinon valeur historique la plus récente du bureau).
- Cibles proposées : municipales 2026 (tour 1), legislatives 2027 (tour 1), presidentielles 2027 (tour 1).
## Structure des données
- Configurations : `config/`
- Bruts : `data/raw/`
- Long harmonisé : `data/interim/elections_long.parquet`
- Élections blocs (filtrées) : `data/processed/elections_blocs.parquet`
- Stats communales par scrutin : `data/processed/commune_event_stats.parquet`
- Panel features+cibles : `data/processed/panel.parquet`
- Mapping nuances -> catégories : `config/nuances.yaml` (base: `data/mapping_candidats_blocs.csv`)
## Notes
- Aucune fuite temporelle : les features sont calculées uniquement sur des scrutins strictement antérieurs à la cible.
- Les parts sont clipées à [0, 1] puis renormalisées.
- Les blancs/nuls dépendent des colonnes disponibles dans l'historique ; si une source ne les fournit pas, ils seront à 0.
## Inventaire des fichiers (snapshot)
Statuts :
- `actif` : utilisé par le pipeline actuel.
- `généré` : produit par le pipeline/entraînement (recréable).
- `hérité (début projet)` : ancien fichier ou prototype.
- `optionnel` : utile mais non requis au runtime.
- `système (inutile)` : métadonnées OS.
| Fichier | Fonction | Statut |
|---|---|---|
| `.DS_Store` | Métadonnées macOS | système (inutile) |
| `.env.example` | Template des variables d'environnement (DB) | actif |
| `.gitignore` | Règles gitignore | actif |
| `Elections_Sete.code-workspace` | Config VSCode (workspace) | optionnel |
| `README.md` | Documentation projet | actif |
| `app/__init__.py` | Package app (init) | actif |
| `app/app.py` | Ancienne app Gradio (bv_features.parquet) | hérité (début projet) |
| `app/gradio_app.py` | Application Gradio principale | actif |
| `app.py` | Ancienne interface Gradio (compute_predictions) | hérité (début projet) |
| `catboost_info/catboost_training.json` | Artefacts CatBoost (logs/metrics) | généré |
| `catboost_info/learn/events.out.tfevents` | Artefacts CatBoost (logs/metrics) | généré |
| `catboost_info/learn_error.tsv` | Artefacts CatBoost (logs/metrics) | généré |
| `catboost_info/time_left.tsv` | Artefacts CatBoost (logs/metrics) | généré |
| `config/communes.yaml` | Liste des communes cibles (codes INSEE) | actif |
| `config/nuances.yaml` | Overrides mapping nuances -> blocs | actif |
| `config/raw_sources.yaml` | Schéma des CSV bruts (meta-config) | actif |
| `data/.DS_Store` | Métadonnées macOS | système (inutile) |
| `data/contours-france-entiere-latest-v2.geojson` | Fond cartographique (geojson) | optionnel |
| `data/interim/.DS_Store` | Métadonnées macOS | système (inutile) |
| `data/interim/candidates_long.parquet` | Données intermédiaires long format | généré |
| `data/interim/elections_long.csv` | Données intermédiaires long format | généré |
| `data/interim/elections_long.parquet` | Données intermédiaires long format | généré |
| `data/interim/frames_std/14_EU.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/14_MN14_T1T2.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/17_L_T1.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/17_L_T2.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/17_PR_T1.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/17_PR_T2.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/19_EU.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/20_MN_T1.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/20_MN_T2.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/21_DEP_T1.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/21_DEP_T2.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/21_REG_T1.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/21_REG_T2.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/22_L_T1.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/22_L_T2.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/22_PR_T1.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/22_PR_T2.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/frames_std/24_EU.parquet` | Intermédiaire standardisé par scrutin | généré |
| `data/interim/harmonized/14_EU_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/14_MN14_T1T2_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/17_L_T1_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/17_L_T2_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/17_PR_T1_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/17_PR_T2_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/19_EU_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/20_MN_T1_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/20_MN_T2_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/21_DEP_T1_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/21_DEP_T2_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/21_REG_T1_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/21_REG_T2_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/22_L_T1_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/22_L_T2_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/22_PR_T1_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/22_PR_T2_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/harmonized/24_EU_harmonized.csv` | CSV harmonisé par scrutin | généré |
| `data/interim/unmapped_nuances.csv` | Données intermédiaires long format | généré |
| `data/mapping_candidats_blocs.csv` | Mapping nuances -> blocs (base) | actif |
| `data/mappings/category_mapping.csv` | Copie/variante de mapping | hérité (début projet) |
| `data/processed/bv_features.parquet` | Features legacy (utilisées par app/app.py) | hérité (début projet) |
| `data/processed/data_dictionary.md` | Dictionnaire de données généré | généré (doc) |
| `data/processed/elections_blocs.csv` | Dataset blocs (filtré communes) | généré (utilisé) |
| `data/processed/elections_blocs.parquet` | Dataset blocs (filtré communes) | généré (utilisé) |
| `data/processed/history_cache.parquet` | Cache local (historique/prédictions) | généré (cache) |
| `data/processed/panel.csv` | Panel features+cibles | généré (utilisé) |
| `data/processed/panel.parquet` | Panel features+cibles | généré (utilisé) |
| `data/processed/predictions_cache.parquet` | Cache local (historique/prédictions) | généré (cache) |
| `data/processed/predictions_municipales_2026.csv` | Exports de prédictions | généré (résultats) |
| `data/processed/predictions_municipales_2026_blocs.csv` | Exports de prédictions | généré (résultats) |
| `data/processed/predictions_municipales_sete_2026.csv` | Exports de prédictions | généré (résultats) |
| `data/raw/14_EU.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/14_MN14_T1T2.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/17_L_T1.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/17_L_T2.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/17_PR_T1.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/17_PR_T2.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/19_EU.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/20_MN_T1.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/20_MN_T2.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/21_DEP_T1.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/21_DEP_T2.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/21_REG_T1.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/21_REG_T2.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/22_L_T1.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/22_L_T2.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/22_PR_T1.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/22_PR_T2.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/24_EU.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/24_L_T1.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `data/raw/24_L_T2.csv` | Données brutes (entrée prétraitement) | actif (entrée pipeline) |
| `datasets/.DS_Store` | Métadonnées macOS | système (inutile) |
| `datasets/14_EU.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/14_MN14_T1T2.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/17_L_T1.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/17_L_T2.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/17_PR_T1.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/17_PR_T2.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/19_EU.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/20_MN_T1.tsv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/20_MN_T2.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/21_DEP_T1.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/21_DEP_T2.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/21_REG_T1.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/21_REG_T2.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/22_L_T1.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/22_L_T2.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/22_PR_T1.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/22_PR_T2.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/24_EU.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/24_L_T1T2.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `datasets/24_L_T2.csv` | Copie brute des datasets (ancienne structure) | hérité (début projet) |
| `docker-compose.yml` | Services Docker (PostgreSQL/pgAdmin) | actif |
| `harmoniser.md` | Notes d'harmonisation | optionnel |
| `main.py` | Orchestrateur pipeline (CLI utilitaire) | optionnel |
| `mission.md` | Backlog / notes projet | optionnel |
| `models/best_model.json` | Nom du meilleur modèle | généré (utilisé) |
| `models/feature_columns.json` | Liste des features du modèle | généré (utilisé) |
| `models/hist_gradient_boosting.joblib` | Modèle entraîné | généré (utilisé) |
| `models/model_card.md` | Model card (synthèse) | généré (doc) |
| `notebooks/01_pretraitement.ipynb` | Notebook d'analyse / exploration | optionnel (exploration) |
| `notebooks/02_feature_engineering.ipynb` | Notebook d'analyse / exploration | optionnel (exploration) |
| `notebooks/03_modelisation_prediction.ipynb` | Notebook d'analyse / exploration | optionnel (exploration) |
| `notebooks/aed.ipynb` | Notebook d'analyse / exploration | optionnel (exploration) |
| `notebooks/catboost_info/catboost_training.json` | Artefacts CatBoost (notebook) | généré |
| `notebooks/catboost_info/learn/events.out.tfevents` | Artefacts CatBoost (notebook) | généré |
| `notebooks/catboost_info/learn_error.tsv` | Artefacts CatBoost (notebook) | généré |
| `notebooks/catboost_info/time_left.tsv` | Artefacts CatBoost (notebook) | généré |
| `output/.DS_Store` | Métadonnées macOS | système (inutile) |
| `output/Sans titre 2.png` | Exports graphiques | hérité (début projet) |
| `output/Sans titre 3.png` | Exports graphiques | hérité (début projet) |
| `output/Sans titre 4.png` | Exports graphiques | hérité (début projet) |
| `output/Sans titre 5.png` | Exports graphiques | hérité (début projet) |
| `output/Sans titre 6.png` | Exports graphiques | hérité (début projet) |
| `output/Sans titre.png` | Exports graphiques | hérité (début projet) |
| `output/output.png` | Exports graphiques | hérité (début projet) |
| `predictions/pred_municipales_2026_sete.csv` | Exports de prédictions | généré (résultats) |
| `reports/colonnes_comparatif.csv` | Rapport / métriques | généré |
| `reports/cv_summary.csv` | Rapport / métriques | généré |
| `reports/figures/mae_per_category.png` | Figures de rapports | généré |
| `reports/metrics.json` | Rapport / métriques | généré |
| `reports/metrics.md` | Rapport / note analytique | généré (doc) |
| `reports/notebook_audit.md` | Rapport / note analytique | généré (doc) |
| `requirements.txt` | Dépendances Python | actif |
| `src/__init__.py` | Package src (init) | actif |
| `src/constants.py` | Constantes projet | actif |
| `src/data/__init__.py` | Module data | actif |
| `src/data/preprocess.py` | Prétraitement/harmonisation | actif |
| `src/data_prep.py` | Librairie d'harmonisation des données | actif |
| `src/database.py` | Accès base SQL (fallback/app) | actif |
| `src/db/__init__.py` | Module DB | actif |
| `src/db/ingest.py` | Ingestion PostgreSQL | actif |
| `src/db/schema.py` | Schéma PostgreSQL | actif |
| `src/features/__init__.py` | Module features | actif |
| `src/features/build_features.py` | Construction du panel features+cibles | actif |
| `src/model/predict.py` | Prédiction hors ligne | actif |
| `src/model/train.py` | Entraînement + CV | actif |
| `src/pipeline.py` | Pipeline de construction (blocs + stats) | actif |
| `src/prediction.py` | Prédiction legacy (app.py) | hérité (début projet) |
| `supports/Plan-2024_Bureaux-de-vote.pdf` | Documents de référence | optionnel |
| `supports/zonages_admin_canton.pdf` | Documents de référence | optionnel | |