- 🚀 Objectif du projet
- 🧰 Stack technologique
- ⚡ Démarrage rapide
- 🛠️ Commandes Make
- 🧪 Procédure de soutenance
- 📦 Utilisation
- 📝 Données
- 🧠 Architecture
- 🛠️ Fichiers de configuration
- 🧪 Tests
- 🔍 Qualité du code
- 📚 Documentation liée
- 🛡️ Licence
Implémenter un premier algorithme de Machine Learning : une régression linéaire simple.
👉 Prédire le prix d’une voiture en fonction de son kilométrage via :
- Deux programmes obligatoires :
train.py
→ entraîne le modèle (descente de gradient, mise à jour simultanée de θ).predict.py
→ prédit un prix à partir d’un kilométrage (0 avant entraînement).
🎯 Conformité stricte à l’énoncé 42 :
- Pas de
numpy.polyfit
/sklearn.LinearRegression
. - θ sauvegardés entre runs dans
theta.json
. - Prédiction = 0 avant tout entraînement.
- Pas de crash en soutenance.
- Python : 3.10.18 (Ubuntu 22.04.5 Jammy)
- Gestion dépendances : Poetry
- Qualité / CI :
pytest
,coverage
,ruff
,mypy
,mutmut
(mutation testing) - Visualisation (bonus uniquement) : matplotlib (installé sur demande via
poetry install --with viz
)
En cas d’entrée invalide (ex. kilométrage négatif ou non numérique) : le programme écrit un message
ERROR: ...
sur stderr et quitte avec exit 2.
# Avec Poetry (recommandé)
poetry install --with dev
ℹ️ Bonus non installé par défaut
Pour activer uniquement la visualisation bonus :
poetry install --with viz --with dev
# Entraînement
poetry run train --data data/samples/data.csv --alpha 0.1 --iters 1000 --theta theta.json
# Prédiction
poetry run predict 85000 --theta theta.json
ℹ️ Si la droite rouge affichée par
viz
reste quasiment horizontale, vérifiez le contenu detheta.json
. Une valeur de--alpha
trop faible (par exemple1e-7
) laisse les coefficients proches de zéro. Utilisez--alpha 0.1
(ou0.01
) et suffisamment d'itérations pour obtenir une pente négative réaliste.
Les principales cibles du Makefile facilitent l'installation, la qualité du code et l'utilisation du modèle :
Commande | Description |
---|---|
make install |
Installe les dépendances avec Poetry (groupe dev inclus). |
make lint |
Analyse statique du code avec Ruff. |
make format |
Formate le code et applique les corrections automatiques de Ruff. |
make type |
Vérifie les types avec Mypy. |
make test |
Lance les tests unitaires via Pytest. |
make cov |
Produit les rapports de couverture (JSON, HTML, console). |
make mut |
Exécute les tests de mutation avec Mutmut. |
make train |
Entraîne le modèle ; variables personnalisables : DATA , ALPHA , ITERS , THETA . |
make predict [km] |
Prédit le prix pour un kilométrage donné. |
make viz |
(Bonus) Affiche les données et la droite de régression. |
Scénario officiel à démontrer en soutenance, en trois étapes obligatoires :
Étape A : prédiction avant tout entraînement
Suppression du fichier de paramètres
rm -f theta.json
python3 -m src.predict 50000 --theta theta.json
→ Résultat attendu : 0 (θ₀=0, θ₁=0 par défaut)
Étape B : entraînement du modèle
poetry run train --data data.csv --alpha 0.1 --iters 1000 --theta theta.json
→ Apprentissage des paramètres θ₀ et θ₁, sauvegardés dans theta.json
Étape C : prédiction après entraînement → Résultat attendu : prix non nul, cohérent avec la droite apprise (≈ CSV)
python3 -m src.predict 50000 --theta theta.json
Évaluable uniquement si le mandatory est parfait. Non requis pour la soutenance.
poetry run python -m src.viz --data data.csv --theta theta.json --show-residuals
Ajoutez --show-residuals
pour tracer des lignes verticales représentant les résidus.
Utilisez --sigma-k
(défaut 2
) pour colorer en orange les points dont
|résidu| > k·σ
; ils sont ajoutés à la légende sous le nom « outliers ».
Nuage de points et droite θ₀ + θ₁·x (après entraînement).
La pente se met en place itération par itération (cliquer pour la galerie).
➡️ Voir la galerie complète : docs/regression_lineaire.md
Une analyse pédagogique pas à pas montre pourquoi la bande est étroite au centre et large aux extrêmes.
Bande de confiance autour de la droite de régression (extrait).
👉 Voir docs/confidence_band.md
- Mode interactif :
predict.py
demande un kilométrage si non fourni.
$ make predict
poetry run predict --theta theta.json
Enter mileage: 23000
Predicted price: 7991.88 €
- End-to-End :
predict (0)
→train
→predict ≈ prix
.
- Fichier :
data/samples/data.csv
(colonneskm,price
). - Hypothèses :
- km ≥ 0
- valeurs numériques uniquement
- 24 lignes d’exemple (corrélation ≈ −0,86)
.
├── AGENTS.md
├── author
├── codecov.yml
├── CONTRIBUTING.md
├── coverage.json
├── data
│ ├── benchmarks
│ │ ├── data_anscombe_I.csv
│ │ ├── data_anscombe_II.csv
│ │ ├── data_anscombe_III.csv
│ │ ├── data_anscombe_IV.csv
│ │ ├── data_away.csv
│ │ ├── data_bullseye.csv
│ │ ├── data_circle.csv
│ │ ├── data_collinear.csv
│ │ ├── data.csv
│ │ ├── data_dino.csv
│ │ ├── data_dots.csv
│ │ ├── data_duplicate.csv
│ │ ├── data_flat.csv
│ │ ├── data_high_lines.csv
│ │ ├── data_h_lines.csv
│ │ ├── data_inverse.csv
│ │ ├── data_noise.csv
│ │ ├── data_nonlinear.csv
│ │ ├── data_outlier.csv
│ │ ├── data_slant_down.csv
│ │ ├── data_slant_up.csv
│ │ ├── data_small.csv
│ │ ├── data_sparse.csv
│ │ ├── data_star.csv
│ │ ├── data_step.csv
│ │ ├── data_v_lines.csv
│ │ ├── data_wide_lines.csv
│ │ └── data_x_shape.csv
│ └── samples
│ └── data.csv
├── docs
│ ├── assets
│ │ └── plots
│ │ ├── confiance
│ │ │ ├── fig01_donnees.png
│ │ │ ├── fig02_droite_ols.png
│ │ │ ├── fig03_residus_sigma.png
│ │ │ ├── fig04_effet_levier.png
│ │ │ ├── fig05_SE.png
│ │ │ ├── fig06_bande_95.png
│ │ │ └── fig07_tableau.png
│ │ ├── examples
│ │ │ └── price-vs-km-regression.png
│ │ └── regression
│ │ ├── etape1_donnees_brutes.png
│ │ ├── etape2_droite_initiale.png
│ │ ├── etape3_droites_successives.png
│ │ ├── etape4_erreurs_initiales.png
│ │ ├── etape5_erreurs_finales.png
│ │ ├── etape6_theta0_vs_iter.png
│ │ ├── etape7_theta1_vs_iter.png
│ │ └── etape8_cout_vs_iter.png
│ ├── confidence_band.md
│ └── regression_lineaire.md
├── LICENSE
├── Makefile
├── poetry.lock
├── poetry.toml
├── pyproject.toml
├── README.md
├── src
│ ├── linear_regression.py
│ ├── metrics.py
│ ├── predict
│ │ ├── __init__.py
│ │ ├── __main__.py
│ │ └── predict.py
│ ├── train
│ │ ├── __init__.py
│ │ ├── __main__.py
│ │ └── train.py
│ └── viz.py
└── tests
├── test_accuracy_main.py
├── test_cli.py
├── test_data_parsing.py
├── test_e2e.py
├── test_estimate_price.py
├── test_gradient.py
├── test_json.py
├── test_main_modules.py
├── test_metrics.py
├── test_parser.py
├── test_predict_logic.py
└── test_viz.py
(Bonus : viz.py
affiche données + droite de régression)
Les tests E2E vérifient aussi les messages d’erreurs exacts (snapshot) et les codes de sortie (0/1/2).
pyproject.toml
(Poetry, dépendances, lint, type check)- Groupe optionnel [tool.poetry.group.viz] (non installé par défaut, réservé au bonus)
requirements.txt
(fallback sans Poetry).coveragerc
,.gitignore
,Makefile
(raccourcis CI/CD)- Note :
theta.json
est listé dans.gitignore
→ ne jamais le versionner.
- Portée des tests (mandatory) :
train.py
,predict.py
,io_utils.py
, CLI, I/O θ, stratégie GD. viz.py
est hors mandatory et hors périmètre des exigences minimales (peut être testé si le bonus est activé).
- Comparaisons float avec
pytest.approx
uniquement (rtol=1e-2
), jamais==
. - Test dédié qui échoue si la mise à jour des θ n’est pas simultanée (utilisation de temporaires).
- Tests robustesse I/O : CSV manquant, colonnes inattendues, valeurs non numériques, JSON
theta
absent/corrompu. - Vérification des messages d’erreurs et codes retour (exemples attendus) :
ERROR: invalid CSV format (expected columns: km,price)
→ exit 2ERROR: invalid mileage (must be a non-negative number)
→ exit 2ERROR: theta file not found: <path>
→ exit 2
predict(0)=0
→train
→predict(km_csv) ≈ price
.- CLI
--help
(exit 0), erreurs d’options (exit ≠ 0, message).- Entrée interactive : prompt si kilométrage manquant, gestion EOF/pipe.
pytest -q
coverage run -m pytest
coverage json
coverage report --fail-under=100
coverage html --skip-empty --show-contexts
Les programmes doivent imprimer ces messages à l’identique sur stderr et quitter avec le code indiqué.
ERROR: theta file not found: <path>
→ exit 2ERROR: invalid CSV format (expected columns: km,price)
→ exit 2ERROR: invalid mileage (must be a non-negative number)
→ exit 2
Règles générales :
- 0 : exécution nominale (train/predict OK).
- 2 : erreur d’usage/entrée/I‑O/validation (fichier manquant, CSV invalide, saisie invalide, etc.).
- 1 : erreur interne inattendue (exception non prévue).
Tests recommandés :
- Snapshot minimal des messages d’aide (
--help
) et d’erreur (texte essentiel, stable). - Asserts explicites sur
returncode
(0, 1 ou 2 selon les cas).
✅ Objectifs qualité (mandatory) :
- Coverage 100 % (statements + branches + diff + contrôle fichier).
- Mutation testing ≥90 % (scope global mandatory, avec survivants justifiés).
- Tolérance floats stricte : toujours utiliser
pytest.approx(..., rel=1e-2)
(jamais==
sur floats). - Test dédié “MAJ simultanée” : un test échoue explicitement si θ₀, θ₁ sont mis à jour séquentiellement (sans temporaires).
- Tests E2E :
predict(0)=0 → train → predict≈csv
. - Tests robustesse I/O : CSV manquant, mal formé, km négatif, NaN, EOF/pipe.
- Tests CLI :
--help
, erreurs d’options → exit ≠ 0 avec message clair. - Codes retour : 0 succès, ≠0 échec.
- Formatage & imports :
ruff format
,isort
. - Typage statique :
mypy
. - Lint :
ruff check
. - CI/CD Ubuntu-only (GitHub Actions).
- Hooks
pre-commit
pour vérifier format/lint/tests rapides avant commit.
AGENTS.md
→ Blueprint complet CI/CD + checklist défense-proof.ft_linear_regression_checklist_défense-proof.txt
→ Qualité tests & couverture.ft_linear_regression_murphy_law.txt
→ Risques & contre-mesures.- Énoncé officiel : ft_linear_regression.en.subject.pdf.
- Le bonus est cloisonné : il ne doit pas interférer avec le mandatory ni impacter la CI de base.
Les contenus suivants ont été essentiels pour comprendre et implémenter la régression linéaire et l’algorithme du gradient :
-
🎥 Playlist YouTube — Machine Learning from Scratch
Série pédagogique détaillant les fondements du Machine Learning et la régression linéaire. -
📄 Wikipédia — Fonction linéaire (analyse)
Définitions et propriétés mathématiques de la fonction linéaire. -
📄 Wikipédia — Algorithme du gradient
Explication théorique de la descente de gradient et de ses applications en optimisation.