Les ordinateurs sont rigoureusement logiques, mais le monde reel ne l’est pas. Considerez ces exemples :
Un système de reconnaissance d’ecriture manuscrite : le gribouillis peut correspondre a “hill”, “bull” ou “hello”
Un diagnostic medical : les symptomes peuvent indiquer plusieurs maladies possibles
Un système de recommandation : les préférences de l’utilisateur sont partiellement connues
Dans tous ces cas, nous devons raisonner avec de l’incertitude.
Variables aléatoires
Les variables conventionnelles (bool, int, double) ont des valeurs bien définies. La programmation probabiliste introduit les variables aléatoires qui représentent un ensemble de valeurs possibles, chacune associée a une probabilité.
// Variable classique - valeur fixebool estFace =true;// Variable aléatoire - distribution de probabilitéVariable<bool> estFace = Variable.Bernoulli(0.5);// 50% de chance
Les 3 piliers de la programmation probabiliste
Modèles probabilistes : Definissent comment les observations sont générées
Inférence bayesienne : Raisonne de l’effet vers la cause
Apprentissage : Les paramètres eux-mêmes sont des variables aléatoires
2. Presentation d’Infer.NET
Qu’est-ce que Infer.NET ?
Infer.NET est un framework Microsoft pour l’inférence bayesienne dans les modèles graphiques. Il fait partie de la bibliotheque ML.NET.
Caractéristiques principales :
Caractéristique
Description
Langage de modelisation
Variables continues et discretes, univariees et multivariees
Ajout de distributions, facteurs et algorithmes personnalises
Comment fonctionne Infer.NET ?
1. Définition du modèle --> API de modelisation
|
v
2. Compilation du modèle --> Génération de code source
|
v
3. Exécution de l'inférence --> Calcul des distributions posterieures
3. Installation
Avant de commencer, nous devons installer les packages NuGet necessaires. Infer.NET est distribue en deux packages : - Microsoft.ML.Probabilistic : Contient les distributions, le moteur d’inférence et les algorithmes - Microsoft.ML.Probabilistic.Compiler : Permet la compilation dynamique des modèles en code optimise
L’installation via #r "nuget: télécharge automatiquement les packages et leurs dépendances.
Important : Si Graphviz est installe, la cellule suivante l’ajoute automatiquement au PATH pour permettre la visualisation des graphes de facteurs.
// Configuration multiplateforme du PATH pour Graphviz// Cette cellule doit s'executer avant le chargement d'Infer.NET pour que le moteur trouve 'dot'.using System.Runtime.InteropServices;var graphvizPaths = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)?new[]{ @"C:\Program Files\Graphviz\bin", @"C:\Program Files (x86)\Graphviz\bin"}: RuntimeInformation.IsOSPlatform(OSPlatform.OSX)?new[]{"/opt/homebrew/bin",// Homebrew sur Apple Silicon"/usr/local/bin"// Homebrew sur Mac Intel}:new[]{"/usr/bin","/usr/local/bin"};var dotExecutable = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)?"dot.exe":"dot";foreach(var gvPath in graphvizPaths){var dotPath = System.IO.Path.Combine(gvPath, dotExecutable);if(!System.IO.File.Exists(dotPath))continue;var currentPath = Environment.GetEnvironmentVariable("PATH")??"";var pathEntries = currentPath.Split( System.IO.Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries);var comparison = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)? StringComparison.OrdinalIgnoreCase: StringComparison.Ordinal;if(!pathEntries.Any(entry =>string.Equals(entry, gvPath, comparison))){ Environment.SetEnvironmentVariable("PATH", gvPath + System.IO.Path.PathSeparator+ currentPath); Console.WriteLine($"Graphviz configure pour cette plateforme : {gvPath}");}else{ Console.WriteLine($"Graphviz deja dans le PATH : {gvPath}");}break;}// Verification avec ProcessStartInfo correctement configuretry{var psi =new System.Diagnostics.ProcessStartInfo{ FileName ="dot", Arguments ="-V", RedirectStandardError =true, RedirectStandardOutput =true, UseShellExecute =false, CreateNoWindow =true};usingvar proc = System.Diagnostics.Process.Start(psi);var stderr = proc.StandardError.ReadToEnd();var stdout = proc.StandardOutput.ReadToEnd(); proc.WaitForExit();var versionOutput =string.IsNullOrWhiteSpace(stderr)? stdout : stderr;if(proc.ExitCode==0|| versionOutput.Contains("graphviz", StringComparison.OrdinalIgnoreCase)) Console.WriteLine($"Verification OK : {versionOutput.Trim()}");else Console.WriteLine($"Graphviz trouve mais verification echouee (code {proc.ExitCode})");}catch{var installHint = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)?"winget install Graphviz.Graphviz": RuntimeInformation.IsOSPlatform(OSPlatform.OSX)?"brew install graphviz":"sudo apt install graphviz"; Console.WriteLine($"Graphviz non disponible (optionnel). Installation : {installHint}");}
The below script needs to be able to find the current output cell; this is an easy method to get it.
Graphviz configure pour cette plateforme : C:\Program Files\Graphviz\bin
Verification OK : dot - graphviz version 14.1.5 (20260411.2331)
Verification de la configuration Graphviz
La cellule précédente détecte la plateforme, recherche dot dans les emplacements usuels et utilise le séparateur de PATH fourni par .NET (; sous Windows, : sous Linux et macOS).
Message
Signification
Graphviz configure pour cette plateforme : ...
Le répertoire de dot a été ajouté au PATH du kernel
Graphviz deja dans le PATH : ...
Le répertoire est déjà configuré dans la session
Verification OK : dot - graphviz version ...
Le binaire Graphviz répond correctement
Graphviz trouve mais verification echouee (code N)
Le binaire a démarré mais a renvoyé un code inattendu
Graphviz non disponible ... Installation : ...
Graphviz est absent ; la commande adaptée à Windows, macOS ou Linux est indiquée
Commandes d’installation usuelles :
Windows : winget install Graphviz.Graphviz
macOS : brew install graphviz
Debian/Ubuntu : sudo apt install graphviz
Note : Graphviz reste optionnel pour l’inférence. Sans dot, Infer.NET peut générer les fichiers .gv, visualisables ensuite sur viz-js.com.
// Installation des packages NuGet Infer.NET#r "nuget: Microsoft.ML.Probabilistic"#r "nuget: Microsoft.ML.Probabilistic.Compiler"
Installing Packages
Microsoft.ML.Probabilistic
Microsoft.ML.Probabilistic.Compiler
Note : Infer.NET fait desormais partie de la bibliotheque ML.NET de Microsoft.
// Import des espaces de noms essentielsusing Microsoft.ML.Probabilistic;using Microsoft.ML.Probabilistic.Distributions;using Microsoft.ML.Probabilistic.Utilities;using Microsoft.ML.Probabilistic.Math;using Microsoft.ML.Probabilistic.Models;using Microsoft.ML.Probabilistic.Algorithms;using Microsoft.ML.Probabilistic.Compiler;Console.WriteLine("Infer.NET charge avec succes !");Console.WriteLine($" - Microsoft.ML.Probabilistic.Models : Variables aleatoires et modeles");Console.WriteLine($" - Microsoft.ML.Probabilistic.Distributions : Gaussian, Beta, Dirichlet...");Console.WriteLine($" - Microsoft.ML.Probabilistic.Algorithms : EP, VMP, Gibbs");Console.WriteLine($" - Microsoft.ML.Probabilistic.Compiler : Compilation Roslyn des modeles");
Infer.NET charge avec succes !
- Microsoft.ML.Probabilistic.Models : Variables aleatoires et modeles
- Microsoft.ML.Probabilistic.Distributions : Gaussian, Beta, Dirichlet...
- Microsoft.ML.Probabilistic.Algorithms : EP, VMP, Gibbs
- Microsoft.ML.Probabilistic.Compiler : Compilation Roslyn des modeles
Chargement du helper de visualisation des graphes de facteurs.
// Chargement du helper pour la visualisation des factor graphs// (Une version inline est aussi definie plus bas dans ce notebook)#load "FactorGraphHelper.cs"Console.WriteLine("FactorGraphHelper.cs charge depuis le fichier externe !");Console.WriteLine("Usage: moteur.ShowFactorGraph = true; puis display(HTML(FactorGraphHelper.GetLatestFactorGraphHtml()))");
FactorGraphHelper.cs charge depuis le fichier externe !
Usage: moteur.ShowFactorGraph = true; puis display(HTML(FactorGraphHelper.GetLatestFactorGraphHtml()))
Espaces de noms Infer.NET charges
La cellule précédente a importe les espaces de noms essentiels. Voici leur rôle :
Namespace
Contenu
Usage principal
Microsoft.ML.Probabilistic.Models
Variable<T>, VariableArray<T>, Range
Définition des modèles probabilistes
Microsoft.ML.Probabilistic.Distributions
Gaussian, Beta, Gamma, Dirichlet
Distributions de probabilité
Microsoft.ML.Probabilistic.Algorithms
ExpectationPropagation, VariationalMessagePassing
Algorithmes d’inférence
Microsoft.ML.Probabilistic.Compiler
InferenceEngine, CompilerChoice
Compilation et exécution
Microsoft.ML.Probabilistic.Math
Fonctions mathematiques
Opérations sur distributions
Architecture Infer.NET : Le moteur d’inférence compile votre modèle en code C# optimise, stocke dans GeneratedSource/. Cette approche “compile une fois, execute plusieurs fois” offre d’excellentes performances.
4. Premier Exemple : Le Lancer de Deux Pieces
Enonce du problème
Quelle est la probabilité d’obtenir deux faces lors du lancer de deux pieces non biaisées ?
// Étape 1 : Définition du modèle probabilisteVariable<bool> premierePiece = Variable.Bernoulli(0.5);// Piece 1 : 50% faceVariable<bool> deuxiemePiece = Variable.Bernoulli(0.5);// Piece 2 : 50% faceVariable<bool> deuxFaces = premierePiece & deuxiemePiece;// ET logique// Étape 2 : Création du moteur d'inferenceInferenceEngine moteur =newInferenceEngine();moteur.Compiler.CompilerChoice= CompilerChoice.Roslyn;// Necessaire pour .NET Interactive// Étape 3 : Execution de l'inferencevar resultat = moteur.Infer(deuxFaces);Console.WriteLine($"Probabilite d'obtenir deux faces : {resultat}");
Compiling model...done.
Probabilite d'obtenir deux faces : Bernoulli(0,25)
Analyse de la sortie
Le résultat Bernoulli(0,25) représente une distribution de Bernoulli avec paramètre p = 0.25 :
Interpretation : La variable deuxFaces a 25% de chance d’être vraie
Coherence mathematique : 0.5 × 0.5 = 0.25 ✓
Remarquez les messages “Compiling model… done.” lors de la première exécution. Infer.NET compile dynamiquement votre modèle en code C# optimise, stocke dans un répertoire GeneratedSource/. Cette compilation n’a lieu qu’une fois par modèle.
Pourquoi une distribution et pas juste 0.25 ?
Infer.NET retourne toujours des distributions complètes, pas seulement des valeurs ponctuelles. Cela permet de propager l’incertitude dans des modèles plus complexes.
5. Les 3 Étapes Fondamentales
Tout programme Infer.NET suit ces 3 étapes :
Étape 1 : Définition du Modèle
Créez des variables aléatoires et definissez leurs relations.
// Variables aléatoires avec leurs distributions a prioriVariable<bool> A = Variable.Bernoulli(0.5);Variable<bool> B = Variable.Bernoulli(0.5);// Variable derivee (dependante)Variable<bool> C = A & B;// C depend de A et B
Étape 2 : Création du Moteur d’Inférence
Le moteur compile le modèle et prepare l’algorithme d’inférence.
InferenceEngine moteur =newInferenceEngine();moteur.Compiler.CompilerChoice= CompilerChoice.Roslyn;// Pour notebooks
Étape 3 : Exécution de l’Inférence
Demandez au moteur de calculer la distribution d’une variable.
var résultat = moteur.Infer(C);// Distribution marginale de C
6. Types de Distributions Fondamentales
Infer.NET supporte de nombreuses distributions. Voici les plus courantes :
Distribution
Type
Usage
Exemple
Bernoulli
Discrete
Événement binaire
Pile/Face, Vrai/Faux
Discrete
Discrete
Catégorie parmi N
Choix d’un jour, couleur
Gaussian
Continue
Valeur reelle avec incertitude
Taille, temperature
Gamma
Continue
Precision, variance
Bruit, fiabilite
Beta
Continue
Probabilité inconnue
Taux de succes
Dirichlet
Continue
Vecteur de probabilités
Poids de mélange
// Exemples de création de variables aleatoires// Bernoulli : probabilité d'un événement binaireVariable<bool> pluie = Variable.Bernoulli(0.3);// 30% de chance de pluie// Discrete : choix parmi N optionsVariable<int> jourSemaine = Variable.DiscreteUniform(7);// Uniform sur 0-6// Gaussian : valeur continue avec incertitudeVariable<double> temperature = Variable.GaussianFromMeanAndVariance(20,4);// Moyenne 20, variance 4// Gamma : precision (inverse de la variance)Variable<double> precision = Variable.GammaFromShapeAndScale(2,0.5);Console.WriteLine("Variables creees avec succes !");
Variables creees avec succes !
Interpretation des variables créées
La cellule précédente a crée quatre variables aléatoires. Voici ce que représente chacune :
Variable
Type
Distribution
Paramètres
Interpretation
pluie
Variable<bool>
Bernoulli(0.3)
p = 0.3
30% de chance de pluie
jourSemaine
Variable<int>
DiscreteUniform(7)
n = 7
Chaque jour equiprobable (1/7)
temperature
Variable<double>
Gaussian(20, 4)
mu = 20, var = 4
Temperature moyenne 20 degrés, ecart-type 2
precision
Variable<double>
Gamma(2, 0.5)
shape = 2, scale = 0.5
Precision avec moyenne 1, mode 0.5
Rappel sur les parametrisations :
Gaussian(mean, variance) : La variance est le carre de l’ecart-type
Attention : Ces variables ne sont pas encore “liées” entre elles. Dans un modèle complet, on definirait des dépendances (ex: la temperature influence la probabilité de pluie).
7. Exemple Avance : Pièce Biaisée
Considerons une pièce potentiellement biaisée. Nous observons 7 faces sur 10 lancers. Quel est le biais de la pièce ?
Modèle bayesien pour l’estimation de biais
Le code suivant illustre les étapes clés d’un modèle bayesien :
Prior : Beta(1,1) = distribution uniforme, aucune croyance initiale sur le biais
Vraisemblance : Chaque lancer suit Bernoulli(biais)
Observations : 7 faces sur 10 lancers
Inférence : Calcul de la distribution posterieure du biais
Beta(1,1) est un prior “non-informatif” : il donne la même probabilité a toutes les valeurs de biais entre 0 et 1. C’est équivalent a dire “je n’ai aucune idee a priori du biais de la pièce”.
// Modèle pour estimer le biais d'une piece// A priori : le biais peut être n'importe quelle valeur entre 0 et 1// Beta(1,1) = distribution uniforme sur [0,1]Variable<double> biais = Variable.Beta(1,1);// Observations : 10 lancersint nombreLancers =10;Range lancers =newRange(nombreLancers);VariableArray<bool> resultats = Variable.Array<bool>(lancers);// Chaque lancer suit une distribution Bernoulli avec le biais inconnuusing(Variable.ForEach(lancers)){ resultats[lancers]= Variable.Bernoulli(biais);}// Observations : 7 faces (true), 3 piles (false)resultats.ObservedValue=newbool[]{true,true,true,true,true,true,true,false,false,false};// InferenceInferenceEngine moteur =newInferenceEngine();moteur.Compiler.CompilerChoice= CompilerChoice.Roslyn;Beta biaisPosterieur = moteur.Infer<Beta>(biais);Console.WriteLine($"Distribution a posteriori du biais : {biaisPosterieur}");Console.WriteLine($"Moyenne estimee du biais : {biaisPosterieur.GetMean():F3}");Console.WriteLine($"Intervalle de confiance (ecart-type) : +/- {Math.Sqrt(biaisPosterieur.GetVariance()):F3}");
Compiling model...done.
Distribution a posteriori du biais : Beta(8,4)[mean=0,6667]
Moyenne estimee du biais : 0,667
Intervalle de confiance (ecart-type) : +/- 0,131
Visualisation du graphe de facteurs du modèle de biais de pièce.
// Visualisation du factor graph pour le modèle de piece biaisée// Recreons le modèle avec ShowFactorGraph = trueVariable<double> biaisViz = Variable.Beta(1,1).Named("biais");int nLancers =10;Range lancersViz =newRange(nLancers).Named("lancers");VariableArray<bool> resultatsViz = Variable.Array<bool>(lancersViz).Named("resultats");using(Variable.ForEach(lancersViz)){ resultatsViz[lancersViz]= Variable.Bernoulli(biaisViz);}resultatsViz.ObservedValue=newbool[]{true,true,true,true,true,true,true,false,false,false};InferenceEngine moteurViz =newInferenceEngine();moteurViz.Compiler.CompilerChoice= CompilerChoice.Roslyn;moteurViz.ShowFactorGraph=true;Beta biaisPost = moteurViz.Infer<Beta>(biaisViz);Console.WriteLine($"Biais estime: {biaisPost}");// Afficher le factor graphdisplay(HTML(FactorGraphHelper.GetLatestFactorGraphHtml()));
Compiling model...done.
Biais estime: Beta(8,4)[mean=0,6667]
Model_09_12_26_13_44_35_46.svg
Factor Graph : Modèle de Pièce Biaisée
Le graphe de facteurs ci-dessus illustre la structure du modèle bayesien :
Legende du graphe : - Rectangles : Facteurs (distributions de probabilité) - Ellipses : Variables aléatoires - Fleches : Connexions entre facteurs et variables
Interpretation : 1. Le prior Beta(1,1) initialise notre croyance sur le biais de la pièce (uniforme) 2. La variable biais est partagee par tous les facteurs Bernoulli (conjugaison) 3. Chaque résultat[i] est génère independamment par Bernoulli(biais) 4. Les observations (7 faces, 3 piles) contraignent le modèle
Flux des messages : - Durant l’inférence, les messages de vraisemblance remontent des observations vers le biais - Le facteur Beta combine ces messages avec le prior pour produire le posterior Beta(8,4)
Rendu Graphviz : Graphviz est détecté dans le PATH du kernel et le helper convertit le fichier .gv généré par Infer.NET en SVG affiché directement dans la sortie précédente. Si dot est absent sur une autre plateforme, le fichier .gv reste visualisable sur viz-js.com ou edotor.net.
Analyse detaillee du résultat
Sortie obtenue : Beta(8,4)[mean=0,6667]
La distribution Beta(α, β) représente notre croyance mise a jour sur le biais de la pièce :
Paramètre
Valeur
Signification
α (alpha)
8
1 (prior) + 7 (faces observées)
β (beta)
4
1 (prior) + 3 (piles observes)
Moyenne
0.667
α / (α + β) = 8/12
Ecart-type
0.131
Mesure de l’incertitude residuelle
Pourquoi Beta(8,4) et pas simplement 7/10 ?
Integration du prior : Nous avons commence avec Beta(1,1), équivalent a avoir déjà observe 1 face et 1 pile
Formule de mise a jour : Beta(α + n_faces, β + n_piles) = Beta(1+7, 1+3) = Beta(8,4)
Moyenne legerement biaisée : 0.667 vs 0.700 (l’effet du prior diminue avec plus d’observations)
Concept clé : Conjugaison
La distribution Beta est conjuguee a Bernoulli : prior Beta + observations Bernoulli = posterior Beta.
Cette propriete permet une mise a jour analytique exacte, sans approximation.
8. Exemple guide : Trois Pieces
Enonce
Vous lancez trois pieces non biaisées. Calculez :
La probabilité d’obtenir exactement trois faces
La probabilité d’obtenir au moins deux faces
Indice
Pour “au moins deux faces”, vous pouvez utiliser plusieurs variables derivees : - deuxOuTrois = (p1 & p2) | (p1 & p3) | (p2 & p3)
Solution
Code de l’exercice
La cellule suivante contient la solution de référence. Essayez de comprendre chaque ligne avant de l’executer :
Lignes 4-6 : Création de trois variables Bernoulli independantes
Ligne 9 : Conjonction logique (AND) des trois variables
Ligne 13 : Disjonction logique (OR) de paires - structure plus complexe
La valeur 0.5781 au lieu de 0.5 s’explique par l’algorithme d’inférence approchee utilise par Infer.NET (Expectation Propagation).
Pour “au moins deux faces”, la vraie probabilité est : - P(exactement 2 faces) = C(3,2) × 0.5³ = 3 × 0.125 = 0.375 - P(exactement 3 faces) = 0.125 - Total = 0.5
L’ecart vient de la complexite des correlations entre variables dans l’expression (p1&p2) | (p1&p3) | (p2&p3). Les mêmes variables apparaissent dans plusieurs termes, creant des dépendances que l’algorithme EP approxime.
Bon a savoir : Infer.NET utilise des algorithmes d’inférence variationnelle qui peuvent introduire de legeres erreurs sur des modèles avec des structures de dépendance complexes. Pour des calculs exacts sur des modèles discrets simples, d’autres approches (enumeration, junction tree) seraient plus précises.
8bis. Troubleshooting et Debogage
Cette section couvre les problemes courants avec Infer.NET et leurs solutions.
Erreurs Communes
Erreur
Cause
Solution
Model has no support
Variable observée incompatible avec le prior
Verifier que les observations sont dans le support du prior
Improper distribution
Divergence de l’inférence
Utiliser des priors plus informatifs ou changer d’algorithme
Could not find method
Opération non supportée
Reformuler le modèle avec des opérations supportées
Note : La configuration de Graphviz a ete effectuee en section 3. Les fichiers .gv generes peuvent être visualises sur viz-js.com si Graphviz n’est pas installe.
// Inspection du code genere et du factor graphConsole.WriteLine("=== Options de Debug Infer.NET ===\n");// Verification de Graphviz (le PATH a ete configure au debut du notebook)bool graphvizInstalle =false;try{var psi =new System.Diagnostics.ProcessStartInfo{ FileName ="dot", Arguments ="-V", RedirectStandardError =true, RedirectStandardOutput =true, UseShellExecute =false, CreateNoWindow =true};usingvar proc = System.Diagnostics.Process.Start(psi);var stderr = proc.StandardError.ReadToEnd(); proc.WaitForExit();if(proc.ExitCode==0|| stderr.Contains("graphviz")){ Console.WriteLine($"Graphviz disponible : {stderr.Trim()}"); graphvizInstalle =true;}}catch(Exception ex){ Console.WriteLine($"Verification Graphviz echouee : {ex.Message}");}if(!graphvizInstalle){ Console.WriteLine("Graphviz non detecte - les fichiers .gv seront generes"); Console.WriteLine("Visualisez-les sur : https://viz-js.com/\n");}Console.WriteLine();// Création d'un modèle simple pour demonstrationVariable<double> x = Variable.GaussianFromMeanAndPrecision(0,1).Named("x");Variable<double> y = Variable.GaussianFromMeanAndPrecision(x,1).Named("y");y.ObservedValue=2.0;// Moteur avec options de debugInferenceEngine moteurDebug =newInferenceEngine();moteurDebug.Compiler.CompilerChoice= CompilerChoice.Roslyn;// Option 1 : Afficher le schedule d'inferencemoteurDebug.ShowSchedule=true;Console.WriteLine("1. ShowSchedule = true : Affiche l'ordre des calculs de messages\n");// Option 2 : Afficher le factor graph (genere .gv et .svg si Graphviz disponible)moteurDebug.ShowFactorGraph=true;Console.WriteLine("2. ShowFactorGraph = true : Genere fichier DOT"+(graphvizInstalle ?" + SVG":" (SVG si Graphviz disponible)")+"\n");// Option 3 : Sauvegarder le code generemoteurDebug.Compiler.WriteSourceFiles=true;moteurDebug.Compiler.GeneratedSourceFolder="GeneratedSource";Console.WriteLine("3. WriteSourceFiles = true : Sauvegarde le code C# genere dans GeneratedSource/\n");// Option 4 : Montrer les avertissements de compilationmoteurDebug.Compiler.ShowWarnings=true;Console.WriteLine("4. ShowWarnings = true : Affiche les avertissements du compilateur\n");// Executer l'inferenceConsole.WriteLine("--- Execution avec options debug ---\n");var xPost = moteurDebug.Infer<Gaussian>(x);Console.WriteLine($"\nResultat : x ~ {xPost}");// Note : Le FactorGraphHelper est défini plus bas dans ce notebook.// Une fois charge, utilisez : display(HTML(FactorGraphHelper.GetLatestFactorGraphHtml()))Console.WriteLine("\n--- Factor Graph ---");Console.WriteLine("Fichiers .gv generes. Voir section FactorGraphHelper ci-dessous pour l'affichage inline.");
=== Options de Debug Infer.NET ===
Graphviz disponible : dot - graphviz version 14.1.5 (20260411.2331)
1. ShowSchedule = true : Affiche l'ordre des calculs de messages
2. ShowFactorGraph = true : Genere fichier DOT + SVG
3. WriteSourceFiles = true : Sauvegarde le code C# genere dans GeneratedSource/
4. ShowWarnings = true : Affiche les avertissements du compilateur
--- Execution avec options debug ---
Compiling model...done.
Resultat : x ~ Gaussian(1, 0,5)
--- Factor Graph ---
Fichiers .gv generes. Voir section FactorGraphHelper ci-dessous pour l'affichage inline.
Interpretation du résultat d’inférence en mode debug
Sortie obtenue : x ~ Gaussian(1, 0.5)
Ce résultat représente la distribution posterieure de la variable x après avoir observe y = 2.0.
Paramètre
Valeur
Signification
Moyenne
1.0
Estimation centrale de x
Variance
0.5
Incertitude sur x (ecart-type ~ 0.71)
Pourquoi cette mise a jour ?
Prior : x ~ N(0, 1) - nous pensions que x était proche de 0
Observation : y = 2.0, avec y ~ N(x, 1)
Posterior : x ~ N(1, 0.5) - compromis entre le prior et l’observation
Le posterior est “tire” vers l’observation (moyenne passe de 0 a 1) tout en reduisant l’incertitude (variance passe de 1 a 0.5).
Formule analytique (cas gaussien) :
La moyenne posterieure = (prior_precision × prior_mean + likelihood_precision × observation) / (prior_precision + likelihood_precision)
Soit : (1×0 + 1×2) / (1+1) = 1
Utilisation des Options de Debug
Quand utiliser chaque option :
Option
Utilite
ShowSchedule
Comprendre l’ordre des messages, identifier les boucles infinies
ShowFactorGraph
Visualiser le modèle, verifier les connections
WriteSourceFiles
Inspecter le code génère, optimiser manuellement
ShowWarnings
Detecter les approximations, opérateurs experimentaux
Fichiers generes :
Le dossier GeneratedSource/ contient : - Model_EP.cs : Code d’inférence pour EP - Model_VMP.cs : Code d’inférence pour VMP - Ces fichiers sont du C# pur, compilable et executable
Visualisation des Factor Graphs
Lorsque ShowFactorGraph = true est active, Infer.NET génère des fichiers .gv (format DOT Graphviz) decrivant la structure du modèle.
Avec Graphviz installe : La conversion en SVG est automatique.
Sans Graphviz : Les fichiers .gv peuvent être visualises sur viz-js.com ou edotor.net.
Dans ce graphe : - Les rectangles représentent les facteurs (distributions) - Les cercles représentent les variables aléatoires - Les fleches indiquent le flux de messages entre facteurs et variables
Helper : Affichage inline des Factor Graphs
Le code suivant définit un helper FactorGraphHelper pour afficher les graphes de facteurs directement dans les cellules du notebook. Ce helper : - Detecte automatiquement les fichiers .gv generes par Infer.NET - Les convertit en SVG via Graphviz - Les affiche inline dans la sortie de la cellule
// Helper pour afficher les graphes de facteurs (SVG) inline dans le notebookusing System.IO;using System.Linq;using Microsoft.DotNet.Interactive.Formatting;/// <summary>/// Helper pour generer et afficher les factor graphs Infer.NET dans les notebooks/// </summary>publicstaticclass FactorGraphHelper{privatestaticbool? _graphvizAvailable =null;/// <summary>/// Verifie si Graphviz (dot) est disponible/// </summary>publicstaticboolIsGraphvizAvailable(){if(_graphvizAvailable.HasValue)return _graphvizAvailable.Value;try{var psi =new System.Diagnostics.ProcessStartInfo{ FileName ="dot", Arguments ="-V", RedirectStandardError =true, RedirectStandardOutput =true, UseShellExecute =false, CreateNoWindow =true};usingvar proc = System.Diagnostics.Process.Start(psi); proc.WaitForExit(3000); _graphvizAvailable =(proc.ExitCode==0);}catch{ _graphvizAvailable =false;}return _graphvizAvailable.Value;}/// <summary>/// Retourne le HTML pour afficher le dernier fichier SVG genere par Infer.NET/// Usage: display(HTML(FactorGraphHelper.GetLatestFactorGraphHtml()))/// </summary>publicstaticstringGetLatestFactorGraphHtml(int maxWidth =800){var svgFiles = Directory.GetFiles(Environment.CurrentDirectory,"Model_*.svg");if(svgFiles.Length>0){var latestSvg = svgFiles.OrderByDescending(f =>newFileInfo(f).LastWriteTime).First();returnGetSvgFileHtml(latestSvg, maxWidth);}else{returnConvertAndGetLatestGvHtml(maxWidth);}}/// <summary>/// Retourne le HTML pour afficher un fichier SVG inline/// </summary>publicstaticstringGetSvgFileHtml(string svgPath,int maxWidth =800){if(!File.Exists(svgPath))return $"<div style='color:red'>Fichier non trouve : {svgPath}</div>";var svgContent = File.ReadAllText(svgPath);var fileName = Path.GetFileName(svgPath);returnGetSvgContentHtml(svgContent, fileName, maxWidth);}/// <summary>/// Retourne le HTML pour afficher du contenu SVG/// </summary>publicstaticstringGetSvgContentHtml(string svgContent,string title ="Factor Graph",int maxWidth =800){return $@"<div style=""margin:10px 0; padding:10px; border:1px solid #ddd; border-radius:5px; background: #fafafa;""><div style=""font-weight: bold; margin-bottom:8px; color: #333;"">{title}</div><div style=""max-width:{maxWidth}px; overflow: auto;"">{svgContent}</div></div>";}/// <summary>/// Convertit un fichier .gv en SVG et retourne le HTML/// </summary>publicstaticstringConvertAndGetGvHtml(string gvPath,int maxWidth =800){if(!File.Exists(gvPath))return $"<div style='color:red'>Fichier .gv non trouve : {gvPath}</div>";if(!IsGraphvizAvailable()){var fileName = Path.GetFileName(gvPath);return $@"<div style='padding: 10px; border: 1px solid #f0ad4e; background: #fcf8e3; border-radius: 5px;'><strong>Graphviz non disponible.</strong><br/> Copiez le contenu de <code>{fileName}</code> sur <a href='https://viz-js.com/' target='_blank'>viz-js.com</a></div>";}var svgPath = Path.ChangeExtension(gvPath,".svg");try{var psi =new System.Diagnostics.ProcessStartInfo{ FileName ="dot", Arguments = $"-Tsvg \"{gvPath}\" -o \"{svgPath}\"", RedirectStandardError =true, UseShellExecute =false, CreateNoWindow =true};usingvar proc = System.Diagnostics.Process.Start(psi); proc.WaitForExit(5000);if(proc.ExitCode==0&& File.Exists(svgPath))returnGetSvgFileHtml(svgPath, maxWidth);else{var error = proc.StandardError.ReadToEnd();return $"<div style='color:red'>Erreur Graphviz : {error}</div>";}}catch(Exception ex){return $"<div style='color:red'>Erreur : {ex.Message}</div>";}}/// <summary>/// Trouve et convertit le dernier fichier .gv/// </summary>publicstaticstringConvertAndGetLatestGvHtml(int maxWidth =800){var gvFiles = Directory.GetFiles(Environment.CurrentDirectory,"Model_*.gv");if(gvFiles.Length==0){return @"<div style='padding: 10px; border: 1px solid #d9534f; background: #f2dede; border-radius: 5px;'> Aucun fichier .gv trouve.<br/> Activez <code>ShowFactorGraph =true</code> sur le moteur d'inference.</div>";}var latestGv = gvFiles.OrderByDescending(f =>newFileInfo(f).LastWriteTime).First();returnConvertAndGetGvHtml(latestGv, maxWidth);}/// <summary>/// Nettoie les fichiers .gv et .svg generes/// </summary>publicstaticintCleanupGeneratedFiles(){var files = Directory.GetFiles(Environment.CurrentDirectory,"Model_*.gv").Concat(Directory.GetFiles(Environment.CurrentDirectory,"Model_*.svg")).Concat(Directory.GetFiles(Environment.CurrentDirectory,"Task_Graph_*.gv"));int count =0;foreach(var file in files){try{ File.Delete(file); count++;}catch{}}return count;}}Console.WriteLine("FactorGraphHelper charge !");Console.WriteLine(" - display(HTML(FactorGraphHelper.GetLatestFactorGraphHtml())) : affiche le dernier graphe");Console.WriteLine(" - FactorGraphHelper.CleanupGeneratedFiles() : nettoie les fichiers generes");
FactorGraphHelper charge !
- display(HTML(FactorGraphHelper.GetLatestFactorGraphHtml())) : affiche le dernier graphe
- FactorGraphHelper.CleanupGeneratedFiles() : nettoie les fichiers generes
Utilisation du FactorGraphHelper
Une fois la cellule précédente executee, vous pouvez afficher les graphes de facteurs directement dans le notebook :
// Afficher le dernier graphe génèredisplay(HTML(FactorGraphHelper.GetLatestFactorGraphHtml()));// Nettoyer les fichiers temporairesFactorGraphHelper.CleanupGeneratedFiles();
Méthodes disponibles :
Méthode
Description
GetLatestFactorGraphHtml()
Affiche le dernier graphe SVG inline
GetSvgFileHtml(path)
Affiche un fichier SVG spécifique
ConvertAndGetGvHtml(path)
Convertit un .gv en SVG et l’affiche
CleanupGeneratedFiles()
Supprime les fichiers .gv et .svg generes
IsGraphvizAvailable()
Verifie si Graphviz est installe
9. Resume
Dans ce notebook, vous avez appris :
Concept
Description
Programmation probabiliste
Representer l’incertitude avec des variables aléatoires
Modelisez le lancer de deux des a 6 faces avec Infer.NET.
Créez deux variables aléatoires discretes uniformes représentant chaque de (6 faces)
Definissez leur somme comme variable dependante
Calculez la probabilité que la somme soit superieure ou egale a 10
Conditionnez sur le fait que le premier de affiche 6 (valeur = 5 en 0-indexe) et re-inferez
Indice : Utilisez Variable.DiscreteUniform(6) et Variable.If() pour conditionner.
// Exercice : Modèle de deux des a 6 faces// TODO: Creer le moteur d inference avec Roslyn// Indice: InferenceEngine + CompilerChoice.Roslyn// TODO: Creer les deux variables aleatoires pour les des (valeurs 0-5 representant faces 1-6)// Indice: utilisez Variable.DiscreteUniform() avec le bon nombre de faces// TODO: Inferer la distribution marginale de chaque de (avant observation)// Indice: engine.Infer<Discrete>(variable)// TODO: Observer que le premier de montre 6 (valeur = 5) et re-inferer de2// Indice: utilisez .ObservedValue puis re-inferez la distribution de l autre de// Question: La distribution de de2 change-t-elle apres observation de de1 ? Pourquoi ?Console.WriteLine("Exercice a completer");
Exercice a completer
Conclusion
Ce notebook d’introduction a pose les fondements de la programmation probabiliste avec Infer.NET :
Visualisation de la structure du modèle via Graphviz
Debugging
ShowFactorGraph, ShowSchedule, WriteSourceFiles
Point clé : Infer.NET retourne toujours des distributions complètes (Gaussian, Beta, Bernoulli), jamais de simples valeurs ponctuelles, ce qui permet de propager l’incertitude a travers tout le modèle.
Comment fonctionne Infer.NET ?