veranoscience's picture
Update README.md
08cfbd8 verified
metadata
title: Attrition API (FastAPI)
colorFrom: purple
colorTo: indigo
sdk: docker
pinned: false

Prédiction de l’Attrition des Employés – TechNova Partners

Bienvenue dans ce projet de classification en Machine Learning dont l’objectif est d’analyser et prédire les démissions d’employés (attrition) au sein de l’ESN TechNova Partners, spécialisée dans le conseil en transformation digitale et la vente de solutions SaaS.

Ce dépôt contient l’ensemble du travail réalisé en tant que Consultant Data Scientist pour :

  • comprendre les facteurs clés derrière les démissions,
  • construire un modèle de prédiction de l’attrition,
  • produire des insights actionnables pour les équipes RH

Table des Matières


Contexte & objectifs

Problème : anticiper les départs d’employés (attrition) et expliquer les facteurs clés.

Objectifs:

  • Construire un pipeline scikit-learn (prétraitements + modèle RF)
  • Exposer une **API ** (FastAPI) avec Swagger/OpenAPI.
  • Tracer chaque prédiction (inputs/outputs) dans PostgreSQL
  • Mettre en place CI (tests) et CD (déploiement automatique).

Jeux de données

Trois sources principales sont mises à disposition :

  1. SIRH: poste, département, contrat, âge, ancienneté, salaire, etc.

  2. Évaluations de performance: notes annuelles, engagement/satisfaction, historiques RH.

  3. Sondage annuel employés: bien-être, charge, management, équilibre vie pro/perso.
    Variable cible (attrition = 1/0)

Ces différentes sources sont fusionnées et préparées pour construire un dataset modélisable.

Fichier aligné pour l’inférence : data/processed/df_central_norm.csv (contient le feature engineering attendu par le pipeline et les schémas SQL).


Approche

  • Préparation : encodages catégoriels, normalisation, features (exp_moins_3_years, etc.).

  • Modèle : RandomForestClassifier dans un Pipeline scikit-learn.

  • API : FastAPI + endpoints predict_one et predict_proba.

  • Traçabilité : table ml.predictions_log (inputs/outputs/threshold).

  • Déploiement : Docker → Hugging Face Spaces (CD GitHub Actions).

  • Qualité : Pytest + couverture, règles de branche et PR.


Structure du dépôt

.
├── src/
│   ├── __init__.py           
│   ├── data_preparation.py.   # chargement & split X/y (données traitées)
│   ├── train_model.py         # entraînement + sauvegarde artefact
│   └── utils.py               # utilitaires (chargement modèle, prédiction unitaire)
├── tests/
│   ├── test_data_preparation.py
│   └── test_predict.py
├── models/                    # artefact modèle 
├── data/
│   ├── raw/                   # fichiers brutsv(privé, ignoré) – .gitkeep 
│   └── processed/             # données traités (visibles)
├── db/
│   ├── attrition_local.session.sql    # schémas hr_staging/hr/ml + indexes + logs
│   ├── create_db.py                   # création table + exemple
│   └── load_csv.py                    # chargement CSV → hr.employees
├── notebooks/
│   ├── 01_analyse_exploratoire.ipynb
│   ├── 02_preprocessing.ipynb
│   └── 03_modelisation.ipynb
├── .github/workflows/
│   ├── ci.yml
│   └── deploy-to-hf-space.yml          
├── main.py                    # entraînement
├── pyproject.toml             # configuration de l'environnement & dépendances
├── requirements.txt.          # exporté depuis uv
├── README.md
├── .gitignore
└── uv.lock
├── Dockerfile                    # verrouillage précis des versions

