Ce notebook est distillé des sources fondatrices suivantes (audit fidélité, voir #8081) :
Evidence / marginal likelihood (Occam factor) — Bishop, C. M. (2006). Pattern Recognition and Machine Learning. Springer, §3.4 (Bayesian model comparison) et §3.5 (The evidence approximation). MacKay, D. J. C. (1992). Bayesian Interpolation, Neural Computation 4(3):415–447 — cadre fondateur de l’evidence framework.
Facteur de Bayes et échelle d’interprétation — Kass, R. E. & Raftery, A. E. (1995). Bayes Factors. Journal of the American Statistical Association, 90(430):773–795 (DOI 10.1080/01621459.1995.10476572). L’échelle de comparaison (substantielle / forte / décisive) est l’échelle de Jeffreys (1961), Theory of Probability, telle que rapportée et normalisée par Kass & Raftery.
Automatic Relevance Determination (ARD) — Tipping, M. E. (2001). Sparse Bayesian Learning and the Relevance Vector Machine. Journal of Machine Learning Research, 1:211–244. Également Bishop PRML §6.4.4 (ARD) et §7.2 (Relevance Vector Machines).
1. Configuration
Nous preparons l’environnement pour explorer la sélection de modèles bayesienne. Cette approche permet de comparer objectivement différents modèles en calculant leur evidence marginale, implementant ainsi le rasoir d’Occam de maniere mathematique.
The below script needs to be able to find the current output cell; this is an easy method to get it.
Installed Packages
Microsoft.ML.Probabilistic, 0.4.2504.701
Microsoft.ML.Probabilistic.Compiler, 0.4.2504.701
Infer.NET pret !
Chargement du helper de visualisation des graphes de facteurs.
// Chargement du helper pour visualisation des graphes de facteurs#load "FactorGraphHelper.cs"Console.WriteLine($"FactorGraphHelper charge. Graphviz disponible : {FactorGraphHelper.IsGraphvizAvailable()}");
Ce notebook utilise FactorGraphHelper.cs pour visualiser les graphes de facteurs generes par Infer.NET. Ces graphes montrent la structure probabiliste des modèles : les noeuds representent les variables aleatoires et les observations, les facteurs (carres) representent les distributions conditionnelles.
Pour activer la visualisation, on configure ShowFactorGraph = true sur le moteur d’inference.
Note technique : Calcul de l’evidence dans Infer.NET
Infer.NET calcule l’evidence du modèle via une astuce elegante :
On introduit une variable indicatrice evidence = Bernoulli(0.5)
Le modèle est conditionne par Variable.If(evidence)
Après inference, evidence.LogOdds donne le log de l’evidence
Pourquoi ca fonctionne ? Par le théorème de Bayes : \[P(\text{evidence}=\text{true}|D) \propto P(D|\text{evidence}=\text{true}) \times P(\text{evidence}=\text{true})\]
Comme \(P(\text{evidence}=\text{true}) = 0.5\), le log-odds posterieur est directement le log de l’evidence (a une constante pres).
Cette méthode est spécifique a Infer.NET et permet d’obtenir l’evidence sans calcul integral explicite.
2. Le Problème du Surapprentissage
Observation
Un modèle complexe peut parfaitement ajuster les données d’entrainement mais mal generaliser.
Exemple
Ajuster un polynome de degré n-1 a n points : ajustement parfait mais prediction catastrophique.
Solution bayesienne
Les priors penalisent les modèles complexes
L’evidence du modèle equilibre ajustement et complexite
C’est le rasoir d’Occam bayesien
3. Evidence du Modèle (Marginal Likelihood)
Définition
\[P(D|M) = \int P(D|\theta, M) P(\theta|M) d\theta\]
L’evidence est la probabilité des données sous le modèle, marginalisee sur les paramètres.
Interpretation
Un modèle simple fait des predictions moins precises mais moins dispersees
Un modèle complexe fait des predictions plus precises mais plus dispersees
L’evidence favorise le bon equilibre
Fidélité à la source (Bishop 2006, §3.4 ; MacKay 1992). L’evidence réalise un arbitrage automatique entre ajustement et complexité via le facteur d’Occam : un modèle complexe répartit sa masse de probabilité sur un espace d’hypothèses plus large, donc dilue\(P(D|M)\) dès que les données tombent hors d’une région étroite. Le modèle qui maximise l’evidence n’est ni le plus simple ni le mieux ajusté, mais celui dont la « portée » (volume de prédictions plausibles) épouse le mieux les données — c’est la formalisation bayésienne du rasoir d’Ockham que Bishop §3.4 développe en détail et que l’intégrale ci-dessus encode implicitement.
// Calcul de l'evidence avec Infer.NET// Donnéesdouble[] observations ={13,15,17,14,16,15,18};int n = observations.Length;// MODELE 1 : Une seule gaussienneVariable<bool> evidence1 = Variable.Bernoulli(0.5).Named("evidence1");using(Variable.If(evidence1)){ Variable<double> moyenne1 = Variable.GaussianFromMeanAndPrecision(15,0.01).Named("moyenne"); Variable<double> precision1 = Variable.GammaFromShapeAndScale(2,0.5).Named("precision");for(int i =0; i < n; i++){ Variable<double> obs1 = Variable.GaussianFromMeanAndPrecision(moyenne1, precision1).Named($"obs_{i}"); obs1.ObservedValue= observations[i];}}InferenceEngine moteur1 =newInferenceEngine();moteur1.Compiler.CompilerChoice= CompilerChoice.Roslyn;moteur1.ShowFactorGraph=true;// Activation de la visualisationdouble logEvidence1 = moteur1.Infer<Bernoulli>(evidence1).LogOdds;Console.WriteLine("=== Evidence du Modele ===");Console.WriteLine($"\nModele 1 (1 gaussienne) : log evidence = {logEvidence1:F2}");
Log evidence = -16.98 pour le modèle a une gaussienne.
Cette valeur negative est normale : c’est un logarithme de probabilité, donc toujours negatif (ou nul). Plus la valeur est proche de 0, meilleure est l’evidence.
En termes absolus, \(e^{-16.98} \approx 4.2 \times 10^{-8}\) semble très petit, mais c’est la comparaison relative entre modèles qui importe, pas la valeur absolue.
// Visualisation du graphe de facteurs - Modèle 1 gaussiennedisplay(HTML(FactorGraphHelper.GetLatestFactorGraphHtml()));
Model_06_22_26_21_16_50_24.svg
Lecture du graphe de facteurs - Modèle 1 gaussienne
Le graphe montre la structure du modèle a une gaussienne :
La variable evidence1 (Bernoulli) englobe tout le modèle via Variable.If(). Les 7 observations partagent la même moyenne et precision, ce qui represente l’hypothese i.i.d. (independantes et identiquement distribuees).
Implementation : Modèle 2 - Melange de deux gaussiennes
Le modèle de melange (mixture model) suppose que chaque observation provient de l’une ou l’autre de deux gaussiennes, avec une probabilité \(\pi\) pour la première et \(1-\pi\) pour la seconde.
Paramètres du modèle : - \(\mu_1, \mu_2\) : moyennes des deux composantes - \(\tau\) : precision commune (simplification) - \(\pi\) : proportion du melange (poids de la première composante)
Code : Pour chaque observation, on tire d’abord composante ~ Bernoulli(pi), puis on observe depuis la gaussienne correspondante.
Note algorithmique : Nous utilisons VariationalMessagePassing car les melanges de gaussiennes sont plus stables avec VMP qu’avec EP pour le calcul d’evidence.
Visualisation du graphe de facteurs du modèle de melange de gaussiennes.
// Visualisation du graphe de facteurs - Modèle melangedisplay(HTML(FactorGraphHelper.GetLatestFactorGraphHtml()));
Model_06_22_26_21_16_52_60.svg
Lecture du graphe de facteurs - Modèle melange
Le graphe du modèle de melange est plus complexe :
moyenne_a, moyenne_b : les deux centres des composantes gaussiennes
poids_mixte : paramètre Beta controlant la proportion du melange
comp_i : variable latente discrete (quelle composante genere l’observation i ?)
obs2_i : observations, chacune connectee aux deux moyennes via sa variable de composante
La structure en “gateway” (Variable.If/IfNot) créé des branchements conditionnels visibles dans le graphe. Chaque observation peut provenir de l’une ou l’autre gaussienne selon comp_i.
Référence. Kass & Raftery (1995), Bayes Factors, JASA 90(430):773–795. Le tableau ci-dessus est l’échelle de Jeffreys (1961, Theory of Probability) telle que consolidée par Kass & Raftery. À noter : les seuils originels de Jeffreys (1–3 / 3–10 / 10–30 / 30–150 / >150 en \(\log\)) diffèrent légèrement des seuils alternatifs (3 / 20 / 150) utilisés ailleurs dans la littérature — le notebook suit la convention de Jeffreys, ce qui est un choix légitime à documenter explicitement.
// Facteur de Bayesdouble logBF = logEvidence1 - logEvidence2;double BF = Math.Exp(logBF);Console.WriteLine("=== Facteur de Bayes ===");Console.WriteLine($"\nlog(BF) = {logBF:F2}");Console.WriteLine($"BF = {BF:F2}");string interpretation;if(Math.Abs(logBF)<1) interpretation ="Evidence negligeable";elseif(Math.Abs(logBF)<2) interpretation ="Evidence substantielle";elseif(Math.Abs(logBF)<3) interpretation ="Evidence forte";else interpretation ="Evidence tres forte/decisive";string favori = logBF >0?"Modele 1 (1 gaussienne)":"Modele 2 (melange)";Console.WriteLine($"\n{interpretation} en faveur de : {favori}");
=== Facteur de Bayes ===
log(BF) = 3,14
BF = 23,03
Evidence tres forte/decisive en faveur de : Modele 1 (1 gaussienne)
Interprétation du facteur de Bayes
Résultat : log(BF) = 3.14, BF ≈ 23
Selon l’échelle de Jeffreys, un BF de 23 représente une evidence forte (entre 10 et 30) en faveur du modèle 1.
Pourquoi le modèle simple gagne-t-il ?
Les données {13, 15, 17, 14, 16, 15, 18} sont unimodales avec moyenne ~15.3. Le modèle à 2 gaussiennes : 1. Introduit des paramètres inutiles (2 moyennes, poids du mélange) 2. Ces paramètres doivent être “expliqués” par le prior 3. Le prior “dilue” la vraisemblance sur un espace plus grand
C’est le rasoir d’Occam bayésien en action : à ajustement égal, le modèle simple est préféré car il fait des prédictions plus “concentrées”.
Formule intuitive : Evidence ≈ (vraisemblance) × (volume du prior utilisé) / (volume total du prior)
5. Sélection du Nombre de Composantes
Application
Determiner le nombre optimal de composantes dans un modèle de melange.
Données bimodales : quand le modèle complexe gagne
Les données précédentes etaient unimodales (autour de 15). Testons maintenant avec des données clairement bimodales : deux groupes bien separes autour de 6 et 15.
Question : Le modèle a 2 composantes va-t-il maintenant etre prefere ?
L’algorithme compare systematiquement 1 vs 2 composantes en calculant l’evidence de chaque modèle.
// Données bimodalesdouble[] dataBimodal ={5,6,7,5.5,6.5,15,16,17,14,15.5,16.5,6,15};int nBi = dataBimodal.Length;Console.WriteLine("=== Selection du nombre de composantes ===");Console.WriteLine($"Donnees : {string.Join(",", dataBimodal)}\n");// Test avec 1, 2, 3 composantesdouble[] logEvidences =newdouble[3];// 1 composante{ Variable<bool> ev = Variable.Bernoulli(0.5);using(Variable.If(ev)){ Variable<double> m = Variable.GaussianFromMeanAndPrecision(10,0.01); Variable<double> p = Variable.GammaFromShapeAndScale(2,0.5);foreach(var d in dataBimodal){ Variable<double> o = Variable.GaussianFromMeanAndPrecision(m, p); o.ObservedValue= d;}}var eng =newInferenceEngine(); eng.Compiler.CompilerChoice= CompilerChoice.Roslyn; logEvidences[0]= eng.Infer<Bernoulli>(ev).LogOdds;}Console.WriteLine($"1 composante : log evidence = {logEvidences[0]:F2}");// 2 composantes - simplifie{ Variable<bool> ev = Variable.Bernoulli(0.5);using(Variable.If(ev)){ Variable<double> m1 = Variable.GaussianFromMeanAndPrecision(6,0.1); Variable<double> m2 = Variable.GaussianFromMeanAndPrecision(15,0.1); Variable<double> p = Variable.GammaFromShapeAndScale(2,1); Variable<double> w = Variable.Beta(1,1);foreach(var d in dataBimodal){ Variable<bool> c = Variable.Bernoulli(w); Variable<double> o = Variable.New<double>();using(Variable.If(c)){ o.SetTo(Variable.GaussianFromMeanAndPrecision(m1, p));}using(Variable.IfNot(c)){ o.SetTo(Variable.GaussianFromMeanAndPrecision(m2, p));} o.ObservedValue= d;}}var eng =newInferenceEngine(newVariationalMessagePassing()); eng.Compiler.CompilerChoice= CompilerChoice.Roslyn; logEvidences[1]= eng.Infer<Bernoulli>(ev).LogOdds;}Console.WriteLine($"2 composantes : log evidence = {logEvidences[1]:F2}");// Meilleur modèleint meilleur = logEvidences[0]> logEvidences[1]?1:2;Console.WriteLine($"\n=> Le modele a {meilleur} composante(s) est prefere");
=== Selection du nombre de composantes ===
Donnees : 5, 6, 7, 5,5, 6,5, 15, 16, 17, 14, 15,5, 16,5, 6, 15
Compiling model...done.
Iterating:
.........|.........|.........|.........|.........| 50
1 composante : log evidence = -45,89
Compiling model...done.
Iterating:
.........|.........|.........|.........|.........| 50
2 composantes : log evidence = -31,35
=> Le modele a 2 composante(s) est prefere
Analyse des résultats : données bimodales
Données : deux groupes distincts autour de 6 et 15
Modèle
Log evidence
Interpretation
1 composante
-45.89
Mal adapte (moyenne ~10.5 ne represente aucun groupe)
2 composantes
-31.35
Bien adapte (capture les deux modes)
Différence : log(BF) = -31.35 - (-45.89) = 14.54
Un facteur de Bayes \(e^{14.54} \approx 2 \times 10^6\) en faveur du modèle a 2 composantes constitue une evidence decisive.
Lecon cle : Le facteur de Bayes detecte automatiquement la structure des données. Il prefere le modèle simple quand les données sont simples (section 3-4) et le modèle complexe quand les données l’exigent (ici).
6. Automatic Relevance Determination (ARD)
Principe
ARD utilise des priors hiérarchiques pour determiner automatiquement quelles features sont pertinentes.
Si \(\alpha_f\) devient grand, le poids \(w_f\) est contraint pres de 0 -> feature non pertinente.
Fidélité à la source (Tipping 2001 ; Bishop PRML §6.4.4 et §7.2). Le mécanisme d’ARD est le cœur du Sparse Bayesian Learning de Tipping : le prior hiérarchique \(\alpha_f \sim \text{Gamma}\) agit comme une « précision » apprise par inférence. Pour une feature non pertinente, les données ne contraignent pas \(w_f\), le posterior de \(\alpha_f\) croît vers de grandes valeurs, et le prior \(w_f \sim \mathcal{N}(0, \alpha_f^{-1})\) rétrécit le poids vers zéro — la feature est ainsi automatiquement désactivée par le modèle lui-même, sans seuillage manuel. C’est exactement le principe exploité par le Relevance Vector Machine (RVM), qui n’en retient qu’un petit sous-ensemble de « relevance vectors ».
Transition : de la comparaison de modèles a la sélection de features
Jusqu’ici, nous avons compare des modèles entiers (1 vs 2 gaussiennes, lineaire vs quadratique). Mais en pratique, on veut souvent repondre a une question plus fine :
Quelles features sont vraiment utiles dans mon modèle ?
C’est le problème de la sélection de variables. L’approche bayesienne offre une solution elegante : l’Automatic Relevance Determination (ARD).
Generation des données synthetiques
Nous creons un problème de regression ou : - Feature 1 : coefficient reel = 2.0 (pertinente) - Feature 2 : coefficient reel = 0.0 (non pertinente) - Feature 3 : coefficient reel = 3.0 (pertinente)
Le modèle ARD devra “decouvrir” automatiquement que la feature 2 n’apporte aucune information predictive.
// ARD pour regression// Données : y = 2*x1 + 0*x2 + 3*x3 + bruit// x2 est une feature non pertinenteint nSamples =20;int nFeatures =3;Random rng =newRandom(42);double[,] X =newdouble[nSamples, nFeatures];double[] y =newdouble[nSamples];double[] vraisPoids ={2.0,0.0,3.0};// x2 a poids 0for(int i =0; i < nSamples; i++){for(int f =0; f < nFeatures; f++){ X[i, f]= rng.NextDouble()*2-1;// [-1, 1]} y[i]= vraisPoids[0]* X[i,0]+ vraisPoids[1]* X[i,1]+ vraisPoids[2]* X[i,2]+ rng.NextDouble()*0.5-0.25;// Bruit}Console.WriteLine("=== ARD : Automatic Relevance Determination ===");Console.WriteLine($"\nVrais poids : w1={vraisPoids[0]}, w2={vraisPoids[1]} (non pertinent), w3={vraisPoids[2]}");
Le modèle ARD introduit un hyperparametre de precision\(\alpha_f\) pour chaque feature \(f\) :
\[w_f \sim \mathcal{N}(0, \alpha_f^{-1})\]
Interpretation : - Si \(\alpha_f\) est petit (ex: 0.3), la variance \(1/\alpha_f\) est grande, donc \(w_f\) peut prendre des valeurs significatives - Si \(\alpha_f\) devient grand (ex: 10), la variance est petite, \(w_f\) est “pousse” vers 0
Les \(\alpha_f\) sont eux-mêmes des variables aleatoires avec prior Gamma(1, 1). L’inference determine simultanement les poids et leur pertinence.
// Modèle ARDRange sampleRange =newRange(nSamples).Named("sample");Range featureRange =newRange(nFeatures).Named("feature");// Precisions par feature (ARD)VariableArray<double> alpha = Variable.Array<double>(featureRange).Named("alpha");alpha[featureRange]= Variable.GammaFromShapeAndScale(1,1).ForEach(featureRange);// Poids avec prior dependant de alphaVariableArray<double> poids = Variable.Array<double>(featureRange).Named("poids");using(Variable.ForEach(featureRange)){ poids[featureRange]= Variable.GaussianFromMeanAndPrecision(0, alpha[featureRange]);}// Bruit de l'observationVariable<double> noisePrecision = Variable.GammaFromShapeAndScale(2,1).Named("noise");// DonnéesVariableArray2D<double> xVar = Variable.Array<double>(sampleRange, featureRange).Named("x");VariableArray<double> yVar = Variable.Array<double>(sampleRange).Named("y");using(Variable.ForEach(sampleRange)){ Variable<double> prediction = Variable.Constant(0.0);for(int f =0; f < nFeatures; f++){ prediction = prediction + poids[f]* xVar[sampleRange, f];} yVar[sampleRange]= Variable.GaussianFromMeanAndPrecision(prediction, noisePrecision);}xVar.ObservedValue= X;yVar.ObservedValue= y;InferenceEngine moteurARD =newInferenceEngine(newExpectationPropagation());moteurARD.Compiler.CompilerChoice= CompilerChoice.Roslyn;moteurARD.ShowFactorGraph=true;// Activation de la visualisationGaussian[] poidsPost = moteurARD.Infer<Gaussian[]>(poids);Gamma[] alphaPost = moteurARD.Infer<Gamma[]>(alpha);Console.WriteLine("\nResultats ARD :");for(int f =0; f < nFeatures; f++){double wMean = poidsPost[f].GetMean();double wStd = Math.Sqrt(poidsPost[f].GetVariance());double alphaMean = alphaPost[f].GetMean();string relevance = alphaMean >5?"faible": alphaMean >1?"moyenne":"haute"; Console.WriteLine($" Feature {f+1} : poids = {wMean:F2} +/- {wStd:F2}, alpha = {alphaMean:F2} (pertinence {relevance})");}Console.WriteLine("\n=> Les features avec alpha eleve sont considerees non pertinentes");
Visualisation du graphe de facteurs du modèle ARD.
// Visualisation du graphe de facteurs - Modèle ARDdisplay(HTML(FactorGraphHelper.GetLatestFactorGraphHtml()));
Model_06_22_26_21_17_01_25.svg
Lecture du graphe de facteurs - Modèle ARD hiérarchique
Le graphe ARD illustre la structure hiérarchique a deux niveaux :
Niveau hyperparametres : - alpha[feature] : precision par feature (hyperparametre Gamma) - Le prior sur alpha contrôle la “force” de la regularisation
Niveau paramètres : - poids[feature] : poids de regression, chacun avec une precision alpha[f] différente - Les poids sont couples : poids[f] ~ N(0, 1/alpha[f])
Niveau données : - x[sample, feature] : matrice des features (observee) - y[sample] : cible (observee) - noise : precision du bruit (infere)
La structure “plate notation” avec ForEach créé des repetitions sur les ranges sample et feature, representees par des boites dans le graphe.
Analyse des résultats ARD
Comparaison vrais poids vs estimations :
Feature
Vrai poids
Estimé
α estimé
Pertinence
1
2.0
2.04
0.49
Haute ✓
2
0.0
0.02
1.49
Moyenne
3
3.0
2.97
0.28
Haute ✓
Interprétation des hyperparamètres α : - α petit (< 1) → le prior sur w est large → w peut prendre des valeurs significatives → feature pertinente - α grand (> 1) → le prior sur w est concentré autour de 0 → w contraint à ~0 → feature non pertinente
Pourquoi Feature 2 n’a pas α très élevé ?
Avec seulement 20 échantillons, le modèle reste incertain. α = 1.49 indique une pertinence “moyenne” plutôt que clairement nulle. Plus de données augmenteraient α pour cette feature.
Application pratique : ARD est utilisé en machine learning pour la sélection automatique de features sans validation croisée explicite.
Exercice : ARD avec 5 features – quelles features sont pertinentes ?
L’exemple précédent montrait l’ARD avec 3 features (dont 1 non pertinente). Dans cet exercice, vous allez appliquer l’ARD a un problème plus realiste avec 5 features, dont seulement 2 sont reellement informatives.
Seules les features 1 et 4 contribuent a la prediction. Les features 2, 3 et 5 sont du bruit.
Travail demande : 1. Generez les données avec nSamples = 30 et nFeatures = 5 (seed 42) 2. Construisez le modèle ARD hiérarchique (reutilisez la structure de la section 6) 3. Lancez l’inference et affichez les poids posterieurs et les valeurs alpha pour chaque feature 4. Identifiez quelles features sont selectionnees (alpha faible = pertinente) 5. Comparez les poids estimes avec les vrais poids : {1.5, 0.0, 0.0, 2.5, 0.0}
Indice : Avec plus de features (5 vs 3) et plus de données (30 vs 20), les alpha des features non pertinentes devraient etre plus eleves qu’avec 3 features, car le modèle a plus d’information pour distinguer le signal du bruit. Utilisez le même prior Gamma(1, 1) sur les alpha et ExpectationPropagation pour l’inference.
// Exercice : ARD avec 5 features// TODO: Étape 1 - Generer les données synthetiquesint nSamplesARD =30;int nFeaturesARD =5;double[] vraisPoidsARD ={1.5,0.0,0.0,2.5,0.0};double[,] XARD =newdouble[nSamplesARD, nFeaturesARD];// TODO: remplir avec Random(42)double[] yARD =newdouble[nSamplesARD];// TODO: calculer y = sum(w_f * x_f) + bruit// TODO: Étape 2 - Construire le modèle ARD hierarchique// Range sampleRangeARD = new Range(nSamplesARD);// Range featureRangeARD = new Range(nFeaturesARD);// VariableArray<double> alphaARD = ... (Gamma prior par feature)// VariableArray<double> poidsARD = ... (Gaussian avec precision alphaARD)// Variable<double> noiseARD = ... (Gamma prior sur bruit)// Relation: y = sum(poids[f] * x[f])// TODO: Étape 3 - Inference avec ExpectationPropagation// TODO: Étape 4 - Afficher les résultats// Console.WriteLine("=== Résultats ARD (5 features) ===");// Pour chaque feature : afficher poids moyen, ecart-type, alpha, pertinence// TODO: Étape 5 - Comparer avec les vrais poids et conclure// Quelles features ont ete correctement identifiees comme pertinentes/non pertinentes ?Console.WriteLine("Exercice a completer");
Exercice a completer
7. Validation Croisee Bayesienne
Principe
Au lieu de diviser les données, utiliser la predictive posterieure pour evaluer le modèle.
Pour chaque point \(i\) : 1. Entrainer le modèle sur tous les points sauf \(i\) 2. Calculer la distribution predictive posterieure 3. Evaluer la log-probabilité du point \(i\) sous cette predictive
La variance predictive combine deux sources d’incertitude : - L’incertitude sur la moyenne (\(\text{Var}(\mu)\)) - Le bruit inherent des observations (\(1/\tau\))
Cette metrique mesure la capacite du modèle a predire des observations non vues. Comparons avec des références :
Log predictive moyenne
Qualite du modèle
> -1.0
Excellente
-1.0 a -2.0
Bonne
-2.0 a -3.0
Acceptable
< -3.0
Mauvaise
Notre valeur de -1.81 indique une bonne capacite predictive.
Avantage du LOO bayesien : Contrairement au LOO classique, cette méthode : - Utilise l’incertitude complete (pas juste une estimation ponctuelle) - Tient compte de l’incertitude sur les paramètres via la variance predictive - Ne necessite pas de reentrainer completement le modèle (en théorie, via des approximations)
Exercice : Sélection de modèle par validation croisee LOO
Dans cette section, vous avez vu la validation Leave-One-Out pour un modèle gaussien simple. L’objectif de cet exercice est d’etendre cette approche pour comparer deux modèles sur les mêmes données, et de verifier si le résultat LOO est coherent avec le facteur de Bayes.
Enonce
On considere les données bimodales de la section 5 :
Modèle A : Une seule gaussienne \(y \sim \mathcal{N}(\mu, \tau^{-1})\) avec priors : - \(\mu \sim \mathcal{N}(10, 100)\) (moyenne vague) - \(\tau \sim \text{Gamma}(2, 0.5)\)
Modèle B : Melange de deux gaussiennes (même structure que la section 5).
Travail demandé : 1. Implementez la validation LOO pour le modèle A (une gaussienne) 2. Implementez la validation LOO pour le modèle B (melange de deux gaussiennes) - utilisez VariationalMessagePassing 3. Comparez les scores LOO totaux : quel modèle est prefere ? 4. Comparez avec le résultat du facteur de Bayes de la section 5 : les deux méthodes donnent-elles le même gagnant ?
Indice : Pour le modèle B dans la boucle LOO, vous devez recreer le modèle de melange complet a chaque itération (en retirant le point i). La distribution predictive posterieure d’un melange n’est pas gaussienne – utilisez GetMean() et GetVariance() sur le résultat Gaussian inferé pour chaque point laisse de cote.
// Exercice : Sélection de modèle par validation croisee LOOdouble[] dataEx ={5,6,7,5.5,6.5,15,16,17,14,15.5,16.5,6,15};int nEx = dataEx.Length;// TODO: Étape 1 - Implementer LOO pour le Modèle A (1 gaussienne)// Pour chaque point i, entrainer sur dataEx sans le point i, calculer log P(dataEx[i])double totalLogPredA =0;// TODO: Boucle LOO Modèle AConsole.WriteLine($"Modele A - LOO total : {totalLogPredA:F2}");// TODO: Étape 2 - Implementer LOO pour le Modèle B (melange 2 gaussiennes)// Utilisez VariationalMessagePassing pour la stabilitedouble totalLogPredB =0;// TODO: Boucle LOO Modèle B// Indice : pour chaque iteration, recreer le melange complet sans le point i// puis inferer la posteriorie et evaluer la log-probabilité du point laisse de coteConsole.WriteLine($"Modele B - LOO total : {totalLogPredB:F2}");// TODO: Étape 3 - Comparer les résultatsConsole.WriteLine("\n=== Comparaison LOO ===");// Quel modèle est prefere par LOO ?// Est-ce coherent avec le facteur de Bayes de la section 5 (2 composantes preferees) ?Console.WriteLine("Exercice a completer");
Modele A - LOO total : 0,00
Modele B - LOO total : 0,00
=== Comparaison LOO ===
Exercice a completer
Exercice : Comparer les critères BIC et evidence approximee
Dans les sections précédentes, nous avons utilise l’evidence exacte (marginal likelihood) calculee par Infer.NET pour comparer des modèles. En pratique, l’evidence exacte est souvent incalculable et on utilise des approximations comme le BIC (Bayesian Information Criterion).
Enonce
Le BIC est défini par :
\[\text{BIC} = -2 \ln(\hat{L}) + k \ln(n)\]
ou \(\hat{L}\) est la vraisemblance maximale, \(k\) le nombre de paramètres et \(n\) le nombre d’observations. Un BIC plus faible indique un meilleur modèle.
On reprend les données bimodales de la section 5 :
Travail demande : 1. Pour le modèle a 1 gaussienne, calculez le BIC en estimant mu et tau par maximum de vraisemblance (moyenne empirique et variance inverse) 2. Pour le modèle a 2 gaussiennes, utilisez les posteriors Infer.NET de la section 5 comme approximation du MLE, puis calculez le BIC (k = 5 paramètres : mu1, mu2, tau, poids, + 1 bruit) 3. Comparez les classements BIC vs facteur de Bayes : les deux méthodes selectionnent-elles le même modèle ? 4. Affichez un tableau comparatif : | Critere | Modèle 1 | Modèle 2 | Gagnant |
Indice : Pour le BIC du modèle a 1 gaussienne, \(k=2\) (mu + tau). La log-vraisemblance se calcule en sommant Gaussian.FromMeanAndPrecision(mu_hat, tau_hat).GetLogProb(dataBIC[i]) pour chaque point. Pour le modèle a 2 gaussiennes, \(k=5\) (mu1, mu2, tau, poids + variance commune). Le BIC penalise davantage les modèles complexes que le facteur de Bayes – observez si la penalite change le gagnant.
// Exercice : Comparer les criteres BIC et evidence approximeedouble[] dataBIC ={5,6,7,5.5,6.5,15,16,17,14,15.5,16.5,6,15};int nBIC = dataBIC.Length;// TODO: Étape 1 - Calculer le BIC pour le modèle a 1 gaussienne (k=2)// Estimer mu_hat = moyenne empirique, tau_hat = 1 / variance empirique// Puis BIC = -2 * sum(log P(x_i | mu_hat, tau_hat)) + k * ln(n)double bicModele1 =0;// Indice : double muHat = dataBIC.Average();// Indice : double varHat = dataBIC.Select(x => (x - muHat) * (x - muHat)).Sum() / nBIC;// Indice : double tauHat = 1.0 / varHat;// Indice : double logLik = dataBIC.Sum(x => Gaussian.FromMeanAndPrecision(muHat, tauHat).GetLogProb(x));// Indice : bicModele1 = -2 * logLik + 2 * Math.Log(nBIC);Console.WriteLine($"Modele 1 (1 gaussienne) - BIC : {bicModele1:F2}");// TODO: Étape 2 - Calculer le BIC pour le modèle a 2 gaussiennes (k=5)// Utilisez les posteriors de la section 5 ou estimez par MLEdouble bicModele2 =0;// Indice : k=5 parametres (mu1, mu2, tau, poids, variance)// Indice : Pour chaque point, la vraisemblance est P(x_i) = w * N(x_i|mu1,tau) + (1-w) * N(x_i|mu2,tau)// Indice : log P(x_i) = log(w * exp(logN1) + (1-w) * exp(logN2))Console.WriteLine($"Modele 2 (2 gaussiennes) - BIC : {bicModele2:F2}");// TODO: Étape 3 - Comparer BIC vs facteur de BayesConsole.WriteLine("\n=== Comparaison BIC vs Facteur de Bayes ===");// Indice : Le facteur de Bayes de la section 5 favorisait le modèle a 2 composantes (log BF ~ 14.5)// Indice : Le BIC favorise-t-il le meme modèle ? Si oui, les deux méthodes sont coherentes.// Indice : Si non, expliquez pourquoi (taille d'echantillon, approximation BIC, etc.)// TODO: Étape 4 - Afficher le tableau comparatif// | Critere | Modèle 1 | Modèle 2 | Gagnant |// |----------------------|----------|----------|------------|// | BIC (plus petit=mieux)| ... | ... | ... |// | log Evidence | -45.89 | -31.35 | Modèle 2 |Console.WriteLine("Exercice a completer");
Modele 1 (1 gaussienne) - BIC : 0,00
Modele 2 (2 gaussiennes) - BIC : 0,00
=== Comparaison BIC vs Facteur de Bayes ===
Exercice a completer
8. Exemple guide : Comparer Polynomes
Enonce
Comparez trois modèles de regression : - Lineaire : y = ax + b - Quadratique : y = ax^2 + bx + c - Cubique : y = ax^3 + bx^2 + cx + d
Sur des données lineaires avec bruit.
Mise en pratique : comparaison lineaire vs quadratique
Les données sont generees selon \(y = 2x + 1 + \epsilon\) (relation lineaire).
Le modèle quadratique peut representer la relation lineaire (avec \(a \approx 0\)), mais paie un “cout de complexite” pour ce paramètre inutile.
Hint : Pour ajouter un modèle cubique, il suffirait d’ajouter un terme \(d \times x^3\). Le même raisonnement s’applique : plus de paramètres = plus de penalite si ils ne sont pas necessaires.
// Exemple guide : Comparaison de modèles polynomiaux// Données lineaires : y = 2*x + 1 + bruitdouble[] xPoly ={0,1,2,3,4,5,6,7,8,9};double[] yPoly ={1.2,3.1,4.8,7.2,8.9,11.1,13.0,14.8,17.2,19.1};int nPoly = xPoly.Length;Console.WriteLine("=== Comparaison de Modeles Polynomiaux ===");Console.WriteLine("Vraie relation : y = 2*x + 1\n");// Modèle lineaireVariable<bool> evLin = Variable.Bernoulli(0.5).Named("evidence_lin");using(Variable.If(evLin)){ Variable<double> a = Variable.GaussianFromMeanAndVariance(0,10).Named("a_lin"); Variable<double> b = Variable.GaussianFromMeanAndVariance(0,10).Named("b_lin"); Variable<double> noise = Variable.GammaFromShapeAndScale(2,0.5).Named("noise_lin");for(int i =0; i < nPoly; i++){ Variable<double> pred =(a * xPoly[i]+ b).Named($"pred_lin_{i}"); Variable<double> obs = Variable.GaussianFromMeanAndPrecision(pred, noise).Named($"obs_lin_{i}"); obs.ObservedValue= yPoly[i];}}var engLin =newInferenceEngine();engLin.Compiler.CompilerChoice= CompilerChoice.Roslyn;engLin.ShowFactorGraph=true;// Activation de la visualisationdouble logEvLin = engLin.Infer<Bernoulli>(evLin).LogOdds;Console.WriteLine($"Modele lineaire : log evidence = {logEvLin:F2}");// Modèle quadratiqueVariable<bool> evQuad = Variable.Bernoulli(0.5).Named("evidence_quad");using(Variable.If(evQuad)){ Variable<double> a = Variable.GaussianFromMeanAndVariance(0,10).Named("a_quad"); Variable<double> b = Variable.GaussianFromMeanAndVariance(0,10).Named("b_quad"); Variable<double> c = Variable.GaussianFromMeanAndVariance(0,10).Named("c_quad"); Variable<double> noise = Variable.GammaFromShapeAndScale(2,0.5).Named("noise_quad");for(int i =0; i < nPoly; i++){ Variable<double> pred =(a * xPoly[i]* xPoly[i]+ b * xPoly[i]+ c).Named($"pred_quad_{i}"); Variable<double> obs = Variable.GaussianFromMeanAndPrecision(pred, noise).Named($"obs_quad_{i}"); obs.ObservedValue= yPoly[i];}}var engQuad =newInferenceEngine();engQuad.Compiler.CompilerChoice= CompilerChoice.Roslyn;engQuad.ShowFactorGraph=true;// Activation de la visualisationdouble logEvQuad = engQuad.Infer<Bernoulli>(evQuad).LogOdds;Console.WriteLine($"Modele quadratique : log evidence = {logEvQuad:F2}");// Meilleur modèlestring meilleurMod = logEvLin > logEvQuad ?"Lineaire":"Quadratique";Console.WriteLine($"\n=> Le modele {meilleurMod} est prefere (rasoir d'Occam)");
Visualisation du graphe de facteurs du modèle polynomial.
// Visualisation du graphe de facteurs - Modèle quadratique (dernier compile)display(HTML(FactorGraphHelper.GetLatestFactorGraphHtml()));
Model_06_22_26_21_17_07_14.svg
Lecture du graphe de facteurs - Modèle quadratique
Le graphe montre la structure du modèle quadratique \(y = ax^2 + bx + c\) :
a_quad, b_quad, c_quad : les trois coefficients du polynome (priors Gaussiens)
noise_quad : precision du bruit d’observation (prior Gamma)
evidence_quad : variable indicatrice pour le calcul d’evidence
pred_quad_i : predictions intermediaires (combinaison des coefficients)
obs_quad_i : observations (valeurs fixees)
Comparativement au modèle lineaire, ce graphe contient un paramètre supplementaire (c_quad), ce qui augmente la complexite du modèle et la “surface” du prior - d’ou la penalisation par le rasoir d’Occam bayesien.
Coefficient quadratique inutile : le paramètre \(a\) (coefficient de \(x^2\)) n’apporte rien
Penalite de complexite : le prior sur \(a\) “dilue” la vraisemblance
Exercice supplementaire : Que se passerait-il si les données etaient generees par y = 0.1x^2 + 2x + 1 ? Le terme quadratique est present mais faible. Le modèle lineaire pourrait encore gagner si le signal quadratique est noye dans le bruit - c’est la balance ajustement vs complexite en action.
Sélection du nombre de composantes : Clustering avec nombre de clusters inconnu
Sélection de features : Regression avec beaucoup de covariables
Choix d’architecture : Reseaux bayesiens avec structure variable
Comparaison de familles : Lineaire vs non-lineaire, parametrique vs non-parametrique
Points cles a retenir
1. Le rasoir d’Occam est automatique
La sélection de modèles bayesienne penalise naturellement la complexite. Pas besoin de critères ad hoc comme l’AIC ou le BIC - l’evidence marginale fait le travail.
2. L’echelle compte
Méthode
Quand l’utiliser
Facteur de Bayes
Comparer 2-3 modèles distincts
ARD
Sélectionner parmi de nombreuses features
LOO-CV
Evaluer la capacite predictive
3. Les priors sont importants
Les priors vagues (\(\sigma^2 = 10\) sur les poids) penalisent moins que des priors informatifs. Un mauvais choix de prior peut fausser la comparaison.
Conseil pratique : Pour une comparaison equitable, utilisez des priors de même “force” (même variance) sur les paramètres comparables entre modèles.
10. Exercice : Trouver le Meilleur Modèle pour des Données Quadratiques
Enonce
Vous disposez de données generees par y = 2*x^2 - 3*x + 1 + bruit :
x = {-2, -1, 0, 1, 2, 3}
y = {14.8, 5.9, 1.1, -0.2, 3.8, 10.1}
Comparez 3 modèles de regression polynomiale : 1. Lineaire : y = a*x + b (2 paramètres) 2. Quadratique : y = a*x^2 + b*x + c (3 paramètres) 3. Cubique : y = a*x^3 + b*x^2 + c*x + d (4 paramètres)
Quel modèle a le meilleur log evidence ? Le cubique surpasse-t-il le quadratique ?
// Exercice : Sélection de modèle polynomial sur données quadratiquesConsole.WriteLine("Exercice a completer : selection de modele polynomial");// Données quadratiques : y = 2*x^2 - 3*x + 1 + bruitdouble[] xData ={-2,-1,0,1,2,3};double[] yData ={14.8,5.9,1.1,-0.2,3.8,10.1};// TODO: Construire les matrices de features polynomiales// Lineaire : X[i] = [1, x_i]// Quadratique: X[i] = [1, x_i, x_i^2]// Cubique : X[i] = [1, x_i, x_i^2, x_i^3]// using Microsoft.ML.Probabilistic.Math;// TODO: Creer une fonction CalculLogEvidence(Vector[] features, double[] y)// (Reutilisez la structure de la section 8 de l'exemple guide)// TODO: Calculer le log evidence pour chaque modèle// TODO: Afficher et comparer// Quel modèle gagne ? Expliquez pourquoi le cubique ne bat pas forcement le quadratique.
Exercice a completer : selection de modele polynomial
Conclusion
Ce notebook a presente la sélection de modèles bayesienne : evidence, facteur de Bayes, ARD et validation croisee LOO.
Méthode
Principe
Quand l’utiliser
Evidence (marginal likelihood)
P(D|M) integre sur les paramètres
Comparer 2-3 modèles
Facteur de Bayes
Ratio des evidences, echelle de Jeffreys
Quantifier la préférence
ARD
Priors hiérarchiques Gamma -> precision par feature
Sélection automatique de features
LOO-CV
Log-probabilité predictive leave-one-out
Evaluer la capacite predictive
Distribution
Rôle
Bernoulli(0.5)
Variable indicatrice pour le calcul d’evidence
Gaussian
Priors sur les poids et coefficients
Gamma
Priors sur les precisions (bruit, ARD)
Beta
Prior sur les proportions de melange
Rasoir d’Occam bayesien : L’evidence penalise automatiquement la complexite. Un modèle plus simple avec un bon ajustement bat toujours un modèle complexe dont les paramètres supplementaires n’apportent rien. Cela rend la comparaison objective, sans critères ad hoc.