Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -791,49 +791,19 @@
"source": [
"**Lecture — Doppler : le terrain non stationnaire, victoire nette de l'ondelette (sans oracle).** Le seuillage dur atteint **17,83 dB** (+8,86 dB sur le bruité), contre **13,36 dB** pour le meilleur Fourier — le cutoff *libre*, choisi en connaissant le signal — soit **+4,47 dB d'avance sans oracle**. Toutes les variantes Fourier s'effondrent ensemble (11,95 à 13,36 dB) parce que le problème est structurel : le §3 a montré que l'énergie du chirp est étalée sur toutes les échelles (top-3 détails = 32,9 % seulement). Un passe-bas doit donc choisir ce qu'il ampute : le cutoff libre sacrifie **1,70 % de l'énergie propre** — le début du chirp, précisément la partie haute fréquence — et le cutoff étroit (11,95 dB) ampute plus fort encore tout en gardant du bruit dans sa bande.\n",
"\n",
"Côté ondelette, la parcimonie est extrême : **51 coefficients de détail sur 2040** (2,5 %) survivent au seuil $\\lambda = 1{,}369$. Un chirp dont l'information occupe tout le spectre se représente par 51 nombres, parce que chaque portion temporelle du signal trouve *son* échelle — c'est exactement le troc temps-fréquence du §0."
]
},
{
"cell_type": "markdown",
"id": "8e7e8296",
"metadata": {
"papermill": {
"duration": 0.003847,
"end_time": "2026-09-14T03:04:46.073108",
"exception": false,
"start_time": "2026-09-14T03:04:46.069261",
"status": "completed"
},
"tags": []
},
"source": [
"Côté ondelette, la parcimonie est extrême : **51 coefficients de détail sur 2040** (2,5 %) survivent au seuil $\\lambda = 1{,}369$. Un chirp dont l'information occupe tout le spectre se représente par 51 nombres, parce que chaque portion temporelle du signal trouve *son* échelle — c'est exactement le troc temps-fréquence du §0.\n",
"\n",
"**Lecture — HeaviSine : le terrain mixte, quasi-égalité, et une lecture honnête.** Le Fourier *libre* (23,28 dB @ fc=0,0100) devance ici le seuillage dur (22,43 dB) de 0,85 dB. Trois observations pour ne pas se mentir :\n",
"\n",
"1. **Ce signal est presque à bande limitée** : 97,1 % de l'énergie dans l'approximation a8, amputation du cutoff libre = 0,19 % (presque rien). Quand le signal vit dans une bande étroite, le passe-bas optimal est presque idéal — nous sommes aussi sur le terrain de Fourier, et l'oracle peut choisir un cutoff qui ne détruit presque rien.\n",
"2. **L'ondelette gagne contre les Fourier non libres** : garde-tout 21,64 dB, étroit 18,94 dB, tous deux battus par 22,43 dB — sans aucune connaissance du signal.\n",
"3. **La parcimonie est stupéfiante** : 8 coefficients de détail sur 2040 (0,4 %). L'estimateur ondelette décrit ce signal par « deux sinus + deux sauts localisés » en quelques nombres — les sauts survivent comme quelques grands coefficients répartis sur toutes les échelles, les sinus dans l'approximation.\n",
"\n",
"Verdict honnête : quasi-égalité sur un terrain qui favorise Fourier, avec un estimateur qui n'a rien su du signal."
]
},
{
"cell_type": "markdown",
"id": "49cacd48",
"metadata": {
"papermill": {
"duration": 0.003999,
"end_time": "2026-09-14T03:04:46.082477",
"exception": false,
"start_time": "2026-09-14T03:04:46.078478",
"status": "completed"
},
"tags": []
},
"source": [
"Verdict honnête : quasi-égalité sur un terrain qui favorise Fourier, avec un estimateur qui n'a rien su du signal.\n",
"\n",
"**Lecture — Stationnaire + burst : le terrain de Fourier, assumé — et le contrepoint du transitoire.** Le passe-bas gagne nettement en SNR global : étroit **19,92 dB**, libre **21,19 dB** (amputation 0,37 %) contre **16,37 dB** pour l'ondelette. C'est le résultat attendu — deux tons éternels sont l'objet parfait de Fourier, et couper à fc = 0,025–0,05 élimine le bruit partout ailleurs. L'asymétrie de protocole joue aussi : ces cutoffs savent où vivent les tons.\n",
"\n",
"Le contrepoint est le **pic du burst** (valeur propre : 1,362). Toutes les méthodes le surestiment — le maximum d'un signal bruité est biaisé vers le haut — mais pas autant : dur **1,485** (écart +0,12), étroit 1,496 (+0,13), garde-tout 1,564 (+0,20). L'ondelette dure est la plus proche du vrai pic, le garde-tout la plus déformée. Surtout, le **doux écrase** le transitoire : pic 0,996, soit **−27 %** — les coefficients du burst, tout juste au-dessus du seuil, sont rétractés de $\\lambda$. Et le SNR local de l'ondelette dure (autour du burst) tombe à 11,44 dB : le transitoire reste le point dur des deux familles."
"Le contrepoint est le **pic du burst** (valeur propre : 1,362). Toutes les méthodes le surestiment — le maximum d'un signal bruité est biaisé vers le haut — mais pas autant : dur **1,485** (écart +0,12), étroit 1,496 (+0,13), garde-tout 1,564 (+0,20). L'ondelette dure est la plus proche du vrai pic, le garde-tout la plus déformée. Surtout, le **doux écrase** le transitoire : pic 0,996, soit **−27 %** — les coefficients du burst, tout juste au-dessus du seuil, sont rétractés de $\\lambda$. Et le SNR local de l'ondelette dure (autour du burst) tombe à 11,44 dB : le transitoire reste le point dur des deux familles.\n"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,23 +329,8 @@
"\n",
"**Reproductibilité.** Le notebook recharge le fichier versionné `sales_data.csv` à chaque exécution : les outils ADK travaillent donc sur le même jeu de données et les mêmes agrégats. Les valeurs citées dans les interprétations (revenus par région et top produits) restent vérifiables directement avec pandas.\n",
"\n",
"**Pourquoi un CSV.** L'agent ne reçoit pas le DataFrame brut dans son prompt. Les tools pandas fermés sur `df` effectuent les calculs puis transmettent seulement leurs retours structurés à l'agent. Le fichier matérialise le jeu de test sur disque et découple sa provenance de l'état du kernel."
]
},
{
"cell_type": "markdown",
"id": "cell-6",
"metadata": {
"papermill": {
"duration": 0.002657,
"end_time": "2026-09-04T10:22:16.601931+00:00",
"exception": false,
"start_time": "2026-09-04T10:22:16.599274+00:00",
"status": "completed"
},
"tags": []
},
"source": [
"**Pourquoi un CSV.** L'agent ne reçoit pas le DataFrame brut dans son prompt. Les tools pandas fermés sur `df` effectuent les calculs puis transmettent seulement leurs retours structurés à l'agent. Le fichier matérialise le jeu de test sur disque et découple sa provenance de l'état du kernel.\n",
"\n",
"### Lecture de l'implémentation : trois briques, une passe unique\n",
"\n",
"Le code ci-dessus repose sur trois briques fondamentales, et chacune porte une décision de conception claire :\n",
Expand All @@ -354,7 +339,7 @@
"\n",
"- **`run_agent_turn`** — le cœur opérationnel : cette fonction déclenche l'exécution de l'agent pour un tour unique. Elle encapsule l'appel au LLM, la validation des appels de tools selon leurs signatures typées, et retourne un objet `AdkRunResult` contenant la réponse textuelle, les appels de tools effectués avec leurs paramètres, et les métriques d'exécution. Le contexte est passé une seule fois, sans boucle de révision : une seule passe, comme le montre concrètement l'échec étudié dans la section 5. Cette simplicité est voulue pour isoler chaque étape du pipeline.\n",
"\n",
"- **`AdkRunResult`** — la structure de retour qui matérialise le résultat : `response_text` pour la réponse finale du LLM, `tool_calls` pour la liste détaillée des invocations (avec les noms des tools, leurs arguments sérialisés, et leur statut), et `tool_was_invoked` pour un flag booléen indiquant si au moins un tool a été utilisé. C'est cette transparence qui permet de déboguer les échecs d'appel ou de comprendre précisément pourquoi un tool n'a pas été invoqué dans la suite du laboratoire."
"- **`AdkRunResult`** — la structure de retour qui matérialise le résultat : `response_text` pour la réponse finale du LLM, `tool_calls` pour la liste détaillée des invocations (avec les noms des tools, leurs arguments sérialisés, et leur statut), et `tool_was_invoked` pour un flag booléen indiquant si au moins un tool a été utilisé. C'est cette transparence qui permet de déboguer les échecs d'appel ou de comprendre précisément pourquoi un tool n'a pas été invoqué dans la suite du laboratoire.\n"
]
},
{
Expand Down Expand Up @@ -1418,8 +1403,8 @@
"end_time": "2026-09-04T10:22:31.415357+00:00",
"environment_variables": {},
"exception": null,
"input_path": "D:\\dev\\CoursIA-vibe\\lab9-adk\\MyIA.AI.Notebooks\\ML\\DataScienceWithAgents\\Track2-GoogleADK\\Day4-Foundations\\Lab9-First-ADK-Agent.ipynb",
"output_path": "D:\\dev\\CoursIA-vibe\\lab9-adk\\MyIA.AI.Notebooks\\ML\\DataScienceWithAgents\\Track2-GoogleADK\\Day4-Foundations\\Lab9-First-ADK-Agent_output.ipynb",
"input_path": "Lab9-First-ADK-Agent.ipynb",
"output_path": "Lab9-First-ADK-Agent.ipynb",
"parameters": {},
"start_time": "2026-09-04T10:22:10.904375+00:00",
"version": "2.6.0"
Expand Down
12 changes: 3 additions & 9 deletions MyIA.AI.Notebooks/ML/ML.Net/ML-3-Entrainement-Python.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -500,22 +500,16 @@
"1. **LinearRegression échoue** (RMSE 7,01) : sur une sinusoïde, une droite est structurellement inadaptée. Le modèle le plus simple est ici le pire — contrairement à l'exemple précédent sur données linéaires.\n",
"2. **RandomForest bat GradientBoosting** (3,06 vs 3,79) : sur 60 points bruités, le RF (moyenne de 50 arbres peu profonds) est plus robuste au bruit que le GBM (qui additionne des arbres et peut amplifier le bruit). L'écart est faible mais répété sur 5 plis — la CV donne une mesure stable.\n",
"\n",
"AutoML n'a pas « deviné » : il a mesuré. C'est la différence entre l'intuition et la preuve expérimentale."
]
},
{
"cell_type": "markdown",
"id": "6e5b515e",
"metadata": {},
"source": [
"AutoML n'a pas « deviné » : il a mesuré. C'est la différence entre l'intuition et la preuve expérimentale.\n",
"\n",
"### Interprétation — pourquoi AutoML sur données sinusoïdales\n",
"\n",
"Sur données sinusoïdales, la `LinearRegression` échoue — elle ne modélise\n",
"que des droites ; les modèles non linéaires (`GradientBoosting`,\n",
"`RandomForest`, `SVR` RBF) s'en sortent bien mieux. **C'est tout l'intérêt\n",
"d'AutoML** : on ne parie pas sur un algorithme, on laisse la validation\n",
"croisée désigner le meilleur pour ce dataset — les chiffres du classement\n",
"sont lus dans la section précédente."
"sont lus dans la section précédente.\n"
]
},
{
Expand Down
12 changes: 3 additions & 9 deletions MyIA.AI.Notebooks/ML/ML.Net/ML-5-TimeSeries.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1070,14 +1070,8 @@
"| MAE faible | < 10% des ventes moyennes | > 30% des ventes moyennes |\n",
"| RMSE proche de MAE | Erreurs uniformes | Grosses erreurs ponctuelles |\n",
"\n",
"**Exemple** : Si les ventes moyennes sont de 150, un MAE de 15 (10%) est considéré comme bon."
]
},
{
"cell_type": "markdown",
"id": "c773-naive-baseline-interpretation",
"metadata": {},
"source": [
"**Exemple** : Si les ventes moyennes sont de 150, un MAE de 15 (10%) est considéré comme bon.\n",
"\n",
"### Interprétation : au-delà du MAE — la baseline naïve\n",
"\n",
"Un MAE ne dit pas si le modèle SSA est *utile* : il dit seulement de combien les prévisions s'écartent en moyenne de la vérité. **La question pédagogique déterminante** est : *le SSA bat-il une prédiction triviale ?*\n",
Expand All @@ -1095,7 +1089,7 @@
"\n",
"**Gain relatif : 45.2% en MAE, 42.0% en RMSE** — le SSA bat nettement la persistance. La série porte donc une structure (tendance + saisonnalité hebdomadaire) que la dernière valeur seule ne porte pas : l'investissement ML.NET est ici justifié pour la prédiction ponctuelle.\n",
"\n",
"> **Leçon** : corriger le protocole d'évaluation a fait passer le MAE affiché de **33.8** (valeur buggée par l'appariement `SelectMany.Zip`) à **10.5**. C'est exactement pourquoi *toujours comparer à une baseline triviale* (Hyndman & Koehler, 2006) et **aligner chaque prédiction sur sa date cible** sont deux réflexes indissociables de l'évaluation forecasting."
"> **Leçon** : corriger le protocole d'évaluation a fait passer le MAE affiché de **33.8** (valeur buggée par l'appariement `SelectMany.Zip`) à **10.5**. C'est exactement pourquoi *toujours comparer à une baseline triviale* (Hyndman & Koehler, 2006) et **aligner chaque prédiction sur sa date cible** sont deux réflexes indissociables de l'évaluation forecasting.\n"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -559,24 +559,9 @@
"(OBBTP, maxres selon la théorie). L'alternative manuelle — une **dichotomie** sur le coût\n",
"(`Solver` avec `cost <= mid`, resserrer `mid` jusqu'à unsat) — marche mais demande N appels\n",
"et une logique de boucle. `Optimize` le fait en un appel, et généralise (`maximize`, objectifs\n",
"multiples, front de Pareto — cf. notebook 06)."
]
},
{
"cell_type": "markdown",
"id": "f1a6b3c8",
"metadata": {
"papermill": {
"duration": 0.004341,
"end_time": "2026-09-28T11:49:45.144579",
"exception": false,
"start_time": "2026-09-28T11:49:45.140238",
"status": "completed"
},
"tags": []
},
"source": [
"**Lecture chiffrée — le prix de l'équilibre et l'optimum confirmé deux fois.** Trois menus se lisent ensemble : le moins cher (énumération §2 et `Optimize` §4) rend **8,50 EUR** pour 770 kcal et 27 g de protéines ; le menu équilibré (§3) rend **10,50 EUR** pour 630 kcal et 37 g ; le menu libre sans contrainte (§1) tombe à 530 kcal. L'équilibre nutritionnel se facture : **+2,00 EUR/jour** et l'abandon de 140 kcal par rapport au menu le moins cher, en échange de +10 g de protéines — un solveur ne « préfère » pas l'équilibre, il le facture. Et l'optimum de coût se lit en croisant deux méthodes indépendantes : l'énumération exhaustive (36 combinaisons filtrées sur 36) et l'`Optimize` SMT rendent le même minimum **8,50 EUR** avec le même menu (soupe de légumes + pâtes à la bolognaise + mousse au chocolat). Deux algorithmes sans aucune ligne de code en commun qui convergent vers le même chiffre : c'est la validation la plus forte disponible sur un petit domaine — et la raison pour laquelle l'énumération reste le témoin de référence tant qu'elle reste tractable."
"multiples, front de Pareto — cf. notebook 06).\n",
"\n",
"**Lecture chiffrée — le prix de l'équilibre et l'optimum confirmé deux fois.** Trois menus se lisent ensemble : le moins cher (énumération §2 et `Optimize` §4) rend **8,50 EUR** pour 770 kcal et 27 g de protéines ; le menu équilibré (§3) rend **10,50 EUR** pour 630 kcal et 37 g ; le menu libre sans contrainte (§1) tombe à 530 kcal. L'équilibre nutritionnel se facture : **+2,00 EUR/jour** et l'abandon de 140 kcal par rapport au menu le moins cher, en échange de +10 g de protéines — un solveur ne « préfère » pas l'équilibre, il le facture. Et l'optimum de coût se lit en croisant deux méthodes indépendantes : l'énumération exhaustive (36 combinaisons filtrées sur 36) et l'`Optimize` SMT rendent le même minimum **8,50 EUR** avec le même menu (soupe de légumes + pâtes à la bolognaise + mousse au chocolat). Deux algorithmes sans aucune ligne de code en commun qui convergent vers le même chiffre : c'est la validation la plus forte disponible sur un petit domaine — et la raison pour laquelle l'énumération reste le témoin de référence tant qu'elle reste tractable.\n"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -893,23 +893,8 @@
"\n",
"Un glouton \"jour par jour\" choisirait, pour chaque jour, les 3 plats les moins chers satisfaisant la fenetre kcal — mais il **ignorerait le couplage hebdomadaire** : apres 2 repetitions, les plats les moins chers deviennent indisponibles (contrainte de variete), et le glouton se retrouve bloque ou contraint de prendre des plats chers en fin de semaine, sans avoir anticipe. Le `Optimize()` de Z3, lui, minimise le **cout total sur les 7 jours simultanement** : il repartit les repetitions bon marche sur toute la semaine pour minimiser la somme globale.\n",
"\n",
"**Capabilite exercee (Prong-B).** La matrice booleenne `Sel[7][24]` (168 variables) est resolue en quelques centaines de millisecondes : l'optimisation SMT reste tractable a cette echelle. La frontiere de convergence est plus loin — un corpus RecipeML a ~11 000 recettes (variables `Sel[7][11000]` = 77 000 Booleens par jour) sortirait du regime d'un simple `Optimize()` et demanderait une decomposition (column-generation, Lagrangian relaxation) : c'est la limite honnete de la \"couverture bornee\" d'un solveur SMT monocall, signalee dans l'Epic #1206.\n"
]
},
{
"cell_type": "markdown",
"id": "s6b-lecture",
"metadata": {
"papermill": {
"duration": 0.00262,
"end_time": "2026-10-05T02:09:14.908408+00:00",
"exception": false,
"start_time": "2026-10-05T02:09:14.905788+00:00",
"status": "completed"
},
"tags": []
},
"source": [
"**Capabilite exercee (Prong-B).** La matrice booleenne `Sel[7][24]` (168 variables) est resolue en quelques centaines de millisecondes : l'optimisation SMT reste tractable a cette echelle. La frontiere de convergence est plus loin — un corpus RecipeML a ~11 000 recettes (variables `Sel[7][11000]` = 77 000 Booleens par jour) sortirait du regime d'un simple `Optimize()` et demanderait une decomposition (column-generation, Lagrangian relaxation) : c'est la limite honnete de la \"couverture bornee\" d'un solveur SMT monocall, signalee dans l'Epic #1206.\n",
"\n",
"**Lecture chiffree — quatre ordres de grandeur sur le corpus de jouet.** Le plan a cout minimal ci-dessus (D=7, 24 plats) se resout en une fraction de seconde dans ce notebook (le temps exact est imprime par la cellule de code ci-dessus) ; le [16](Z3-16-Meal-Planner-Python.ipynb) mesure, sur le meme corpus de jouet, l'enumeration des 36 combinaisons **0,06 ms**, le plan SMT booleen D=3 **2,4 ms** et l'`Optimize` a cout minimal D=1 **17,7 ms**. L'enumeration gagne partout ou elle reste tractable — mais sa pente est exponentielle en le nombre de variables quand celle du solveur suit la combinatoire contrainte. Passer de 3 a 7 jours avec corpus elargi et contrainte de variete coute environ deux ordres de grandeur (millisecondes -> fraction de seconde) : observation sur cette paire de runs, pas une loi (jours et corpus changent en meme temps). La lecture pratique : le temps du solveur achete l'exactitude a l'echelle ou l'enumeration explose, et la fenetre [1400, 1900] kcal avec 40 g de proteines reste resolue en moins d'une seconde a D=7.\n"
]
},
Expand Down
Loading
Loading