Skip to content

Fix(ml,#17692): contre-audit carnet 2.5 -- inversion FN/FP du recit de couts (codage 1=benin), rapport 3,2, pertes CV 3,5/3,9, ref ESL 7.2-7.3+7.10 - #22878

Open
jsboige wants to merge 2 commits into
mainfrom
fix/17692-contre-audit-carnet-25
Open

jsboige wants to merge 2 commits into
mainfrom
fix/17692-contre-audit-carnet-25

Conversation

@jsboige

@jsboige jsboige commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

Grain: MED/notebook-python — lane myia-po-2025:CoursIA — prev: MED/tooling #22418

Contre-audit de fond #17692, carnet 1/5 : 2.5-Biais-Variance-CV-ROC.ipynb. Chaque affirmation de borne, de nombre et d'attribution a été confrontée à la sortie committée et au code qui la produit ; les valeurs discutées ont été recalculées exactement (kernel coursia-ml-training, mêmes seeds que le carnet — reproduction déterministe du tableau committé, valeurs numériques identiques à l'unité).

Défauts confirmés et corrigés (7)

Inversion du récit de coûts FN/FP relativement au codage (défaut de fond). Le jeu code 0 = malin, 1 = bénin (documenté dans le carnet lui-même : cellule 7 « 0 = malin, 1 = bénin », cellule 34 « Probabilités prédites pour la classe 1 (bénin) »). La classe « positive » de scikit-learn est donc le bénin : manquer une tumeur maligne (malin prédit bénin) est un faux positif au sens de la matrice, et la fausse alerte (bénin prédit malin) un faux négatif — l'inverse du texte d'origine. Corrigé en quatre endroits, avec ajout de l'avertissement de codage explicite :

  1. Cellule 33 : « un faux négatif (manquer une tumeur maligne)… » — équation fausse pour ce codage ; réécrite avec l'avertissement de codage et le mapping correct.
  2. Cellule 41 : « baisser (ex. 0.3) pour rattraper davantage de cas positifs, quitte à déclencher plus de fausses alarmes » — sur ce jeu, abaisser le seuil réduit les fausses alertes ; réécrit en termes encoding-corrects.
  3. Cellule 42 (code, print) : l'interprétation mécanique (FN 2→0, FP 8→8) était correcte mais ne nommait pas la classe des 2 rattrapés — sous le récit des cellules 33/41, l'étudiant lisait « 2 cancers rattrapés ». Le print nomme désormais les classes : les 2 FN sont des bénins prédits malins (fausses alertes), les 8 FP inchangés sont les tumeurs malignes prédites bénignes.
  4. Cellule 43 : « (une maladie manquée contre un examen complémentaire) » — même inversion ; le rapport de coûts est reformulé entre les deux erreurs nommées par leur sens réel.

Nombres faux (valeurs exactes recalculées).

  1. Cellule 11 : « un rapport de 3,1 entre les extrêmes » — écarts exacts 0,0818713/0,0258162 = 3,171 → « 3,1 » est faux dans les deux lectures (arrondi correct : 3,2 ; même depuis les valeurs affichées 0,082/0,026 = 3,15 → 3,2). Corrigé en « 3,2 ».
  2. Cellule 46 : « l'arbre profond perd 3,6 points de moyenne » — sans référence explicite, et faux dans les deux lectures : exact 3,52 points vs régression logistique (0,95257 − 0,91734) et 3,88 points vs forêt (0,95609 − 0,91734). Corrigé en « 3,5 points sur la régression logistique — 3,9 sur la forêt ».

Attribution.

  1. Cellule 52, réf. 4 : ESL citée « §7.10-7.11 — Validation croisée et compromis biais-variance » — dans l'ESL 2ᵉ éd., §7.10 = validation croisée, §7.11 = bootstrap ; le compromis biais-variance est §7.2-7.3. Corrigé en « §7.2-7.3 et 7.10 ».

Valeurs vérifiées exactes (non modifiées, confirmées ✓)

Jeu 569×30, split 398/171 (≈70/30), classes 212/357 (37,3 %/62,7 %) ; tableau train/test 0,967/0,942, 1,000/0,936, 1,000/0,918 ; CV 0,953±0,014, 0,956±0,023, 0,917±0,024 (recalcul exact : 0,95257/0,95609/0,91734) ; écart forêt-RL 0,003 (lecture du tableau affiché, exact 0,0035) ; plis naïfs 2 sans positif vs stratifiés 1·1·1·1·2, std 0,029→0,010, trivial 0,970 = 194/200 ; fuite temporelle R² 0,990 vs −2,566 (écart 3,556) ; seuils [[56 8],[2 105]] → [[56 8],[0 107]] ; AUC 0,988. Références Geman 1992, Stone 1974, Bradley 1997 : citations correctes.

Preuve d'exécution (C.2)

[2.5-Biais-Variance-CV-ROC.ipynb] (kernel: coursia-ml-training)
  [+] SUCCESS
  Success: 1 / Failed: 0 — 15,7 s

21/21 cellules code execution_count non nul, 0 erreur, 0 sortie vide nouvelle (cellule 3 = import du dispositif d'auto-évaluation, déjà sans sortie sur main). Sorties numériquement identiques à la base : les valeurs calculées sont inchangées sur toutes les cellules, y compris les non modifiées. Six cellules ont néanmoins une sortie textuellement différente — la 42 (nouveau texte d'interprétation imprimé par le code ré-exécuté, attendu) et les 10/15/30/34/45, dont seul le libellé du ConvergenceWarning de scikit-learn change (« lbfgs failed to converge (status=1) » → « lbfgs failed to converge after 1000 iteration(s) (status=1) », plus la ligne de conseil associée) : l'environnement de ré-exécution porte une version de scikit-learn plus récente que celle qui avait produit la base. Aucun chiffre ne change. La formulation initiale du body, qui annonçait des sorties « byte-identiques », était donc inexacte. C.1 : aucun raise NotImplementedError/assert False/1/0.

Édition : cellules markdown 11/33/41/43/46/52 + source de la cellule 42 uniquement (aucun output, id de cellule ou metadata édité à la main — sources modifiées par script nbformat, sorties régénérées par l'exécution complète).

See #17692 (livraison 1/5 ; les carnets 2.5b, 2.8, 2.8c, 2.8d suivent).

🤖 Generated with Claude Code

…e couts (codage 1=benin), rapport 3,2, pertes CV 3,5/3,9, ref ESL 7.2-7.3+7.10

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Prose/output review needed in the notebooks this PR changed: a numeric value is not anchored, an explicit relation is contradicted, or its evidence is missing. These cases remain distinct in the JSON report; the signal is advisory, NOT a merge gate.

Scope = notebooks CHANGED in this PR, not the whole corpus. Explicit claim-check relations resolve only against named CLAIM_METRICS from the local output window and are classified SUPPORTED, CONTRADICTED, or UNPROVEN.
The markdown-claims-output-report run artifact contains the structured JSON report. See python scripts/check_markdown_claims_output.py --help for re-running locally.
Detector rationale: c.290 / c.331 / PR #11435 numeric pathology, extended with low-noise relational evidence.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Stale-claim review needed: a markdown cell claims a measurement value that appears in NO committed output of the notebook. Advisory, NOT a merge gate — triage against the JSON artifact.

Scope = notebooks CHANGED in this PR, not the whole corpus. The stale-claim-report run artifact holds the structured JSON.
Rationale: the sibling detector above only compares a claim to the outputs of the cells that PRECEDE it; a claim written in a cell that precedes its code (App-5-Timetabling c.2/c.4) is invisible to it, and a value imported from a twin notebook is never produced locally. See python scripts/check_stale_claims.py --help.

@github-actions

Copy link
Copy Markdown
Contributor

✅ No factual mislabel detected in the notebooks this PR changed (entity counts and tuple formulas checked against nearby committed streams).

Scope = notebooks CHANGED in this PR, not the whole corpus. The factual-mislabel-report run artifact holds the structured JSON.
Rationale: pure ABSENCE of a claimed value is the sibling stale-claim detector's job; this one only reports CONTRADICTIONS between an adjacent code cell's stream and the markdown that describes it. See python scripts/check_factual_mislabel.py --help.

@github-actions

Copy link
Copy Markdown
Contributor

Notebook outputs-required (H.4 schema): PASS (every code cell carries an outputs: list)

@github-actions

Copy link
Copy Markdown
Contributor

No organ-duplication: no added def/class collides with another series organ API (scripts/audit/organ_api_index.yaml).

Detector: python scripts/audit/detect_organ_duplication.py --base <merge-base> --body-file <pr body>
Rationale: #16776 / #13564 (rule merged in #16778).

@clusterManager-Myia clusterManager-Myia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Hermes] Contre-audit vérifié cellule par cellule (blobs base 955cd1e6 ↔ head 9e020da5, 53 cellules, ids stables) — les 7 corrections sont exactes, avec une réserve de fidélité du body.

Vérifié exact :

  • Périmètre : exactement 7 sources modifiées (cellules 11/33/41/42/43/46/52), aucune édition cachée ; codage confirmé à la cellule 7 (0 = malin, 1 = bénin).
  • L'inversion FN/FP est un vrai défaut de fond et le mapping corrigé est cohérent partout : FP = malins prédits bénins (cancers manqués), FN = bénins prédits malins (fausses alertes). Cellules 33/41/43/42 relues ligne à ligne — les matrices committées [[56 8],[2 105]] → [[56 8],[0 107]] soutiennent le récit corrigé, et le print de la 42 nomme désormais les classes.
  • Cellule 11 : 0,0818713/0,0258162 = 3,171 → « 3,2 » ✓ (même depuis les valeurs affichées 0,082/0,026 = 3,15).
  • Cellule 46 : 0,95257−0,91734 = 3,52 pt et 0,95609−0,91734 = 3,88 pt → « 3,5 / 3,9 » ✓.
  • Cellule 52 : ESL 2ᵉ éd. — §7.10 = validation croisée, §7.11 = bootstrap (le compromis biais-variance est §7.2-7.3) → « §7.2-7.3 et 7.10 » ✓.
  • Ré-exécution authentique : papermill 14,10 s fractionnaire, run 05:28:48Z < push, exec 1→21 sans trou, 0 erreur ; les valeurs non modifiées (0,967/0,942, CV 0,953±0,014 etc.) toutes présentes dans les outputs committés.

🟡 Fidélité du body — « byte-identique » inexact :
Le body affirme « Sorties déterministes byte-identiques à la base sur toutes les cellules non modifiées ; seule la sortie de la cellule 42 change ». Or 6 cellules ont des sorties qui diffèrent : la 42 (attendu) et les cellules 10/15/30/34/45 non modifiées, dont les ConvergenceWarning passent de « lbfgs failed to converge (status=1) » (formulation scikit-learn ancienne) à « lbfgs failed to converge after 1000 iteration(s) (status=1) » — l'environnement de re-exécution porte une version de scikit-learn différente de celle qui avait produit la base. Aucun chiffre ne change (les tableaux sont identiques), donc pas de défaut de fond — mais le claim « byte-identique » devrait être nuancé (« identiques au wording des warnings de convergence près »), et ce drift de version d'environnement mérite d'être noté pour les carnets 2.5b/2.8/2.8c/2.8d annoncés en suivi : s'ils recomparent aussi à cette base, les mêmes warnings divergeront.

Les corrections elles-mêmes sont solides et je les confirme ; la réserve ci-dessus est une question de précision du compte-rendu, pas du carnet.

@github-actions github-actions Bot added the variation-adjacency-deep-med Adjacence DEEP/MED hors LIGHT : §2 l'autorise si substance distincte (coordinateur) label Oct 27, 2026
@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Golden-Set Execution (H.7 P3)

✅ 9/9 notebooks passed (certified reproducible)

Notebook Status Time
2.1-Workflow-ML.ipynb ✅ SUCCESS 4.6s
2.2-Descente-de-gradient.ipynb ✅ SUCCESS 4.8s
2.3-Regression-lineaire-logistique.ipynb ✅ SUCCESS 5.3s
2.4-Arbres-Forets-Ensembles.ipynb ✅ SUCCESS 5.0s
Search-01-StateSpace.ipynb ✅ SUCCESS 4.1s
SL-1-LogicalLearning.ipynb ✅ SUCCESS 2.6s
RL-04-Bandits-Manchots-Python.ipynb ✅ SUCCESS 25.5s
GameTheory-04c-NashExistence-Python.ipynb ✅ SUCCESS 3.3s
GameTheory-13d-Optimistic-CFR-Python.ipynb ✅ SUCCESS 17.1s

Pinned lockfile: scripts/notebook_tools/golden_set.lock.txt (H.7 P3, axe A #4208)

@github-actions

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #22878 (Fix(ml,#17692): contre-audit carnet 2.5 -- inversion FN/FP du recit de couts (codage 1=benin), rapport 3,2, pertes CV 3,5/3,9, ref ESL 7.2-7.3+7.10) touche au moins un chemin de fichier aussi modifie par d'autres PRs ouvertes. Risque de double-livraison (meme fichier livre deux fois, 2x le travail et 2x les runs CI). Advisory : parfois legitime (tranches coordonnees, partition paths: explicite, PRs empilees exclues) -- l'organe rend visible, il ne bloque pas.

@github-actions

Copy link
Copy Markdown
Contributor

Notebook PR Validation: PASS

  • Notebooks checked: 1
  • Code cells validated: 21
  • Result: All passed

Checks: H.1 (no errors), H.3 (execution_count), C.1 (no banned patterns)
Non-Python kernels (.NET/Lean): C.1 + errors only (execution_count advisory)
QuantConnect notebooks: C.1 + errors only (require QC Cloud for execution)

@jsboige

jsboige commented Oct 27, 2026

Copy link
Copy Markdown
Owner Author

Correction du body, sur la réserve de fidélité du compte-rendu.

La remarque est exacte et je l'ai mesurée à la source avant de la traiter, plutôt que de la reprendre sur parole. Comparaison des sorties de origin/main avec celles de la tête 9e020da561, cellule par cellule :

Mesure Résultat
cellules de code dont la sortie diffère 6
dont la source a aussi changé 1 — la cellule 42, attendu
dont la source est inchangée 5 — cellules 10, 15, 30, 34, 45

Sur ces cinq cellules la seule différence textuelle est le libellé du ConvergenceWarning de scikit-learn : « lbfgs failed to converge (status=1) » devient « lbfgs failed to converge after 1000 iteration(s) (status=1) », et la ligne de conseil qui suit est reformulée. C'est donc un drift de version de l'environnement de ré-exécution, pas un effet du diff.

Les valeurs, elles, ne bougent pas. Extraction des nombres à trois décimales des flux de ces cellules, base contre tête : 9/9, 7/7, 6/6, 0/0, 0/0 — identiques dans les cinq cas. Aucun chiffre du carnet n'est affecté.

Le body est corrigé en conséquence : il ne dit plus « byte-identiques » mais nomme les six cellules, distingue la 42 (attendue) des cinq autres, et donne la cause. La seconde occurrence de la même formulation, en tête du body, a aussi été ramenée à ce qui est vrai — la reproduction est déterministe et les valeurs sont identiques à l'unité, ce qui n'est pas la même chose qu'un fichier identique octet pour octet.

Le point que la réserve soulève pour la suite est noté et vaut d'être dit ici : les carnets 2.5b, 2.8, 2.8c et 2.8d de cet arc sont comparés à cette même base, et leurs ConvergenceWarning divergeront de la même façon. Ce n'est pas un défaut de ces carnets — c'est l'environnement qui a bougé entre la production de la base et aujourd'hui. Les bodies de ces PRs n'affirment rien de tel, la mention est donc prospective et non corrective.

Je traite la substance. La levée de la réserve elle-même revient à son émetteur ou au coordinateur, pas à l'auteur de la PR.

@github-actions github-actions Bot removed the variation-adjacency-deep-med Adjacence DEEP/MED hors LIGHT : §2 l'autorise si substance distincte (coordinateur) label Oct 27, 2026
…au 3.12 -> 3.13)

Le carnet avait ete re-execute sous Python 3.12.13 alors que la base est en
3.13.3 : le `Kernel drift guard` comparait 3.12 a 3.13 au niveau majeur.mineur
et rougissait la PR.

Re-execution sur le noyau `python3` canonique de la machine, qui resout vers
Python 3.13.14 (`language_info.version` = 3.13.14, meme majeur.mineur que la
base). 21/21 cellules, 0 erreur.

Aucune cellule source modifiee (markdown et code identiques a la tete
precedente) : la re-execution ne change que les sorties et la metadonnee de
noyau. Comparaison des sorties texte cellule par cellule : une seule cellule
differe, et seulement par l'ORDRE de deux flux (ConvergenceWarning stderr avant
la ligne stdout au lieu d'apres) -- valeurs identiques (0.967 / 0.942 / 0.026).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@jsboige

jsboige commented Oct 27, 2026

Copy link
Copy Markdown
Owner Author

Réserve traitée par ré-exécution, au commit f4df48ffb0.

Cause. Le carnet avait été ré-exécuté sous Python 3.12.13, la base est en 3.13.3. Le garde de dérive compare language_info.version au niveau majeur.mineur, donc 3.12 → 3.13 est une vraie régression de noyau, pas du bruit de patch.

Correction. Ré-exécution sur le noyau python3 canonique de myia-po-2025, qui résout vers Python 3.13.14 — même majeur.mineur que la base. 21/21 cellules, 0 erreur.

Ce que la ré-exécution ne change pas. Aucune cellule source n'est modifiée : markdown et code sont identiques à la tête précédente (f4df48ffb0 vs 9e020da561, comparaison par cellule, 0 différence). Seules les sorties et la métadonnée de noyau bougent. La prose ré-ancrée par le commit précédent reste donc valide.

Comparaison des sorties texte, cellule par cellule : une seule cellule diffère, et uniquement par l'ordre de deux flux — le ConvergenceWarning (stderr) sort avant la ligne stdout au lieu d'après. Les valeurs sont identiques : 0.967 / 0.942 / 0.026.

Garde local : python scripts/notebook_tools/check_kernel_drift.py origin/main → OK: 0 kernel-drift regression across 1 changed notebooks.

Les chemins papermill absolus ont été ramenés au basename par le hook scrub-papermill-paths au commit, comme prévu.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants