Aller au contenu principal
Retour aux projets

Simulateur Parcoursup

Octobre 2025 Projet solo
WebData ScienceSimulation
Voir le projet Dépôt privé
Simulateur Parcoursup

Outil d'estimation des chances d'admission sur Parcoursup, basé sur les données ouvertes et une modélisation statistique explicable. L'application combine une API FastAPI et une interface React pour offrir une expérience interactive et transparente.

1. Collecte des données

a) Sources et fichiers d’entrée

  • Open data Parcoursup – statistiques : fr-esr-parcoursup.csv Effectifs, mentions, rang du dernier appelé, répartition par bac, boursiers, etc.
  • Cartographie des formations : fr-esr-cartographie_formations_parcoursup.csv Métadonnées (type d’établissement, apprentissage, internat, géolocalisation, liens).
  • Spécialités (bacheliers généraux) : fr-esr-parcoursup-enseignements-de-specialite-bacheliers-generaux.csv Doublettes de spécialités et effectifs admis.
  • Compléments géo : departements-france.csv Normalisation des codes départements.

Les champs de géolocalisation sont conservés à des fins d’affichage/diagnostic, sans effet direct dans le modèle (hors agrégations académiques).

b) Enrichissements par scraping

  • Fiches Parcoursup (formations) Récupération : présentation, attendus (en % quand disponible), répartition bac, jalons (candidats/admissibles/admis), conseils, détection concours.
  • Consolidation “concours” Étiquetage concours_label et, si disponibles, coefficients coeff_dossier/coeff_concours.
  • Fiches lycées (L’Étudiant) Cinq métriques « chiffres-clés » (réussite, mentions, nb d’élèves, effectif terminale, note/20) avec stratégies anti-blocage (retries, throttling, UA rotation).

2. Traitement des données

But : produire des tables “modèle-prêtes” via alignements de schémas, typages, imputations et indicateurs dérivés.

a) Nettoyage et fusion — Formations

  1. Indicateurs dérivés

    • Moyenne par mentions (pondérations 11/13/15/17/19).
    • Distance à l’échelle [8, 20] et dispersion proxy (depuis la distribution des mentions).
    • Biais genre BfB_f et boursiers BbB_b, bornés/normalisés.
    • Sélectivité S=1Rd/NS = 1 - R_d/N dans [0,1][0,1] (avec comblement si besoin).
  2. Cartographie 2025 & géo

    Normalisations (apprentissage → booléen, internat catégorisé, types), renommages, complétion des départements et villes, jointure avec table des départements.

  3. Harmonisation familles de formation

    Mapping exhaustif formation_type → formation (ex. « Licence sélective » → « Licence – STS »), contrôles de couverture.

  4. Ajout “concours”

    Ajout de concours et coeff_dossier, coeff_concours à partir de formations présentes dans certains concours (Sésame, Accès, Geipi-Polytech, Avenir, Advance, Puissance Alpha, IEP-Sciences Po).

b) Spécialités

  1. Open data

    Filtrage par millésime, couples (doublettes) → IDs stables (1..13), calcul de part_spe_admis par formation, ranking intra-formation.

  2. Scraping

    Colonnes combinationdoublette_i au format id1,id2 (via specialite2id).

c) Lycées

  1. Scraping robuste

    Enrichissement incrémental, typages, anti-blocage.

  2. Feature engineering & multiplicateur

    Décimaux (réussite, mentions), métrique x[0,1]x \in [0,1], indicateur infos.

    Transformation bornée en Mlycee[0.85,1.15]M_{lycee} \in [0.85, 1.15] via z-score → CDF → exponentielle ; si infos=0 alors Mlycee=1.0M_{lycee} = 1.0.

    Figure 1 : Pipeline de traitement des données

    Figure 1 : Pipeline de traitement des données

3. Établissement des métriques

