Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
"source": [
"<< [App-17b VRP-Logistics (Python)](App-17b-VRP-Logistics-Python.ipynb) | [Index Search](../README.md) | [App-18 HyperparameterTuning (Python OR-Tools/Optuna)](App-18-HyperparameterTuning.ipynb) >>\n",
"\n",
"# App-18b : Optimisation d'Hyperparametres (Python — From-Scratch)\n",
"# App-18b : Optimisation d'Hyperparamètres (Python — From-Scratch)\n",
"\n",
"> **Twin Python** de [`App-18b-HyperparameterTuning-CSharp.ipynb`](App-18b-HyperparameterTuning-CSharp.ipynb). Le jumeau Python existant ([`App-18`](App-18-HyperparameterTuning.ipynb)) utilise scikit-learn + Optuna. Cette PR livre un **twin Python from-scratch** (numpy pur) aligne sur la version C# BCL pure : k-NN from-scratch + Grid/Random + **Bayesian Optimization avec Gaussian Process + Expected Improvement** + **Algorithme Genetique** + **Particle Swarm Optimization**, avec pont de verification SOTA Optuna.\n",
"> **Twin Python** de [`App-18b-HyperparameterTuning-CSharp.ipynb`](App-18b-HyperparameterTuning-CSharp.ipynb). Le jumeau Python existant ([`App-18`](App-18-HyperparameterTuning.ipynb)) utilise scikit-learn + Optuna. Cette PR livre un **twin Python from-scratch** (numpy pur) aligné sur la version C# BCL pure : k-NN from-scratch + Grid/Random + **Bayesian Optimization avec Gaussian Process + Expected Improvement** + **Algorithme Génétique** + **Particle Swarm Optimization**, avec pont de vérification SOTA Optuna.\n",
"\n",
"## Pourquoi un twin from-scratch ?\n",
"\n",
"Le marathon [EPIC #4956](https://github.com/jsboige/CoursIA/issues/4956) vise la parite .NET ⇄ Python des series de notebooks. Pour App-17b, le jumeau Python (`App-17b-VRP-Logistics-Python`) a ete ajoute pour offrir la version Python from-scratch a cote de la version OR-Tools. Le meme gap existait pour App-18 : seul le twin Python OR-Tools/Optuna etait present. Cette PR ferme le gap avec une implementation numpy pure des algorithmes classiques d'optimisation d'hyperparametres."
"Le marathon [EPIC #4956](https://github.com/jsboige/CoursIA/issues/4956) vise la parité .NET ⇄ Python des séries de notebooks. Pour App-17b, le jumeau Python (`App-17b-VRP-Logistics-Python`) a été ajouté pour offrir la version Python from-scratch à côté de la version OR-Tools. Le même gap existait pour App-18 : seul le twin Python OR-Tools/Optuna était présent. Cette PR ferme le gap avec une implémentation numpy pure des algorithmes classiques d'optimisation d'hyperparamètres."
]
},
{
Expand All @@ -23,9 +23,9 @@
"source": [
"## Objectifs d'apprentissage\n",
"\n",
"1. **Formaliser** le tuning d'hyperparametres comme un probleme d'optimisation black-box : un k-NN avec 3 hyperparametres (`k`, `distancePower`, `weightBlend`) et un objectif **CV 3-fold**.\n",
"2. **Comparer** 5 strategies : Grid Search, Random Search, Bayesian Optimization (Gaussian Process + Expected Improvement), Algorithme Genetique, Particle Swarm Optimization.\n",
"3. **Verifier** le from-scratch contre la bibliotheque SOTA **Optuna** (pont de mesure cellule 12).\n",
"1. **Formaliser** le tuning d'hyperparamètres comme un problème d'optimisation black-box : un k-NN avec 3 hyperparamètres (`k`, `distancePower`, `weightBlend`) et un objectif **CV 3-fold**.\n",
"2. **Comparer** 5 stratégies : Grid Search, Random Search, Bayesian Optimization (Gaussian Process + Expected Improvement), Algorithme Génétique, Particle Swarm Optimization.\n",
"3. **Vérifier** le from-scratch contre la bibliothèque SOTA **Optuna** (pont de mesure cellule 12).\n",
"4. **Visualiser** les courbes de convergence et la carte de chaleur 2D de l'objectif."
]
},
Expand All @@ -34,9 +34,9 @@
"id": "83857a33",
"metadata": {},
"source": [
"## 1. Configuration et jeu de donnees\n",
"## 1. Configuration et jeu de données\n",
"\n",
"On genere un jeu de donnees de **classification binaire 2D** deterministe (deux amas gaussiens chevauchants, pour que la precision du k-NN depende sensiblement des hyperparametres)."
"On génère un jeu de données de **classification binaire 2D** déterministe (deux amas gaussiens chevauchants, pour que la précision du k-NN dépende sensiblement des hyperparamètres)."
]
},
{
Expand Down Expand Up @@ -115,14 +115,14 @@
"id": "8bee9a34",
"metadata": {},
"source": [
"## 2. Modele cible : k-NN from-scratch et objectif (CV 3-fold)\n",
"## 2. Modèle cible : k-NN from-scratch et objectif (CV 3-fold)\n",
"\n",
"Le k-NN est le modele le plus simple a implementer from-scratch et suffit a definir un objectif **reel** (precision de classification) que toutes les strategies vont optimiser. L'objectif est l'**accuracy moyenne sur 3-fold CV stratifie**.\n",
"Le k-NN est le modèle le plus simple à implémenter from-scratch et suffit à définir un objectif **réel** (précision de classification) que toutes les stratégies vont optimiser. L'objectif est l'**accuracy moyenne sur 3-fold CV stratifié**.\n",
"\n",
"Les hyperparametres a optimiser :\n",
"Les hyperparamètres à optimiser :\n",
"- `k` (entier impair, 1..21) : nombre de voisins\n",
"- `distancePower` (reel, 1..4) : exposant de la distance de Minkowski (1 = Manhattan, 2 = Euclidien)\n",
"- `weightBlend` (reel, 0..1) : melange poids uniforme / poids par inverse-distance (0 = uniforme, 1 = full inverse-distance)"
"- `distancePower` (réel, 1..4) : exposant de la distance de Minkowski (1 = Manhattan, 2 = Euclidien)\n",
"- `weightBlend` (réel, 0..1) : mélange poids uniforme / poids par inverse-distance (0 = uniforme, 1 = full inverse-distance)"
]
},
{
Expand Down Expand Up @@ -198,9 +198,9 @@
"id": "b9240b95",
"metadata": {},
"source": [
"## 3. Methode de reference - Grid Search\n",
"## 3. Méthode de référence - Grid Search\n",
"\n",
"**Principe** : explorer systematiquement un sous-ensemble de combinaisons de l'espace. Exhaustif mais **exponentiel** : 5 valeurs par dimension x 3 dimensions = 125 evaluations."
"**Principe** : explorer systématiquement un sous-ensemble de combinaisons de l'espace. Exhaustif mais **exponentiel** : 5 valeurs par dimension x 3 dimensions = 125 évaluations."
]
},
{
Expand Down Expand Up @@ -257,9 +257,9 @@
"id": "7c3f38c9",
"metadata": {},
"source": [
"## 4. Methode de reference - Random Search\n",
"## 4. Méthode de référence - Random Search\n",
"\n",
"**Principe** (Bergstra & Bengio, 2012) : echantillonner uniformement dans l'espace. Contre-intuitivement, **aussi efficace que Grid Search** a budget egal si seulement quelques dimensions importent."
"**Principe** (Bergstra & Bengio, 2012) : échantillonner uniformément dans l'espace. Contre-intuitivement, **aussi efficace que Grid Search** à budget égal si seulement quelques dimensions importent."
]
},
{
Expand Down Expand Up @@ -316,7 +316,7 @@
"source": [
"### Exercice 1 : Vitesse de convergence\n",
"\n",
"Ecrire `iterations_to_threshold(history, fraction)` qui retourne le **nombre d'evaluations** necessaires pour atteindre `fraction x optimum_final` de la meilleure valeur. Comparer Grid vs Random vs les methodes sophistiqueques sur ce critere."
"Écrire `iterations_to_threshold(history, fraction)` qui retourne le **nombre d'évaluations** nécessaires pour atteindre `fraction x optimum_final` de la meilleure valeur. Comparer Grid vs Random vs les méthodes sophistiqueques sur ce critère."
]
},
{
Expand Down Expand Up @@ -349,7 +349,7 @@
"source": [
"## 5. Vedette - Bayesian Optimization (Gaussian Process + Expected Improvement)\n",
"\n",
"**Principe** : modeliser la fonction-objectif couteuse par un **surrogate** probabiliste - un **Gaussian Process** a noyau RBF - et choisir le prochain point en maximisant l'**Expected Improvement** (EI) sur le surrogate."
"**Principe** : modéliser la fonction-objectif coûteuse par un **surrogate** probabiliste - un **Gaussian Process** à noyau RBF - et choisir le prochain point en maximisant l'**Expected Improvement** (EI) sur le surrogate."
]
},
{
Expand Down Expand Up @@ -463,7 +463,7 @@
"id": "cell-bo-72d9369e",
"metadata": {},
"source": [
"**Pourquoi Bayes sous-performe-t-il ici (0.725 < Grid 0.733) ?** Le surrogate RBF du Gaussian Process **lisse le pic etroit de validation croisee** : sur ce paysage rugueux, l'optimum de k-NN tient sur environ un point-test par fold (un signal au niveau du bruit, +0.017 seulement). L'Expected Improvement explore donc une approximation lissee et manque le pic exact que GA et PSO atteignent par echantillonnage direct de la population. C'est le **compromis fondateur de l'optimisation bayesienne** : efficacite en echantillons (20 evaluations vs 125 pour Grid) au prix de la precision de peak-finding sur un paysage rugueux a faible signal. Ce n'est pas un defaut de l'algorithme -- c'est une propriete intrinseque du surrogate RBF."
"**Pourquoi Bayes sous-performe-t-il ici (0.725 < Grid 0.733) ?** Le surrogate RBF du Gaussian Process **lisse le pic étroit de validation croisée** : sur ce paysage rugueux, l'optimum de k-NN tient sur environ un point-test par fold (un signal au niveau du bruit, +0.017 seulement). L'Expected Improvement explore donc une approximation lissée et manque le pic exact que GA et PSO atteignent par échantillonnage direct de la population. C'est le **compromis fondateur de l'optimisation bayésienne** : efficacité en échantillons (20 évaluations vs 125 pour Grid) au prix de la précision de peak-finding sur un paysage rugueux à faible signal. Ce n'est pas un défaut de l'algorithme -- c'est une propriété intrinsèque du surrogate RBF."
]
},
{
Expand All @@ -473,7 +473,7 @@
"source": [
"### Exercice 2 : Fonction d'acquisition UCB (Upper Confidence Bound)\n",
"\n",
"Le BayesianOptimizer ci-dessus utilise **Expected Improvement**. Implementer l'acquisition **UCB** complementaire, plus exploratoire : `UCB(x) = mu(x) + kappa * sig(x)`. Comparer la trajectoire EI vs UCB sur le meme budget."
"Le BayesianOptimizer ci-dessus utilise **Expected Improvement**. Implémenter l'acquisition **UCB** complémentaire, plus exploratoire : `UCB(x) = mu(x) + kappa * sig(x)`. Comparer la trajectoire EI vs UCB sur le même budget."
]
},
{
Expand Down Expand Up @@ -501,9 +501,9 @@
"id": "af5d422e",
"metadata": {},
"source": [
"## 6. Algorithme Genetique (GA)\n",
"## 6. Algorithme Génétique (GA)\n",
"\n",
"**Principe** : faire evoluer une **population** de configurations via selection (tournoi), croisement (arithmetique), mutation (gaussienne decroissante) et elitisme."
"**Principe** : faire évoluer une **population** de configurations via sélection (tournoi), croisement (arithmétique), mutation (gaussienne décroissante) et élitisme."
]
},
{
Expand Down Expand Up @@ -584,12 +584,12 @@
"id": "24032017",
"metadata": {},
"source": [
"### Exercice 3 : Diversite d'une population genetique\n",
"### Exercice 3 : Diversité d'une population génétique\n",
"\n",
"Une population trop homogene signifie que l'algorithme a converge prematurement. Implementer `population_diversity(pop)` :\n",
"- Etape 1 : barycentre de la population.\n",
"- Etape 2 : dispersion moyenne au barycentre.\n",
"- Etape 3 : surveiller la diversite au fil des generations."
"Une population trop homogène signifie que l'algorithme a convergé prématurément. Implémenter `population_diversity(pop)` :\n",
"- Étape 1 : barycentre de la population.\n",
"- Étape 2 : dispersion moyenne au barycentre.\n",
"- Étape 3 : surveiller la diversité au fil des générations."
]
},
{
Expand Down Expand Up @@ -619,7 +619,7 @@
"source": [
"## 7. Particle Swarm Optimization (PSO)\n",
"\n",
"**Principe** : une nuee de particules ou chacune ajuste sa trajectoire selon (a) sa propre meilleure position (cognitive) et (b) la meilleure globale (sociale). Inertie + accelerations."
"**Principe** : une nuée de particules où chacune ajuste sa trajectoire selon (a) sa propre meilleure position (cognitive) et (b) la meilleure globale (sociale). Inertie + accélérations."
]
},
{
Expand Down Expand Up @@ -698,9 +698,9 @@
"id": "fa35d4cf",
"metadata": {},
"source": [
"## 8. Pont SOTA - verification contre Optuna\n",
"## 8. Pont SOTA - vérification contre Optuna\n",
"\n",
"On verifie que le BO from-scratch tient la distance face a **Optuna** (bibliotheque SOTA de reference). Mesure : Optuna (**0.733**) devance le BO from-scratch (**0.725**, +1.1%) et égalise Grid/Random - le from-scratch est **pedagogique** (transparence du GP/EI) mais **pas SOTA en performance pure**. C'est precisement l'enseignement : un surrogate GP-from-scratch reste lisible mais n'égale pas l'optimisation C-level de TPE."
"On vérifie que le BO from-scratch tient la distance face à **Optuna** (bibliothèque SOTA de référence). Mesure : Optuna (**0.733**) devance le BO from-scratch (**0.725**, +1.1%) et égalise Grid/Random - le from-scratch est **pédagogique** (transparence du GP/EI) mais **pas SOTA en performance pure**. C'est précisément l'enseignement : un surrogate GP-from-scratch reste lisible mais n'égale pas l'optimisation C-level de TPE."
]
},
{
Expand Down Expand Up @@ -790,9 +790,9 @@
"id": "b63feb3b",
"metadata": {},
"source": [
"## 9. Comparaison des methodes - courbes de convergence\n",
"## 9. Comparaison des méthodes - courbes de convergence\n",
"\n",
"On compare les **courbes de convergence** (meilleure accuracy observee en fonction du nombre d'evaluations) sur un budget comparable (~125 evaluations).\n",
"On compare les **courbes de convergence** (meilleure accuracy observée en fonction du nombre d'évaluations) sur un budget comparable (~125 évaluations).\n",
"\n",
"**Lecture attendue** : GA et PSO (**0.758**) dépassent les deux baselines Grid/Random (**0.733**) ; la Bayesian Optimization from-scratch à très petit budget (20 evals) reste légèrement en dessous (**0.725** vs 0.733) - l'efficacité-échantillons du GP-EI est un **régime** (budget et dimension favorables), pas une garantie à tout budget. Sur un objectif 3D bruité par la CV 5-fold, 20 evals ne suffisent pas au surrogate RBF pour exploiter le pic étroit que GA/PSO atteignent par population."
]
Expand Down Expand Up @@ -884,7 +884,7 @@
"source": [
"## 10. Visualisation de l'espace de recherche\n",
"\n",
"On visualise l'**objectif** (accuracy CV) sur une tranche 2D `(k, distancePower)` avec `weightBlend` fixe au meilleur trouve par BO."
"On visualise l'**objectif** (accuracy CV) sur une tranche 2D `(k, distancePower)` avec `weightBlend` fixé au meilleur trouvé par BO."
]
},
{
Expand Down Expand Up @@ -938,15 +938,15 @@
"source": [
"## Conclusion\n",
"\n",
"Ce notebook ferme le **gap b-variante App-18** pour le marathon de parite .NET ⇄ Python (EPIC [#4956](https://github.com/jsboige/CoursIA/issues/4956)). Le jumeau Python existant ([`App-18`](App-18-HyperparameterTuning.ipynb)) utilise scikit-learn + Optuna ; ce nouveau jumeau Python propose une version **from-scratch** (numpy pur) alignee sur le jumeau C# BCL pure ([`App-18b`](App-18b-HyperparameterTuning-CSharp.ipynb)).\n",
"Ce notebook ferme le **gap b-variante App-18** pour le marathon de parité .NET ⇄ Python (EPIC [#4956](https://github.com/jsboige/CoursIA/issues/4956)). Le jumeau Python existant ([`App-18`](App-18-HyperparameterTuning.ipynb)) utilise scikit-learn + Optuna ; ce nouveau jumeau Python propose une version **from-scratch** (numpy pur) alignée sur le jumeau C# BCL pure ([`App-18b`](App-18b-HyperparameterTuning-CSharp.ipynb)).\n",
"\n",
"**Resultats cles** :\n",
"**Résultats clés** :\n",
"- **GA et PSO** (**0.758**) dépassent nettement les deux baselines Grid/Random (**0.733**) - c'est la discrimination que l'anisotropie des amas rend visible.\n",
"- **Bayesian Optimization** from-scratch à très petit budget (20 evals, **0.725**) reste légèrement sous les baselines : l'efficacité-échantillons du GP-EI est un **régime** (budget/dimension favorables), pas une garantie à tout budget - leçon plus utile qu'une victoire annoncée.\n",
"- Le pont **Optuna** (cellule 12) mesure l'ecart avec la SOTA library : Optuna (**0.733**) égalise Grid/Random sans les dépasser, et devance le BO from-scratch de +1.1% (TPE optimise C-level).\n",
"- **Verdict SOTA-OK** ([EPIC #3801](https://github.com/jsboige/CoursIA/issues/3801)) : Optuna est proprement invoque comme verification independante, l'ecart est mesure honnetement. Le from-scratch est pedagogiquement justifie (transparence GP, EI acquisition) ; Optuna est industriellement optimise.\n",
"- Le pont **Optuna** (cellule 12) mesure l'écart avec la SOTA library : Optuna (**0.733**) égalise Grid/Random sans les dépasser, et devance le BO from-scratch de +1.1% (TPE optimisé C-level).\n",
"- **Verdict SOTA-OK** ([EPIC #3801](https://github.com/jsboige/CoursIA/issues/3801)) : Optuna est proprement invoqué comme vérification indépendante, l'écart est mesuré honnêtement. Le from-scratch est pédagogiquement justifié (transparence GP, EI acquisition) ; Optuna est industriellement optimisé.\n",
"\n",
"**Parite pedagogique** : les 5 methodes (Grid, Random, BO, GA, PSO) sont presentes dans les deux jumeaux Python et C#, avec les memes 3 exercices (IterationsToThreshold, UCB acquisition, PopulationDiversity). Le lecteur peut comparer les implementations et observer les idiomes Python (numpy, list comprehensions) vs C# (LINQ, delegates, static methods)."
"**Parité pédagogique** : les 5 méthodes (Grid, Random, BO, GA, PSO) sont présentes dans les deux jumeaux Python et C#, avec les mêmes 3 exercices (IterationsToThreshold, UCB acquisition, PopulationDiversity). Le lecteur peut comparer les implémentations et observer les idiomes Python (numpy, list comprehensions) vs C# (LINQ, delegates, static methods)."
]
}
],
Expand Down
Loading
Loading