Mise en place du modèle

  • Entraînement : notebooks 01_analyse_exploratoire.ipynb, 02_preprocessing.ipynb et 03_modelisation.ipynb.

  • Artefact modèle : model.joblib (hébergé sur Hugging Face Hub, téléchargé à l’inférence).

  • Chargement côté API : si models/model.joblib est absent, l’API télécharge depuis veranoscience/attrition-model.

  • Seuil : THRESHOLD=0.33pred = (proba >= 0.33)`.


API (FastAPI)

  • Doc Swagger : /docs

  • Endpoints principaux :

GET /health → statut, source du modèle (local ou hub), threshold.

POST /predict_one → prédiction unitaire (retourne proba et pred).

POST /predict_proba → prédictions batch (retourne listes probas et preds).

Exemple :

curl -s -X POST http://127.0.0.1:8000/predict_one \
  -H "Content-Type: application/json" \
  -d '{
    "age":41, "genre":"F", "revenu_mensuel":6000, "statut_marital":"Célibataire",
    "departement":"Consulting", "poste":"Consultant",
    "nombre_experiences_precedentes":6, "annees_dans_le_poste_actuel":2,
    "note_evaluation_precedente":3, "note_evaluation_actuelle":3,
    "heure_supplementaires":0, "augementation_salaire_precedente":12,
    "nombre_participation_pee":1, "nb_formations_suivies":2,
    "distance_domicile_travail":5, "niveau_education":2,
    "annees_depuis_la_derniere_promotion":1, "annes_sous_responsable_actuel":2,
    "satisfaction_globale":3.0, "exp_moins_3_years":0,
    "domaine_etude":"Infra & Cloud", "frequence_deplacement":"Occasionnel"
  }'
# → {"threshold":0.33,"proba":0.1443,"pred":0}

Base de données PostgreSQL

Objectif : assurer une traçabilité complète des échanges API ↔ modèle.

  • Schémas :

hr_staging : réception brute (employees_raw).

hr : table typée finale (employees) + index.

ml : table de log des inférences (predictions_log) + index.

  • Scripts :

db/attrition_local.session.sql → crée schémas/tables/index.

db/load_csv.py → charge data/processed/df_central_norm.csv dans hr.employees.

db/create_db.py → exemple alternatif (table simple predictions + insertion d’une ligne).

Activation du logging DB côté API (local) :

export DATABASE_URL="postgresql+psycopg2://appuser:appuser@localhost:5432/attrition"
uvicorn src.api.server:app --reload
# Chaque appel /predict_* crée une ligne dans ml.predictions_log

Installation locale

Prérequis

  • Python 3.10+

  • git

  • uv

  • PostgreSQL 15 local

(macOS : brew install postgresql@15)

Setup Python

uv venv && source .venv/bin/activate
uv sync

Démarrer l'API

uvicorn src.api.server:app --reload
# Swagger: http://127.0.0.1:8000/docs

Utilisation

  1. Lancer les notebooks

Depuis la racine du projet, avec l’environnement activé :

jupyter notebook

Puis ouvrir:

  • notebooks/01_analyse_exploratoire.ipynb pour l’analyse exploratoire

  • notebooks/02_preprocessing.ipynb pour le nettoyage & feature engineering

  • notebooks/03_modelisation.ipynb pour la modélisation et SHAP

Script (entrai&nement rapide)

python main.py

Un artefact est sauvegardé dans models/model.joblib

Healthcheck

curl -s http://127.0.0.1:8000/health | jq

Batch

curl -s -X POST http://127.0.0.1:8000/predict_proba \
  -H "Content-Type: application/json" \
  -d '{"inputs":[{ ... les mêmes champs que /predict_one ... }]}'

Workflow Git (branches / commits / tags)

  • Branche principale : main (protégée)
  • Conventions de branches : <type><-resume->
    • Types : feat, fix, docs, refactor, chore, test, data
    • Examples : docs/mise-a-jour-readme
  • Commits descriptifs: feat: ..., chore: ...
  • Tags de version : v0.1.0, v0.2.0, ...
    • Créer : git tag -a v0.1.0 -m "v0.1.0: base"
    • Pousser : git push origin v0.1.0

Résolution de conflits : utiliser l’outil intégré VS Code (Accept Current/Incoming → git add .git rebase --continue).


Traçabilité des prédictions

Activation : définir la variable d’env. DATABASE_URL avant de lancer l’API.

export DATABASE_URL="postgresql+psycopg2://appuser:appuser@localhost:5432/attrition"
uvicorn src.api.server:app --reload

À chaque appel réussi : insertion dans ml.predictions_log (date, payload, proba, classe, seuil, statut).

Requête de contrôle :

SELECT created_at, proba, pred, threshold, status
FROM ml.predictions_log
ORDER BY created_at DESC
LIMIT 5;

Tests & Couverture (CI)

Lancer localement :

uv run pytest
# avec couverture:
uv run pytest --cov=src --cov-report=term-missing

CI GitHub Actions (.github/workflows/ci.yml) :

  • installe l’environnement,

  • exécute Pytest,

  • calcule la couverture,

  • bloque la PR si la CI échoue.


Déploiement (CD) vers Hugging Face Spaces

  • Dockerfile à la racine.

  • Workflow deploy-to-hf-space.yml :

    • clone le repo du Space,

    • copie Dockerfile, pyproject.toml, src/, db/, README.md, etc.,

    • push vers le Space → rebuild automatique → API en ligne.

Secrets requis (GitHub → Settings → Secrets and variables → Actions) :

  • HF_TOKEN : token Hugging Face (scope write).

  • HF_SPACE_SLUG : slug owner/SpaceName (ex. veranoscience/OpenClassroomsProject).

Cycle CD :

  1. Crée une branche → commit → PR.

  2. Merge vers main.

  3. L’Action CD se lance et déploie sur le Space.

Déploiement HF Spaces (Docker)

  • Dockerfile à la racine. Le Space utilise sdk: docker.

Port par défaut 7860. L’API est servie par Uvicorn.

Modèle téléchargé au démarrage si absent localement.


Livrables

Le projet fournit :

  1. Dépôt Git structuré : code source, pyproject.toml, historique (branches/PR/tags), README.

  2. API FastAPI fonctionnelle, documentée (Swagger), déployée (Docker + HF Spaces).

  3. Tests Pytest + rapport de couverture (via CI).

  4. Base PostgreSQL : schémas SQL, scripts de création/chargement, logs d’inférence.

  5. CI/CD : GitHub Actions (CI PR & CD déploiement auto).



Auteur

Projet pédagogique - Ksenia Dautel