Idée : convertir chaque facteur en multiplicateur MiM_i centré en 1, borné pour éviter les extrêmes, puis agréger.

  • Démographie (bornée, symétrique)

    Msexe=exp ⁣(kmax(2Bf1)s)M_{\text{sexe}} = \exp\!\big(k_{\max}\,(2B_f - 1)\cdot s\big) Mbourse=exp ⁣(kmax(2Bb1)t)M_{\text{bourse}} = \exp\!\big(k_{\max}\,(2B_b - 1)\cdot t\big)

    avec Bf,Bb[0,1]B_f, B_b \in [0,1], s,t{1,+1}s,t \in \{-1,+1\}, kmax=ln(1.025)k_{\max}=\ln(1.025) (~±2,5 %).

  • Notes générales (calibrées à la cohorte)

    Soit gg la moyenne du candidat, μ,σ\mu,\sigma celles de la formation (depuis les mentions).

    z=gμσ,p=Φ(z)z=\dfrac{g-\mu}{\sigma}, p=\Phi(z).

    Mnotes={exp ⁣(1.25ln(mmax)(2p1))si g<μexp ⁣(ln(mmax)(2p1))sinonM_{\text{notes}}=\begin{cases} \exp\!\big(1.25\,\ln(m_{\max})(2p-1)\big) & \text{si } g<\mu \\ \exp\!\big(\ln(m_{\max})(2p-1)\big) & \text{sinon} \end{cases}

    avec mmax=1.5m_{\max}=1.5

  • Notes de spécialités (cohérence)

    n=(s1+s2)/2μ5n=\dfrac{(s_1+s_2)/2 - \mu}{5} tronqué à [1,1][-1,1].

    Mnotes-spe={exp ⁣(2.5ln(1.5)n)si n<0exp ⁣(ln(1.5)n)sinonM_{\text{notes-spe}}=\begin{cases} \exp\!\big(2.5\,\ln(1.5)\,n\big) & \text{si } n<0 \\ \exp\!\big(\ln(1.5)\,n\big) & \text{sinon} \end{cases}
  • Type de bac (représentativité)

    Pour bacs non généraux : plancher mmin=0.6m_{\min}=0.6 selon la part observée pbp_b.

    Mbac={0si pb0min(max(3pb,mmin),1)sinonM_{\text{bac}}=\begin{cases} 0 & \text{si } p_b \le 0 \\ \min\big(\max(3p_b, m_{\min}), 1\big) & \text{sinon} \end{cases}
  • Doublette de spécialités (adéquation/rareté)

    Avec pspep_{\text{spe}} la part d’admis portant la doublette et pˉtop\bar p_{\text{top}} la moyenne des NN doublettes les plus fréquentes (souvent N=3N=3), poser r=min ⁣(pspe/pˉtop,1)r=\min\!\big(p_{\text{spe}}/\bar p_{\text{top}},\,1\big).

    Mdoublette={exp ⁣(2ln(1.15)(2r1))si r<0.5exp ⁣(ln(1.15)(2r1))sinonM_{\text{doublette}}=\begin{cases} \exp\!\big(2\,\ln(1.15)(2r-1)\big) & \text{si } r<0.5 \\ \exp\!\big(\ln(1.15)(2r-1)\big) & \text{sinon} \end{cases}
  • Lycée d’origine (contexte académique)

    Score agrégé x[0,1]x \in [0,1]z=xμxσxz=\dfrac{x-\mu_x}{\sigma_x}, p=Φ(z)p=\Phi(z).

    Mlycee=clamp ⁣(exp(k(2p1)),mmin,mmax)M_{\text{lycee}}=\operatorname{clamp}\!\big(\exp(k(2p-1)),\, m_{\min},\, m_{\max}\big)

    avec μx=0.548\mu_x=0.548, σx=0.182\sigma_x=0.182, mmin=0.85m_{\min}=0.85, k=ln(mmax)k=\ln(m_{\max}).

    Si infos=0 alors Mlycee=1M_{\text{lycee}}=1.

4. Modélisation choisie

a) Score agrégé

Le score global pour une formation ff est :

M=MsexeMbourseMbacMnotesMnotes-speMdoubletteMlyceeM = M_{\text{sexe}} \cdot M_{\text{bourse}} \cdot M_{\text{bac}} \cdot M_{\text{notes}} \cdot M_{\text{notes-spe}} \cdot M_{\text{doublette}} \cdot M_{\text{lycee}}

Tous les MiM_i sont plafonnés (bornes) pour rester stables et interprétables.

b) Conversion en percentile calibré

On suppose MM centré autour de 1 et on choisit σM\sigma_M tel que le 97,5e centile corresponde à :

σM=Mmax1Φ1(0.975)\sigma_M=\dfrac{M_{\max}-1}{\Phi^{-1}(0.975)}, zM=M1σMz_M=\dfrac{M-1}{\sigma_M}, P=Φ(zM)[0,1]P=\Phi(z_M)\in[0,1].

La valeur affichée est 100×P100\times P.

c) Décision à trois niveaux

  • Refusé si 100P<20100P<20
  • En attente si 20100P<5020\le 100P<50
  • Accepté si 100P50100P\ge 50

Seuils simples et ajustables par formation/millésime pour affiner la calibration locale.

d) Explicabilité

Outre PP, le service retourne le facteur principal (composante MiM_i dominante) afin d’expliquer le résultat (notes, doublette, type de bac, lycée, etc.). Les effets démographiques sont bornés et symétriques.

