Modèle de Machine Learning pour estimer le prix médian des maisons en Californie, avec un pipeline MLOps complet : entraînement, tracking des expériences, mise en production via API et interface utilisateur, CI/CD, conteneurisation et monitoring du drift.
- Python 3.11 | scikit-learn | pandas | numpy
- MLflow — tracking des expériences et model registry
- FastAPI — API de prédiction
- Streamlit — interface utilisateur
- Docker — conteneurisation
- GitHub Actions — CI/CD
- GitHub Container Registry — hébergement des images Docker
- Evidently — détection du data drift
- Pytest — tests unitaires + couverture
- Ruff — linting
- uv — gestion des dépendances
Dataset California Housing — 20 640 observations, 8 features.
| Feature | Description |
|---|---|
| MedInc | Revenu médian (10K $) |
| HouseAge | Âge médian des maisons |
| AveRooms | Nombre moyen de pièces |
| AveBedrms | Nombre moyen de chambres |
| Population | Population du secteur |
| AveOccup | Occupation moyenne |
| Latitude / Longitude | Coordonnées géographiques |
Cible : MedHouseVal — prix médian (100K $)
| Modèle | RMSE | MAE | R² |
|---|---|---|---|
| Linear Regression | 0.7456 | 0.5332 | 0.5758 |
| Random Forest | 0.5051 | 0.3274 | 0.8053 |
| Gradient Boosting | 0.5422 | 0.3717 | 0.7756 |
Le Random Forest (R² = 0.81) a été retenu et enregistré dans le Model Registry MLflow.
immoprix/
├── .github/
│ └── workflows/
│ └── ci.yml # Pipeline CI/CD
├── docs/
│ └── retraining_strategy.md # Stratégie de réentraînement
├── notebooks/
│ └── exploration.ipynb # Analyse exploratoire + SHAP
├── reports/ # Rapports générés (drift, coverage)
├── src/
│ ├── api/
│ │ └── predict.py # API FastAPI
│ ├── app/
│ │ └── streamlit_app.py # Interface Streamlit
│ ├── modelisation/
│ │ └── train.py # Entraînement + tracking MLflow
│ └── monitoring/
│ └── drift_report.py # Détection du data drift
├── tests/
│ ├── test_api.py # Tests API
│ ├── test_data.py # Tests données
│ └── test_streamlit.py # Tests Streamlit
├── Dockerfile # Image API
├── Dockerfile.streamlit # Image Streamlit
├── docker-compose.yml
├── Makefile
├── .env.example
├── pyproject.toml
└── README.md
# Lancer l'API
docker run -d -p 8000:8000 --name api \
-e USE_MLFLOW=false \
ghcr.io/ntwarigb/immoprix-api:latest
# Lancer Streamlit
docker run -d -p 8501:8501 --name streamlit \
--add-host=host.docker.internal:host-gateway \
-e API_URL=http://host.docker.internal:8000 \
ghcr.io/ntwarigb/immoprix-streamlit:latest| Service | URL |
|---|---|
| API (Swagger) | http://localhost:8000/docs |
| Streamlit | http://localhost:8501 |
git clone https://github.com/NtwariGB/MedHouseVal.git
cd MedHouseVal
cp .env.example .env
docker compose up --buildTous les services démarrent automatiquement : MLflow → Entraînement → API → Streamlit.
| Service | URL |
|---|---|
| MLflow | http://localhost:5000 |
| API (Swagger) | http://localhost:8000/docs |
| Streamlit | http://localhost:8501 |
git clone https://github.com/NtwariGB/MedHouseVal.git
cd MedHouseVal
uv venv
source .venv/bin/activate
uv sync
cp .env.example .env| Commande | Description |
|---|---|
make install |
Installer les dépendances |
make check |
Lancer lint + tests |
make test |
Lancer les tests + rapport de couverture |
make lint |
Vérifier la qualité du code |
make train |
Entraîner les modèles |
make mlflow |
Lancer le serveur MLflow |
make api |
Lancer l'API FastAPI |
make streamlit |
Lancer l'interface Streamlit |
make drift |
Générer le rapport de drift |
make docker-up |
Lancer la stack Docker |
make docker-down |
Arrêter la stack Docker |
make clean |
Nettoyer les fichiers cache |
Le pipeline GitHub Actions s'exécute à chaque push et PR sur main et develop :
- Check — lint avec Ruff + tests unitaires avec Pytest (couverture minimum 80%)
- Build & Serve (main uniquement) :
- Entraînement du modèle
- Détection du data drift (Evidently)
- Test du serving MLflow
- Test de l'API
- Build et push des images Docker sur GitHub Container Registry
Les rapports sont disponibles en tant qu'artefacts téléchargeables dans GitHub Actions :
| Artefact | Contenu |
|---|---|
coverage-report |
Rapport de couverture des tests (HTML) |
drift-report |
Rapport de data drift Evidently (HTML) |
Evidently compare les données d'entraînement (référence) aux données de production pour détecter les changements de distribution. Le drift est mesuré via la distance de Wasserstein normalisée (seuil : 0.1).
make driftLe rapport est généré dans reports/drift_report.html. La stratégie de réentraînement en cas de drift significatif est documentée dans docs/retraining_strategy.md.
| Variable | Description | Défaut |
|---|---|---|
MLFLOW_TRACKING_URI |
URL du serveur MLflow | http://localhost:5000 |
MODEL_NAME |
Nom du modèle dans le registry | Immoprix_randomForest_model |
MODEL_VERSION |
Version du modèle | 1 |
EXPERIMENT_NAME |
Nom de l'expérience MLflow | immoprix-california |
API_URL |
URL de l'API (pour Streamlit) | http://localhost:8000 |
USE_MLFLOW |
Charger le modèle via MLflow | true |
| Méthode | Route | Description |
|---|---|---|
GET |
/health |
Statut de l'API |
POST |
/predict |
Prédiction de prix |
Exemple de requête :
curl -X POST http://localhost:8000/predict \
-H "Content-Type: application/json" \
-d '{"MedInc": 8.32, "HouseAge": 41, "AveRooms": 6.98, "AveBedrms": 1.02, "Population": 322, "AveOccup": 2.56, "Latitude": 37.88, "Longitude": -122.23}'