diff --git a/MyIA.AI.Notebooks/ML/DataScienceWithAgents/01-PythonForDataScience/notebooks/1.3-Analyse_de_Donnees_avec_Pandas.ipynb b/MyIA.AI.Notebooks/ML/DataScienceWithAgents/01-PythonForDataScience/notebooks/1.3-Analyse_de_Donnees_avec_Pandas.ipynb index 663d0a6642..52581039a0 100644 --- a/MyIA.AI.Notebooks/ML/DataScienceWithAgents/01-PythonForDataScience/notebooks/1.3-Analyse_de_Donnees_avec_Pandas.ipynb +++ b/MyIA.AI.Notebooks/ML/DataScienceWithAgents/01-PythonForDataScience/notebooks/1.3-Analyse_de_Donnees_avec_Pandas.ipynb @@ -127,6 +127,14 @@ "print(df)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Lecture ancrée** : Le tableau imprimé, ligne à ligne : col1 = 1, 2, 10 ; col2 = 3, 4, 30 ; Nom = Alice, Bob, Charles — deux colonnes d'entiers, une colonne de chaînes, dans le MÊME objet. C'est le contrat du DataFrame : l'hétérogénéité se juge par colonne (chaque colonne a son dtype), là où un array numpy unique exigerait un type commun aux 9 valeurs. L'index `0, 1, 2` imprime a gauche n'a pas ete fourni : Pandas l'a fabrique (RangeIndex) parce que le dictionnaire ne portait que des colonnes — la ligne existe donc meme quand aucune donnee ne l'etiquette. Et les colonnes sont alignees par NOM : `col1`, `col2`, `Nom` gardent chacun leur dtype au sein du meme objet." + ], + "id": "7706042c-c970-4f31-b3d3-2e9ca71f16a6" + }, { "cell_type": "markdown", "id": "94f4ece9", @@ -199,6 +207,14 @@ "print(colonne_2)" ] }, + { + "cell_type": "markdown", + "id": "c2057490-4f12-4f3a-9ca7-9ebfba7b199f", + "metadata": {}, + "source": [ + "**Lecture ancree** : la sortie imprime deux fois le meme objet sous deux formes. D'abord « Le DataFrame complet » : `col1` et `col2` en deux colonnes, index `0-1`. Puis « La colonne 'col2' (qui est une Series Pandas) » : `0 3`, `1 4`, et son pied `Name: col2, dtype: int64`. L'extraction d'une colonne rend une **Series** 1-D qui emporte le nom (`Name: col2`) et le type (`int64`) de sa colonne d'origine — ce pied est la signature visible de la Series, un DataFrame ne l'imprime pas. C'est ce qui permettra les jointures par cle et les operations alignees de la suite." + ] + }, { "cell_type": "markdown", "id": "4cdc0e3c", @@ -257,6 +273,14 @@ "print(df_filtre)" ] }, + { + "cell_type": "markdown", + "id": "bdb3c322-e6a9-44a0-b2f2-ba41e518e1ed", + "metadata": {}, + "source": [ + "**Lecture ancree** : le resultat ne garde que **deux lignes** — Bob (`col1` = 2) et Charles (`col1` = 10) — et laisse tomber Alice (`col1` = 1). L'expression `df['col1'] > 1` produit une Series de booleens, et `df[filtre]` ne conserve que les lignes ou elle vaut `True`. Le masque est **calcule avant** d'etre applique : c'est la meme Series 1-D etiquetee que dans la section precedente, ici consommee comme index — la selection s'aligne sur les etiquettes, pas sur les positions." + ] + }, { "cell_type": "markdown", "id": "cell-jd-intro", @@ -374,6 +398,14 @@ "Voulez-vous ne garder que les commandes `inner` ? Ou toutes les commandes `left` ?\n" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Lecture ancrée** : Les quatre jointures mesurées : inner **2 lignes** (Alice 100, Charles 250), left **3** (Bob apparaît, montant NaN), right **3** (le client_id=4 orphelin apparaît, nom NaN, montant 75), outer **4**. Deux asymétries lisibles : la clé orpheline (4) ne survit que dans right/outer — avec nom=NaN ; le client sans commande (Bob) ne survit que dans left/outer — avec montant=NaN. Noter aussi le dtype : montant passe à float dès qu'un NaN est possible (100 → 100.0). Les deux tables d'entree sont visibles juste au-dessus de ces comptes : `clients` porte 1 Alice, 2 Bob, 3 Charles, et `commandes` 1 -> 100, 3 -> 250, 4 -> 75 — trois clients, trois commandes, mais les ensembles de cles ne coincident pas : le 2 n'a aucune commande, le 4 n'a aucun client. Les quatre comptes ne sont donc que la projection chiffree de ce desaccord." + ], + "id": "1aaa4685-5aaa-4fa9-a288-802bfa3f36b8" + }, { "cell_type": "markdown", "id": "cell-jd-missing-intro", @@ -463,6 +495,14 @@ "print(notes_imputees)\n" ] }, + { + "cell_type": "markdown", + "id": "9401b3cf-62fe-4668-8487-5898e415f294", + "metadata": {}, + "source": [ + "**Lecture ancree** : « Diagnostic : ou manque-t-il des valeurs ? — nom 0, note 2, age 1 » : la table brute porte Alice (10.0, 20.0), Bob (NaN, 21.0), Charles (12.0, NaN), Diana (NaN, 22.0), Eve (30.0, 19.0) — **3 trous pour 5 lignes**, jamais deux dans la meme ligne. La carte des NaN par colonne (une Series `int64`) est l'instrument qui decide de la strategie AVANT tout calcul : une moyenne Pandas saute les NaN silencieusement, la mediane aussi — le diagnostic est ce qui empeche de croire qu'on a moyenne 5 notes." + ] + }, { "cell_type": "markdown", "id": "cell-jd-missing-read", @@ -478,6 +518,14 @@ "si l'absence est un signal metier, mieux vaut supprimer la ligne et l'asserter.\n" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Lecture ancrée** : Détail qui compte dans la table fillna imprimée : après comblage, Bob et Diana ont note=12.0 — mais Charles garde **age = NaN**. La stratégie fillna de la sortie était ciblée sur `note` uniquement ; `age` conserve son trou. Traiter les valeurs manquantes colonne par colonne, pas dataframe d'un bloc : le diagnostic (note 2, age 1) annonce déjà deux traitements distincts. Le choix se chiffre d'ailleurs : `dropna` (3 lignes restantes) donne une moyenne de **17.33**, `fillna` a la mediane **12.0** donne **15.20** — cinq points d'ecart sur la meme colonne, pour une decision qui ne change qu'une chose : jeter les lignes trouees ou combler d'abord." + ], + "id": "f9f96479-6c6c-4e83-83e5-d8d63a67229f" + }, { "cell_type": "markdown", "id": "cell-jd-dt-intro", @@ -564,6 +612,22 @@ "plt.show()\n" ] }, + { + "cell_type": "markdown", + "id": "130486ae-5b2c-4187-92e3-9934af863fd1", + "metadata": {}, + "source": [ + "**Lecture ancrée** : la colonne `annee` vaut **2024 sur les cinq lignes** — `.dt.year` a extrait l'année de chaque date en une seule opération vectorisée, sans boucle : l'accessor `.dt` expose les propriétés datetime (`year`, `month`, `day`…) sur toute la Series. La table intermédiaire garde `date` et `montant` intacts : l'extraction **ajoute** une colonne, elle n'en remplace aucune. La sortie le confirme sur deux points : l'index `0..4` des cinq lignes d'origine est resté tel quel, et la colonne `date` garde l'horodatage complet (`2024-01-15`) — seule la colonne neuve `annee` porte l'information réduite à l'année." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Lecture ancrée** : « Ventes mensuelles (resample ME) » : 2024-01-31 → 200, 2024-02-29 → 200, 2024-03-31 → 240, « Freq: ME » — cinq transactions mensualisées en trois fins de mois : janvier réunit 120+80, février porte 200 seule, mars additionne 150+90. `resample('ME')` est le groupby du temps : il découpe à bord de mois fini et agrège — la Series résultante porte l'index des dates de clôture, pas des dates de transaction. La figure produite juste apres (600x300, un seul axe) trace cette Series a trois points : `resample` ne rend pas qu'un tableau, il rend une serie temporelle indexee par ses dates de cloture, directement tracable sans retraitement." + ], + "id": "8211e19e-0fe2-4592-a4cb-a17815fb6865" + }, { "cell_type": "markdown", "id": "cell-jd-csv-intro", @@ -630,6 +694,14 @@ "os.remove(chemin_csv)\n" ] }, + { + "cell_type": "markdown", + "id": "3b153a79-0f82-4c9e-8f7a-06c5466c6280", + "metadata": {}, + "source": [ + "**Lecture ancrée** : les types confirment le round-trip — `Date datetime64[us]` et `montant int64`. Mais la conversion de `Date` ne vient pas d'une détection : elle est **demandée explicitement** par le paramètre `parse_dates` de `read_csv` (sans lui, la colonne resterait une chaîne) ; seule l'inférence de `montant` (int64 deviné des valeurs) est réelle. Et le piège des lignes : le « Fichier relu » montre 3 lignes (120, 330, 240) alors que la table **brute** de la section précédente en comptait 5 (120, 80, 200, 150, 90) — seul 120 est commun, et la table mensuelle (200, 200, 240) n'est ni l'une ni l'autre. Le round-trip CSV garantit les **types** (et encore, parce qu'on les a demandés), jamais l'identité des lignes. Le pied `dtype: object` ne decrit pas une colonne : c'est le type de la Series d'etiquettes elle-meme (des chaines), distinct des deux types qu'elle enumere — lire ce pied comme un troisieme type serait une erreur d'un niveau." + ] + }, { "cell_type": "markdown", "id": "a1eb8902", diff --git a/MyIA.AI.Notebooks/ML/DataScienceWithAgents/Track1-LangChain/Day3-Data-Agents/Labs/Lab6-First-Agent/Lab6-First-Agent.ipynb b/MyIA.AI.Notebooks/ML/DataScienceWithAgents/Track1-LangChain/Day3-Data-Agents/Labs/Lab6-First-Agent/Lab6-First-Agent.ipynb index 6ef9fd8290..abf8ea2e07 100644 --- a/MyIA.AI.Notebooks/ML/DataScienceWithAgents/Track1-LangChain/Day3-Data-Agents/Labs/Lab6-First-Agent/Lab6-First-Agent.ipynb +++ b/MyIA.AI.Notebooks/ML/DataScienceWithAgents/Track1-LangChain/Day3-Data-Agents/Labs/Lab6-First-Agent/Lab6-First-Agent.ipynb @@ -274,6 +274,14 @@ "print(\"Prompt REACT configure avec ChatPromptTemplate\")" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Lecture ancrée** : Le template, verbatim du code : `(\"system\", \"You are a helpful assistant. Use the tools available to help the user.\")` puis `MessagesPlaceholder(\"messages\")` — la sortie confirme « Prompt REACT configure avec ChatPromptTemplate ». Structure fixe (le rôle système, qui ordonne d'utiliser les outils) + slot variable (l'historique des messages) : LangGraph injectera la conversation dans le slot à chaque tour de la boucle REACT." + ], + "id": "37a3f099-783f-4cea-ba61-137b35bd32a1" + }, { "cell_type": "markdown", "id": "2ab21f9e", @@ -351,6 +359,14 @@ "print(\"Agent REACT cree avec LangGraph\")" ] }, + { + "cell_type": "markdown", + "id": "3604fb2c-b426-40e2-89a6-6f59ca2a83c0", + "metadata": {}, + "source": [ + "**Lecture ancree** : la cellule imprime « Agent REACT cree avec LangGraph », puis un `LangGraphDeprecatedSinceV10` integral : « create_react_agent has been moved to `langchain.agents`. Please update your import to `from langchain.agents import create_agent`. Deprecated in LangGraph V1.0 to be removed in V2.0. » Le traceback recopie la ligne fautive, `create_react_agent(model=llm, tools=tools, prompt=prompt)` : trois arguments nommes, trois roles — le modele decide, la liste d'outils agit, le prompt cadre. La boucle REACT n'est pas ecrite a la main : elle est COMPILEE par cet appel, c'est ce que « prebuilt » annonce dans `from langgraph.prebuilt import create_react_agent`. L'agent fonctionne aujourd'hui ; l'import migrera en v1.0 et disparaitra en v2.0." + ] + }, { "cell_type": "markdown", "id": "ba74b487",