veranoscience's picture
Update README.md
08cfbd8 verified
---
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](#-contexte)
- [Jeux de données](#-jeux-de-données)
- [Approche](#-approche)
- [Structure du dépôt](#️-structure-du-dépôt)
- [Mise en place du modèle](#-mise-en-place-du-modèle)
- [API(FastAPI)](#-api-fastapi-api)
- [Base de donées PostgreSQL](#-base-de-données-postgresql)
- [Installation](#️-installation)
- [Utilisation](#️-utilisation)
- [Workflow Git](#workflow-git-branches--commits--tags-workflow)
- [Traçabilité des prédictions](#traçabilité-des-prédiction)
- [Tests & Couverture (CI)](#tests--couverture-ci)
- [Déploiement(CI/CD)](#déploiement-cd-vers-hugging-face-spaces)
- [Déploiment HF Spaces (Docker)](#déploiement-hf-spaces-docker)
- [Livrables](#-livrables)
- [Auteur](#-auteur)
---
<a id="-contexte"></a>
## 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).
---
<a id="-jeux-de-données"></a>
## 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).
---
<a id="-approche"></a>
## 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.
---
<a id="-structure-du-dépôt"></a>
## Structure du dépôt
```text
.
├── 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
```
<a id="-mise-en-place-du-modèle"></a>
## 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.33``pred` = (proba >= 0.33)`.
---
<a id="-api-fastapi"></a>
## 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 :
```bash
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}
```
---
<a id="-base-de-données-postgresql"></a>
## 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) :
```bash
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
```
---
<a id="-installation"></a>
## Installation locale
**Prérequis**
- Python 3.10+
- git
- [uv](https://github.com/astral-sh/uv)
- PostgreSQL 15 local
(macOS : `brew install postgresql@15`)
## Setup Python
```bash
uv venv && source .venv/bin/activate
uv sync
```
## Démarrer l'API
```bash
uvicorn src.api.server:app --reload
# Swagger: http://127.0.0.1:8000/docs
```
---
<a id="-utilisation"></a>
## Utilisation
1. Lancer les notebooks
Depuis la racine du projet, avec l’environnement activé :
```bash
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)
```bash
python main.py
```
Un artefact est sauvegardé dans `models/model.joblib`
Healthcheck
```bash
curl -s http://127.0.0.1:8000/health | jq
```
Batch
```bash
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 ... }]}'
```
---
<a id="-workflow"></a>
## 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`).
---
<a id="-tracabilité"></a>
## Traçabilité des prédictions
Activation : définir la variable d’env. `DATABASE_URL` avant de lancer l’API.
```bash
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 :
```sql
SELECT created_at, proba, pred, threshold, status
FROM ml.predictions_log
ORDER BY created_at DESC
LIMIT 5;
```
---
<a id="-tests--couverture-ci"></a>
### Tests & Couverture (CI)
Lancer localement :
```bash
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.
---
<a id="-déploiement-cd-vers-hugging-face-spaces"></a>
## 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.
<a id="-docker"></a>
## 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.
---
<a id="-livrables"></a>
## 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).
---
---
<a id="-auteur"></a>
## Auteur
Projet pédagogique - Ksenia Dautel