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
44 changes: 41 additions & 3 deletions MyIA.AI.Notebooks/Probas/PyMC/PyMC-03-Factor-Graphs.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@
"\n",
"On decouvre que le **revolver appartient a Colonel Mustard**. Qui est le coupable ?\n",
"\n",
"> *Source.* Le « Murder Mystery » (M. Boddy, Miss Scarlet, Colonel Mustard, Mrs. Peacock) est l'exemple introductif phare du **chapitre 1** de Winn & Bishop, *Model-Based Machine Learning* (2019, [mbmlbook.com](https://www.mbmlbook.com)) — conçu pour faire émerger l'inférence bayésienne *via* un récit, sans équation, en révisant itérativement les *a priori* à chaque indice. Le notebook en reprend l'énoncé et le résout en PyMC (`pm.Categorical` + vraisemblance conditionnelle) ; le twin Infer.NET utilise `Variable.Discrete` + `Variable.If/Case` (voir [Infer-3](../Infer/Infer-3-Factor-Graphs.ipynb))."
"> *Source.* Le « Murder Mystery » (M. Boddy, Miss Scarlet, Colonel Mustard, Mrs. Peacock) est l'exemple introductif phare du **chapitre 1** de Winn & Bishop, *Model-Based Machine Learning* (2019, [mbmlbook.com](https://www.mbmlbook.com)) — conçu pour faire émerger l'inférence bayésienne *via* un récit, sans équation, en révisant itérativement les *a priori* à chaque indice. Le notebook en reprend l'énoncé et le résout en PyMC (`pm.Categorical` + vraisemblance conditionnelle) ; le twin Infer.NET utilise `Variable.Discrete` + `Variable.If/Case` (voir [Infer-3](../Infer/Infer-3-Factor-Graphs.ipynb)).\n",
"\n",
"**Le modèle vu comme deux facteurs.** Tout ce que PyMC va échantillonner est déjà contenu dans deux tables locales : le facteur *a priori* `f1(coupable) = (0.6, 0.3, 0.1)` et le facteur de vraisemblance `f2(arme=Mustard | coupable) = 0.9` si Mustard, `0.1` sinon. La distribution jointe est leur produit — c'est littéralement le « graphe de facteurs » du titre : une variable `coupable`, deux facteurs accrochés, une observation `arme_mustard = 1`. L'interprétation de la section 1 montrera que l'on peut faire le calcul exact à la main sur ces deux tables ; MCMC va le redécouvrir tout seul."
]
},
{
Expand Down Expand Up @@ -273,6 +275,16 @@
"print(f\"Diagnostic MCMC (Murder Mystery, CompoundStep) : pire r_hat={diag_murder['r_hat'].max():.3f} (sur {worst_var}) ; ess_bulk min={int(diag_murder['ess_bulk'].min())}\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Lecture du diagnostic — pourquoi il est si propre\n",
"\n",
"`r_hat = 1.000` et `ess_bulk >= 15 310` pour 20 000 tirages : sur un modèle aussi petit, l'échantillonneur discret (`CategoricalGibbsMetropolis`, pas NUTS — les variables discrètes n'offrent pas de gradient à exploiter) mélange presque parfaitement : chaque état reste accessible depuis chaque autre, il n'y a ni géométrie difficile, ni « funnel » à craindre. Le réflexe diagnostic n'est pas superflu pour autant : il deviendra indispensable sur les modèles plus riches de la série (voir PyMC-06-Debugging)."
],
"id": "aa05d7e"
},
{
"cell_type": "markdown",
"id": "bd33d3f1",
Expand Down Expand Up @@ -301,7 +313,17 @@
"\n",
"> **Note technique** : L'echantillonnage par CategoricalGibbsMetropolis est adapte aux variables discretes comme `coupable`. L'utilisation de `pt.switch` (equivalent de `Variable.If` en Infer.NET) permet de conditionner la probabilite de l'observation selon la valeur du coupable.\n",
"\n",
"La cellule suivante visualise la distribution posterieure sous forme de diagramme en barres, permettant de comparer visuellement les frequences d'echantillonnage entre les trois suspects."
"La cellule suivante visualise la distribution posterieure sous forme de diagramme en barres, permettant de comparer visuellement les frequences d'echantillonnage entre les trois suspects.\n",
"\n",
"**Le contrôle par calcul exact.** Ces trois nombres se retrouvent à la main en trois lignes — c'est le vrai contenu du graphe de facteurs :\n",
"\n",
"| Suspect | Prior × Vraisemblance | Non normalisé | Exact (÷ 0.34) | Échantillonné |\n",
"|---|---|---|---|---|\n",
"| Scarlet | 0.6 × 0.1 | 0.06 | 0.176 | 0.176 |\n",
"| Mustard | 0.3 × 0.9 | 0.27 | 0.794 | 0.797 |\n",
"| Peacock | 0.1 × 0.1 | 0.01 | 0.029 | 0.028 |\n",
"\n",
"La constante de normalisation est la somme des produits : 0.06 + 0.27 + 0.01 = **0.34** — c'est aussi la probabilité d'observer l'arme de Mustard *avant* de savoir qui a tiré. Les 20 000 tirages MCMC reproduisent le calcul exact au millième près (écart maximal 0.003, pur bruit Monte-Carlo) : l'échantillonneur n'invente rien, il redécouvre numérateur et dénominateur."
]
},
{
Expand Down Expand Up @@ -437,7 +459,9 @@
"\n",
"Le phenomene d'**explaining away** : quand on observe l'arme de Mustard, la probabilite que Scarlet soit coupable diminue, car l'observation \"explique\" le crime par Mustard.\n",
"\n",
"> *Référence.* Le mécanisme d'« explaining away » est propre aux structures en V (colliders) : deux causes partagent un effet commun, et observer l'effet les rend *compétitives*. Formalisé par Pearl (1988), *Probabilistic Reasoning in Intelligent Systems* (Morgan Kaufmann), §3.3 — c'est l'une des structures élémentaires de la propagation d'information dans un réseau bayésien (chaîne, fourche, collider)."
"> *Référence.* Le mécanisme d'« explaining away » est propre aux structures en V (colliders) : deux causes partagent un effet commun, et observer l'effet les rend *compétitives*. Formalisé par Pearl (1988), *Probabilistic Reasoning in Intelligent Systems* (Morgan Kaufmann), §3.3 — c'est l'une des structures élémentaires de la propagation d'information dans un réseau bayésien (chaîne, fourche, collider).\n",
"\n",
"La lecture chiffrée du tableau de la section 1 rend la compétition visible : l'indice *contre* Scarlet n'a jamais changé — son motif pèse toujours 0.6 *a priori* — et pourtant son posterior tombe de 0.600 à 0.176 (−70.7 %). Ce n'est pas une preuve accumulée contre elle, c'est une **pression concurrentielle** : l'arme de Mustard explique le crime à sa place, et les explications rivales se partagent une masse de probabilité fixée par la vraisemblance de l'observation. Mustard gagne exactement ce que Scarlet et Peacock perdent (+165.7 % contre −70.7 % et −72.0 %)."
]
},
{
Expand Down Expand Up @@ -646,6 +670,18 @@
"print(f\"\\nReponse : il faut CHANGER ! P(gagner si changement) = {(voiture_samples == 2).mean():.3f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Pourquoi changer gagne — la contrainte de Monty comme information\n",
"\n",
"Là encore, trois produits suffisent : `P(Monty ouvre 1 | voiture=0) = 1/2` (il hésite entre les portes 1 et 2), `P(... | voiture=1) = 0` (il ne montre jamais la voiture), `P(... | voiture=2) = 1` (il n'a plus le choix). Non normalisé : `1/6, 0, 1/3` ; constante de normalisation `1/2` ; exact : **`1/3, 0, 2/3`** — exactement ce que renvoie l'échantillonnage (0.333, 0.000, 0.667).\n",
"\n",
"L'information ne vient pas de la porte ouverte mais de la **règle** de Monty : « jamais la voiture, jamais le choix du joueur ». Si la voiture est en 0, Monty pouvait ouvrir 1 ou 2 — l'ouverture de la 1 n'apprend rien. Si elle est en 2, il était *forcé* d'ouvrir la 1 : cette ouverture est un aveu. La porte 0 ne bouge jamais de 1/3 parce que l'observation restait possible dans tous les mondes où le joueur avait bien choisi ; toute la masse libérée par l'information se concentre sur la porte 2. Changer double la chance de gagner : 0.667 contre 0.333."
],
"id": "aa0ed7e"
},
{
"cell_type": "markdown",
"id": "0d7e4f60",
Expand Down Expand Up @@ -748,6 +784,8 @@
"noyau de Metropolis specialise pour les `Categorical`. Le résultat est une\n",
"approximation Monte-Carlo du calcul exact qu'Infer.NET obtient par EP.\n",
"\n",
"La ligne « Performance » du tableau se lit maintenant avec les chiffres de ce notebook : Infer.NET (EP) donnerait 0.176 / 0.794 / 0.029 *analytiquement et instantanément* ; PyMC y arrive par 20 000 tirages en 14 secondes, au millième près. Sur deux tables de trois états, l'écart est invisible ; c'est sur les modèles continus non conjugués — là où EP doit approximer chaque message — que la généralité de MCMC devient le bon côté de l'arbitrage.\n",
"\n",
"***\n",
"\n",
"**Retour au sommaire** : [Index Probas](../README.md)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
bridge_verdict: SOTA-OK
bridge_verdict_reason: "Modele nominal lib-vs-lib cite par owner #10382 (\"PyMC vs Infer, 2 moteurs qui brillent\") : C# = Microsoft Infer.NET (Microsoft.ML.Probabilistic, NuGet officiel, native .NET, inférence variationnelle EP/VMP) et Python = PyMC (pip pymc, native Python, NUTS/HMC + ADVI). Chaque cote atteint le moteur SOTA de son ecosysteme probabiliste -- ni pont intermediaire ni reimplementation. Aucune asymetrie de machinerie a corriger. Verifie firsthand : C# Microsoft.ML.Probabilistic refs + execution_count, Python pymc imports."
known_differences:
- '2026-09-16 (myia-po-2023:CoursIA) #16364 : REBASELINE cote Python apres densification markdown (#13410) : 1227 -> 1915 mots (+2 cellules d''interpretation diagnostic MCMC et Monty Hall, 4 extensions), markdown-only, 9/9 cellules code byte-identiques, ids originaux preserves. content_csharp_sha inchange : le jumeau C# n''est pas touche.'
- '2026-08-19 (myia-ai-01) #11685 : REBASELINE cote C# apres reparation. Le merge 9881553 (#11622) avait re-execute Infer-3 sur une machine sans Graphviz -- le helper .NET imprime l''echec au lieu de lever, donc 6 bannieres "Problem with converting DOT to SVG" + chemins machine se sont retrouves dans les sorties, et l''audit precedent a enregistre un csharp_sha (bb769dc0f648) qui n''a JAMAIS ete le blob du fichier (test_twin_registry_integrity rouge sur main depuis ce merge). Repare par re-execution reelle avec dot sur le PATH (Graphviz 14.1.3 present sur ai-01, seulement absent du PATH) puis strip_probe_banner.py, --update en DERNIER (#8957). Volume de rendu verifie contre la base de fusion : blocs SVG 13356 -> 13362 et 28948 -> 28954 B, svg 2 -> 2 -- aucun livrable rendu perdu. content_python_sha inchange : le jumeau Python n''est pas touche.'
- 'Socle pedagogique commun : graphes de facteurs et variables aleatoires modelise dans les deux stacks.'
- 'Moteurs d''inference distincts : C# Infer.NET = inference deterministe approchee (Expectation Propagation / Variational
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
date: '2026-09-16'
by: myia-po-2023:CoursIA
python_sha: 2fd719b9ac10f6756066ae01e31e23c4cd64afbf
csharp_sha: e8381cc8e9ede47d089ce7c12fb8397c7cc1919e
content_python_sha: bdae44e7b6b0b0057a38e4c7093089780e905451a2b4c9207cc239d105f7ce81
content_csharp_sha: 4516c2c0a108f167aea626ccb6ce18b2a32c4ff8f2b92383fb6b8ab2c516a426
Loading