e) Cas “concours” (optionnel)

Si concours = 1, une pondération post-dossier est appliquée à partir d’une note de concours utilisateur et coefficients coeff_dossier/coeff_concours (quand disponibles).

Exemple : M1.440100P71.8M \simeq 1.440 \Rightarrow 100P \simeq 71.8 → Accepté.

5. Architecture backend

  • Framework : FastAPI (main.py) Config via core/config.py, middlewares (CORS, UserIdMiddleware), dépendances core/deps.py.
  • Infrastructure de Recherche : Intégration de Typesense, un moteur de recherche tolérant aux fautes de frappe et rapide, pour l’indexation et l’interrogation instantanée des formations et établissements.
  • Routeurs :
    • routers/simulate.py : API de simulation (modèle Profil, appel compute_admission).
    • routers/formations.py : recherche & stats formations (BM25, filtres géo, distributions).
    • routers/profiles.py : CRUD profils (Profile, Voeu).
    • routers/motive.py : génération et envoi de lettres (API OpenAI + Brevo).
    • routers/lycees.py : recherche de lycées (pondérations département/type).
    • routers/share.py : envoi des résultats par mail (rendu HTML, Brevo).
  • Base & ORM : db/database.py (SQLAlchemy / SQLite), models/profile.py.

Figure 2 : Documentation des endpoints de l’API

Figure 2 : Documentation des endpoints de l’API

6. Points d’attention backend

  • Mailing : /share/simulation → rendu HTML via _render_motive_body_html, envoi via Brevo (clés dans .env.local : BREVO_API_KEY, BREVO_EMAIL_SENDER).
  • Lettre de motivation : /motive/generate (génération), /motive/email (envoi).
  • Moteur de Recherche : Migration vers Typesense permettant la gestion des synonymes, la tolérance aux fautes de frappe et un tri pertinent des résultats.
  • Filtrage académique : frontend/constants/acad_map.json (département → académie/territoire).

7. Architecture frontend

  • Stack : React (Vite). Entrée main.jsx, app App.jsx.
  • Fonctionnalités avancées :
    • Thématisation dynamique : Système intelligent détectant l’URL d’origine pour adapter automatiquement le branding (logo, palette de couleurs, liens) et permettre un déploiement multi-site en marque blanche.
    • Partage et profils publics : Création de pages de profil publiques accessibles via URL unique, permettant aux vendeurs d’accéder facilement aux simulations et listes de vœux des élèves.
    • Comparateur de formations : Outil interactif permettant de comparer côte à côte plusieurs formations sur des critères clés (sélectivité, débouchés, attendus).

Figure 3 : Fiche profil accessible

Figure 3 : Fiche profil accessible

Figure 4 : Comparateur de formations

Figure 4 : Comparateur de formations

  • Dossiers clés :
    • api/api.js : appels aux endpoints (simulation, formations, profiles, motive, etc.).
    • components/ : details/, motivation/, registration/, search/.
    • constants/ : complete_form.json, concours.json, confidence_levels.json, factorExplains.js, tresholds.js.
    • context/ : état global, thème (styles/theme.css, utils/ThemeLogo.jsx).
    • pages/ : accueil, formations, simulateur, profil, lettre.
    • utils/ : pagination, conversions, helpers.

Figure 5 : Interface graphique de la page de recherche

Figure 5 : Interface graphique de la page de recherche

8. Mise en ligne

a) Hébergement Railway

Hébergement complet du backend et frontend avec une base de données PostgreSQL connectés et instance Typesense (Docker).

Figure 6 : Infrastructure Railway

Figure 6 : Infrastructure Railway

b) Automatisation n8n

  • Déclencheur : Planifié (Schedule Trigger) pour une exécution périodique.
  • Processus : Synchronisation quotidienne des données (Profils et Vœux) depuis la base de données vers des Google Sheets segmentés par client.
  • Finalité : Alimentation automatique des données de suivi et déclenchement de sous-workflows pour la mise à jour des tableaux de bord (Dashboards).

Figure 7 : Workflow automatisation n8n

Figure 7 : Workflow automatisation n8n

Ces projets pourraient vous intéresser

Exploration d'un Pipeline RAG
Exploration d'un Pipeline RAG2026

Exploration d'un Pipeline RAG

Benchmark d'un pipeline RAG et assemblage de l'outil dans un chat Chainlit.

Deep LearningNLPData Science
MCP Data Science
MCP Data Science2026

MCP Data Science

102 outils de data science pilotés en langage naturel via le protocole MCP d'Anthropic.

Data ScienceNLP