Ce notebook est distillé des sources fondatrices suivantes (audit fidélité, voir #8081) :
Bayes Point Machine — Herbrich, R., Graepel, T. & Campbell, C. (2001). Bayes Point Machines. Journal of Machine Learning Research, 1:245–279. DOI: 10.1162/153244301753683717. Papier fondateur : le BPM approxime la prédiction bayésienne complète par un unique point représentatif (le « Bayes point »), estimé par Expectation Propagation.
Régression logistique bayésienne (probit, EP) — Bishop, C. M. (2006). Pattern Recognition and Machine Learning. Springer. §4.3 (Probit Regression), §4.5 (Bayesian Logistic Regression).
Exemple de référence Infer.NET — dépôt dotnet/infer, dossier Examples (Bayes Point Machine, classification). Implémentation canonique C# dont ce notebook est dérivé.
1. Configuration
Cette section prepare l’environnement pour les modèles de classification bayesienne. Contrairement aux classifieurs déterministes, l’approche bayesienne fournit non seulement une prediction mais aussi une mesure de confiance via des distributions de probabilite.
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 visualiser les graphes de facteurs#load "FactorGraphHelper.cs"// Verification de la disponibilite de Graphvizif(FactorGraphHelper.IsGraphvizAvailable()) Console.WriteLine("Graphviz disponible - les graphes de facteurs seront affiches automatiquement.");else Console.WriteLine("Graphviz non installe - utilisez viz-js.com pour visualiser les fichiers .gv generes.");
Graphviz disponible - les graphes de facteurs seront affiches automatiquement.
Environnement pret
Les packages Infer.NET charges incluent : - Microsoft.ML.Probabilistic : Structures de données probabilistes (distributions, variables) - Microsoft.ML.Probabilistic.Compiler : Compilation des modèles en code executable - Microsoft.ML.Probabilistic.Math : Fonctions mathematiques (MMath.NormalCdf pour le probit)
Les algorithmes d’inference disponibles pour la classification :
Algorithme
Usage
Precision
ExpectationPropagation (EP)
modèles probit, BPM
Haute
VariationalMessagePassing (VMP)
modèles gaussiens mixtes
Moderee
GibbsSampling
modèles complexes
très haute (mais lent)
Note : Pour la classification, EP est généralement prefere car il gere bien les facteurs de troncature (comparaisons avec seuils) inherents aux modèles probit.
2. Classification Probabiliste
différence avec la classification classique
Approche
Sortie
Incertitude
Classique
Classe predite
Non
Probabiliste
P(classe)
Oui
Bayesienne
Distribution sur P(classe)
Oui + incertitude sur le modèle
Avantages bayesiens
Quantification de l’incertitude
Regularisation naturelle (priors)
Mise a jour incrementale
Pas de surapprentissage si bon prior
3. Regression Logistique Bayesienne (1 feature)
Architecture du modèle probit
Le modèle de regression logistique bayesienne utilise une variable latente gaussienne :
ou : - \(w\) est le poids (prior Gaussien) - \(b\) est le seuil (prior Gaussien) - \(\epsilon_i \sim \mathcal{N}(0, 1/\tau)\) est le bruit (precision \(\tau\) avec prior Gamma)
Résultats : - Poids ≈ 0.81 (positif → classe 1 augmente avec la feature) - Seuil ≈ 3.38 - Point de décision : feature > 4.15 → classe 1
Interprétation géométrique : Le modèle probit définit une frontière de décision à x ≈ 4.15. Les données montrent effectivement une transition entre les classes autour de x=4-5.
Incertitude sur les paramètres : - σ(poids) ≈ 0.19 → relativement certain - σ(seuil) ≈ 0.87 → plus incertain
Avantage bayésien : Contrairement à la régression logistique classique qui donne des estimations ponctuelles, nous obtenons des distributions complètes sur les paramètres, permettant de propager l’incertitude aux prédictions.
// Visualisation du graphe de facteurs de la regression logistiqueFactorGraphHelper.GetLatestFactorGraphHtml().DisplayAs("text/html");
Model_09_03_26_01_17_37_52.svg
Lecture du graphe de facteurs - Regression Logistique
Le graphe ci-dessus montre la structure du modèle de classification probit :
Facteurs (rectangles noirs) : - Facteurs gaussiens : encodent les priors et la vraisemblance - Facteur de comparaison (> 0) : lie le score bruite a l’etiquette binaire
Structure de plate : La boucle ForEach créé une “plate” (repetition) sur les n echantillons. Chaque observation partage les mêmes paramètres poids et seuil, ce qui permet l’apprentissage a partir de plusieurs exemples.
Flux d’inference EP : Les messages passent entre facteurs et variables jusqu’a convergence. Les posterieurs sur poids et seuil integrent l’information de toutes les observations.
=== Predictions avec incertitude ===
Compiling model...done.
x = 2,5 : P(classe=1) = 0,218
Compiling model...done.
x = 4,5 : P(classe=1) = 0,561
Compiling model...done.
x = 6,5 : P(classe=1) = 0,822
Compiling model...done.
x = 9,0 : P(classe=1) = 0,951
Interpretation des predictions probabilistes
Feature (x)
P(classe=1)
Interpretation
2.5
0.218
très probablement classe 0
4.5
0.561
Zone d’incertitude (proche de 0.5)
6.5
0.822
Probablement classe 1
9.0
0.951
très probablement classe 1
Observations cles :
Gradient de confiance : La probabilite augmente de maniere monotone avec x, coherent avec le poids positif appris.
Zone de transition : Autour de x=4.5, le modèle est incertain (P proche de 0.5). Cela correspond au point de decision calcule (x=4.15).
Propagation de l’incertitude : Ces probabilites ne sont pas juste sigmoid(w*x - b) avec des paramètres fixes. Elles integrent l’incertitude sur w et b apprise pendant l’entrainement.
différence avec la classification déterministe : Un classifieur classique donnerait une prediction binaire (0 ou 1). Ici, nous obtenons une probabilite calibree qui reflette notre confiance reelle basee sur les données disponibles.
Exercice : Influence du prior sur la frontiere de decision
Le modèle de regression logistique bayesienne utilise des priors Gaussiens sur les poids. Le choix du prior (variance) influence la frontiere de decision apprise.
Objectif : Comparez les frontieres de decision obtenues avec un prior large (variance = 100) vs un prior étroit (variance = 0.1) sur le même jeu de données.
étapes : 1. Reprenez les données {1,2,3,4,5,6,7,8} avec labels {F,F,F,T,F,T,T,T} 2. Entrainez un modèle avec Variable.GaussianFromMeanAndVariance(0, 100) pour le poids 3. Entrainez un autre modèle avec Variable.GaussianFromMeanAndVariance(0, 0.1) pour le poids 4. Comparez les poids posterieurs et les points de decision (seuil/poids)
Indices : - Un prior etroit (faible variance) = forte regularisation = poids proches de zero - Un prior large (grande variance) = faible regularisation = poids libres de prendre de grandes valeurs - Calculez le point de decision avec seuil.GetMean() / poids.GetMean()
// Exercice : Influence du prior sur la frontiere de decision// TODO: Definir les donnees d'entrainement (reutiliser les donnees de la section 3)// Indice: double[] features = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 };// TODO: Modele 1 - Prior large (variance = 100)// Indice: Variable.GaussianFromMeanAndVariance(0, 100) pour poids et seuil// TODO: Modele 2 - Prior etroit (variance = 0.1)// Indice: Variable.GaussianFromMeanAndVariance(0, 0.1) pour poids et seuil// TODO: Comparer les resultats// Console.WriteLine($"Prior large : poids={w1}, seuil={b1}, decision={b1.GetMean()/w1.GetMean():F2}");// Console.WriteLine($"Prior etroit : poids={w2}, seuil={b2}, decision={b2.GetMean()/w2.GetMean():F2}");Console.WriteLine("Exercice a completer : Influence du prior");
Exercice a completer : Influence du prior
5. Classification Multi-Features
Extension aux dimensions superieures
Passer d’une seule feature a plusieurs features generalise le modèle :
Aspect
1 feature
p features
paramètre
\(w\) (scalaire)
\(\mathbf{w}\) (vecteur)
Score
\(w \cdot x - b\)
\(\mathbf{w}^T \mathbf{x} - b\)
Frontiere
Point sur \(\mathbb{R}\)
Hyperplan dans \(\mathbb{R}^p\)
Priors
2 Gaussiennes
p+1 Gaussiennes
Le graphe de facteurs s’etend naturellement avec un produit scalaire entre le vecteur de poids et le vecteur de features.
La frontiere de decision est définie par l’equation (coefficients = moyennes postérieures non arrondies ; intercept = seuil/poids2) : \[0.545 \cdot x_1 + 1.254 \cdot x_2 - 5.058 = 0\]
Soit : \(x_2 = -0.44 \cdot x_1 + 4.03\)
Aspect
Valeur
Signification
Pente frontiere
-0.44
Frontiere quasi-horizontale
Intercept
4.03
Coupe l’axe x2 vers 4
Ratio poids
2.3
Feature 2 a 2.3x plus d’influence que feature 1
Importance relative : Le poids de la feature 2 est plus de deux fois celui de la feature 1, indiquant que x2 est plus discriminant pour la classification. Cela pourrait orienter la collecte de données futures.
// Visualisation du graphe de facteurs multi-featuresFactorGraphHelper.GetLatestFactorGraphHtml().DisplayAs("text/html");
Model_09_03_26_01_17_43_39.svg
Graphe de facteurs multi-features - Structure vectorielle
Le graphe multi-features illustre l’extension du modèle a plusieurs dimensions :
différences avec le modèle 1D : - poids est maintenant un tableau avec un élément par feature - Le graphe montre une double structure de plates : - Une sur les features (pour les poids) - Une sur les echantillons (pour les observations)
opérations visibles : - Multiplication poids[f] * x[i,f] pour chaque feature - Addition des scores partiels - Soustraction du seuil - Ajout du bruit gaussien - Comparaison avec zero
Partage de paramètres : Les mêmes poids poids[0] et poids[1] sont utilises pour tous les echantillons, ce qui est la cle de la generalisation. Le graphe encode cette contrainte structurelle.
6. Bayes Point Machine (BPM)
Principe
Le BPM est une méthode de classification bayesienne qui : - Marginalise sur tous les hyperplans separateurs possibles - Donne des probabilites calibrees (mesure hors echantillon ci-dessous, section 6) - Utilise EP pour l’inference
Formulation
\[P(y=1|x) = \int P(y=1|x,w) P(w|D) dw\]
Fidélité à la source (Herbrich, Graepel & Campbell, 2001). L’intégrale ci-dessus est la prédiction bayésienne complète — la moyenne sur tout le postérieur \(P(w|D)\). Le Bayes Point Machine à proprement parler l’approxime par un point représentatif unique, le « Bayes point » (centre de masse de la version space), estimé efficacement par EP plutôt que par le coûteux calcul intégral. C’est cette approximation par un seul hyperplan représentatif qui définit le BPM et le distingue d’un classifieur bayésien pleinement marginalisé.
Note technique : modèle probit vs logit
Le code précédent utilise un modèle probit (comparaison avec bruit gaussien) plutot qu’un modèle logit (fonction sigmoid). Voici la différence :
Aspect
Probit
Logit
Lien
\(\Phi^{-1}(p) = w^T x\)
\(\log\frac{p}{1-p} = w^T x\)
Distribution latente
Gaussienne
Logistique
Inference bayesienne
Plus facile (EP)
Plus difficile
Equivalence pratique
Quasi-identique pour la plupart des cas
En Infer.NET, le modèle probit est prefere car il se prete naturellement a l’Expectation Propagation avec des distributions gaussiennes.
ou \(\Phi\) est la fonction de repartition de la loi normale standard.
Référence. Bishop (2006), PRML §4.3.5 (Probit Regression) et §4.5 (Bayesian Logistic Regression, approximation de Laplace). Le choix du lien probit (bruit gaussien latent) plutôt que logit (bruit logistique) est précisément ce qui rend l’inférence par EP tractable en Infer.NET — le lien probit étant introduit au §4.3.5.
ou \(\Phi\) est la CDF de la loi normale standard.
Validation sur les données 2D
Testons maintenant notre classe SimpleBPM sur les données multi-features définies precedemment pour valider l’implementation. Le BPM devrait donner des predictions coherentes avec l’inference directe, mais avec une API plus simple pour les predictions.
// Utilisation du BPMvar bpm =newSimpleBPM(2);bpm.Entrainer(featuresMulti, labelsMulti);Console.WriteLine("=== Predictions BPM ===");double[][] testPoints ={new[]{1.0,1.0},new[]{3.0,3.0},new[]{5.0,4.0},new[]{2.0,4.0}};foreach(var point in testPoints){double prob = bpm.Predire(point); Console.WriteLine($"({point[0]}, {point[1]}) : P(classe=1) = {prob:F3}");}
Calibration : Les probabilites proches de 0.5 indiquent correctement les zones d’incertitude pres de la frontiere.
Marginalisation : Le BPM considere tous les hyperplans plausibles ponderes par leur probabilite, pas un seul hyperplan optimal.
Regularisation implicite : Le prior Gaussien sur les poids (variance = 1) empeche le surapprentissage en penalisant les poids extremes.
Comparaison SVM vs BPM : Un SVM donnerait une frontiere “dure” et une classification binaire. Le BPM fournit des probabilites calibrees, particulierement utiles quand le cout d’erreur est asymetrique ou quand il faut prioriser les cas incertains pour une revue humaine.
// Visualisation du graphe de facteurs du BPMFactorGraphHelper.GetLatestFactorGraphHtml().DisplayAs("text/html");
Model_09_03_26_01_17_45_30.svg
Graphe de facteurs du Bayes Point Machine
Le graphe du BPM encapsule la classe SimpleBPM et montre :
Structure identique au modèle multi-features : - Le BPM utilise exactement la même structure de modèle que la section précédente - La différence est dans l’encapsulation (classe reutilisable)
Points cles visibles : 1. Prior unitaire : Variance = 1 sur les poids (regularisation implicite) 2. Score additif : Somme des contributions de chaque feature 3. modèle probit : Comparaison avec bruit gaussien
Marginalisation : Le nom “Bayes Point Machine” vient du fait que la prediction marginalise sur l’ensemble des hyperplans separateurs possibles, ponderes par leur probabilite a posteriori. Le graphe encode cette structure de marginalisation via les connexions entre variables et facteurs.
Calibration hors echantillon du BPM : du claim a la mesure (exemple execute)
La section 6 affiche des probabilites « calibrees » sur des points choisis a la main – une affirmation, pas une mesure. Le jumeau PyMC-9 etendait la meme question en exercice non resolu. Les deux twins mesurent desormais la propriete hors echantillon, avec le meme protocole :
jeu 2 features, 2 classes chevauchantes (N = 400, 200 par classe), decoupe 75/25 stratifiee – les etiquettes de test ne servent jamais pendant l’inference ;
le SimpleBPM ci-dessus, entraine sur le train seul (300 points) ;
probabilites sur le test (100 points) via Predire, qui propage l’incertitude posterieure des poids dans la CDF normale ;
Brier score et AUC (discrimination seule) ;
diagramme de fiabilite : 10 bins de meme largeur, avec effectifs ;
un contre-temoin mal calibre : q = p5/(p5 + (1-p)^5), transformation strictement croissante – l’AUC ne bouge pas, la calibration est detruite (surconfiance).
// --- Jeu 2D chevauchant + split train/test stratifie (protocole commun avec PyMC-9) ---var rndCal =newRandom(42);(int Npc,int TestPc,double sd)=(200,50,1.1);double[] mu0 ={2.0,2.0}, mu1 ={3.5,3.5};doubleGauss(){double u1 =1.0- rndCal.NextDouble(), u2 = rndCal.NextDouble();return Math.Sqrt(-2.0* Math.Log(u1))* Math.Sin(2.0* Math.PI* u2);}double[]Point(double[] mu)=>new[]{ mu[0]+ sd *Gauss(), mu[1]+ sd *Gauss()};var pts =new List<double[]>();var labs =new List<bool>();for(int i =0; i < Npc; i++){ pts.Add(Point(mu0)); labs.Add(false);}for(int i =0; i < Npc; i++){ pts.Add(Point(mu1)); labs.Add(true);}var order = Enumerable.Range(0, pts.Count).OrderBy(_ => rndCal.NextDouble()).ToArray();// shuffle seedevar X2 = pts.Select(p => p).ToArray();var y2 = labs.ToArray();int nTrain = pts.Count-2* TestPc;// 300 / 100double[,] Xtr =newdouble[nTrain,2], Xte =newdouble[2* TestPc,2];bool[] ytr =newbool[nTrain], yte =newbool[2* TestPc];for(int i =0; i < pts.Count; i++){if(i < nTrain){ Xtr[i,0]= X2[order[i]][0]; Xtr[i,1]= X2[order[i]][1]; ytr[i]= y2[order[i]];}else{int j = i - nTrain; Xte[j,0]= X2[order[i]][0]; Xte[j,1]= X2[order[i]][1]; yte[j]= y2[order[i]];}}Console.WriteLine($"Train : {nTrain} ({ytr.Count(v => v)} positifs) | Test : {2 * TestPc} "+ $"({yte.Count(v => v)} positifs) -- etiquettes de test inertes pendant l'inference");var bpmCal =newSimpleBPM(2);bpmCal.Entrainer(Xtr, ytr);// EP sur le train SEUL -- le SimpleBPM de la section 6, tel quel
Train : 300 (154 positifs) | Test : 100 (46 positifs) -- etiquettes de test inertes pendant l'inference
Compiling model...done.
Iterating:
.........|.........|.........|.........|.........| 50
// --- Probabilites sur le test + metriques + contre-temoin ---double[]ProbsOf(double[,] X)=> Enumerable.Range(0, X.GetLength(0)).Select(i => bpmCal.Predire(new[]{ X[i,0], X[i,1]})).ToArray();double[] pTe =ProbsOf(Xte);double[] qTe = pTe.Select(p =>{double a = Math.Pow(p,5), b = Math.Pow(1- p,5);return a /(a + b);}).ToArray();// accentuation monotonedoubleBrier(double[] p,bool[] y)=> p.Select((pi, i)=>(pi -(y[i]?1.0:0.0))*(pi -(y[i]?1.0:0.0))).Average();doubleAuc(double[] p,bool[] y)// Mann-Whitney par rangs (main, sans dependance){int n1 = y.Count(v => v), n0 = y.Length- n1;double inv =0;for(int i =0; i < p.Length; i++)for(int j =0; j < p.Length; j++)if(y[i]&&!y[j]) inv += p[i]> p[j]?1.0:(p[i]== p[j]?0.5:0.0);return inv /(n0 * n1);}doubleAcc(double[] p,bool[] y)=> p.Select((pi, i)=>(pi >0.5)== y[i]?1.0:0.0).Average();Console.WriteLine("=== Test (100 points jamais vus) : calibration vs discrimination ===");Console.WriteLine($"{"modele",-30}{"Brier",8}{"AUC",8}{"acc@0.5",9}");Console.WriteLine($"{"BPM EP(calibre)",-30}{Brier(pTe, yte),8:F3}{Auc(pTe, yte),8:F3}{Acc(pTe, yte),9:F3}");Console.WriteLine($"{"contre-temoin p^5(accentue)",-30}{Brier(qTe, yte),8:F3}{Auc(qTe, yte),8:F3}{Acc(qTe, yte),9:F3}");Console.WriteLine("\nMeme AUC (transformation strictement croissante), Brier degrade :");Console.WriteLine("la discrimination est preservee, la calibration ne l'est pas.");
=== Test (100 points jamais vus) : calibration vs discrimination ===
modele Brier AUC acc@0.5
BPM EP (calibre) 0,096 0,954 0,870
contre-temoin p^5 (accentue) 0,110 0,954 0,870
Meme AUC (transformation strictement croissante), Brier degrade :
la discrimination est preservee, la calibration ne l'est pas.
// --- Diagramme de fiabilite (10 bins, effectifs) + graphique ---(int Bin,int N,double Pp,double Fo)[]Fiabilite(double[] p,bool[] y){return Enumerable.Range(0,10).Select(k =>{double lo = k /10.0, hi =(k +1)/10.0;var m = Enumerable.Range(0, p.Length).Where(i =>(k ==9? p[i]>= lo && p[i]<=1.0: p[i]>= lo && p[i]< hi)).ToArray();return(k, m.Length, m.Any()? m.Select(i => p[i]).Average():double.NaN, m.Any()? m.Count(i => y[i])/(double)m.Length:double.NaN);}).ToArray();}Console.WriteLine("Bin | effectif | p_pred moyen | freq observee (BPM EP)");foreach(var r inFiabilite(pTe, yte)) Console.WriteLine($"{r.Bin,3} | {r.N,8} | {r.Pp,12:F3} | {r.Fo,12:F3}");
Le BPM EP est proche de la diagonale sur les bins peuples : la calibration affirmee plus haut est desormais mesuree hors echantillon. Avec 100 points de test, chaque bin attend ~10 evenements – les extremites peu peuplees ne portent pas de conclusion forte.
Le contre-temoin garde l’AUC et perd le Brier : reordonner les scores ne change rien a la discrimination, mais pousser les probabilites vers 0 et 1 cree un modele surconfiant dont les probabilites mentent des qu’on les utilise comme des risques (seuil metier, cout attendu).
EP vs posterior-moyenne : Predire propage la variance posterieure des poids dans la CDF normale (approximation moment-matched) ; le jumeau PyMC moyenne la CDF sur les tirages NUTS. Les AUC des deux moteurs doivent etre proches ; un ecart de Brier mesure cette difference d’integration, pas une difference de protocole.
Ce qu’il faut retenir : une bonne discrimination (AUC) ne suffit pas ; la calibration est une propriete separee, et elle se mesure sur des donnees retenues, jamais sur l’ajustement.
7. Test Clinique Bayesien (A/B Testing)
Contexte
Comparer l’efficacite d’un nouveau traitement vs placebo.
Note importante : Le warning “quality band Experimental” indique que l’opérateur DifferenceBetaOp est encore en développement dans Infer.NET. Les résultats restent fiables mais cette fonctionnalité pourrait évoluer.
Application clinique : Avec 98.6% de probabilité que le traitement soit meilleur, un comité d’éthique pourrait recommander de proposer le traitement au groupe placebo.
// Visualisation du graphe de facteurs du test cliniqueFactorGraphHelper.GetLatestFactorGraphHtml().DisplayAs("text/html");
Model_09_03_26_01_17_49_19.svg
Graphe de facteurs du test A/B clinique
Ce graphe illustre le modèle comparatif Beta-Binomial :
Structure parallele : - Deux branches independantes pour tauxPlacebo et tauxTraitement - Chaque branche : Prior Beta -> Facteur Binomial -> Observation
Variables : - tauxPlacebo, tauxTraitement : paramètres latents (probabilites de guerison) - Les observations sont des comptages binomiaux (rectangles)
Facteur de comparaison : Le facteur tauxTraitement > tauxPlacebo (visible comme opérateur de différence) est le coeur du test A/B. Il permet de repondre directement : “Quelle est la probabilite que le traitement soit meilleur ?”
Independence a priori : Les deux taux ont des priors independants Beta(1,1). L’information sur la comparaison vient uniquement des données observees, pas d’hypotheses a priori sur leur relation.
modèle conjugue Beta-Binomial
Le test clinique utilise le modèle classique Beta-Binomial :
Prior : \(\theta \sim \text{Beta}(1, 1)\) (uniforme sur [0,1])
Posterior : \(\theta | k \sim \text{Beta}(1 + k, 1 + n - k)\)
Cette conjugaison permet une inference exacte. La question “le traitement est-il meilleur ?” se traduit par : \[P(\theta_{traitement} > \theta_{placebo} | \text{données})\]
Infer.NET calcule cette probabilite via l’opérateur DifferenceBetaOp.
8. Effet de la Taille d’Echantillon
Puissance statistique bayesienne
Une question naturelle est : “Combien de patients faut-il recruter pour detecter une différence ?” L’analyse suivante montre comment la certitude evolue avec la taille de l’echantillon, a effet constant (30% vs 45%).
// Impact de la taille d'echantillonConsole.WriteLine("=== Impact de la taille d'echantillon ===");Console.WriteLine("\nMeme ratio (30% vs 45%), differentes tailles :\n");int[] tailles ={10,50,100,500,1000};foreach(int n in tailles){int gP =(int)(n *0.30);int gT =(int)(n *0.45); Variable<double> tP = Variable.Beta(1,1); Variable<double> tT = Variable.Beta(1,1); Variable.ConstrainEqual(Variable.Binomial(n, tP), gP); Variable.ConstrainEqual(Variable.Binomial(n, tT), gT); Variable<bool> meilleur =(tT > tP); InferenceEngine m =newInferenceEngine(); m.Compiler.CompilerChoice= CompilerChoice.Roslyn;double prob = m.Infer<Bernoulli>(meilleur).GetProbTrue(); Console.WriteLine($"n = {n,4} : P(traitement meilleur) = {prob:F4}");}Console.WriteLine("\n=> Plus de donnees = plus de certitude");
=== Impact de la taille d'echantillon ===
Meme ratio (30% vs 45%), differentes tailles :
Compiling model...compilation had 1 warning(s).
[1] DifferenceBetaOp.DifferenceAverageConditional(vdouble128_uses_F[1], vdouble127_uses_F[1]) has quality band Experimental which is less than the recommended quality band (Preview)
done.
n = 10 : P(traitement meilleur) = 0,6702
Compiling model...compilation had 1 warning(s).
[1] DifferenceBetaOp.DifferenceAverageConditional(vdouble131_uses_F[1], vdouble130_uses_F[1]) has quality band Experimental which is less than the recommended quality band (Preview)
done.
n = 50 : P(traitement meilleur) = 0,9258
Compiling model...compilation had 1 warning(s).
[1] DifferenceBetaOp.DifferenceAverageConditional(vdouble134_uses_F[1], vdouble133_uses_F[1]) has quality band Experimental which is less than the recommended quality band (Preview)
done.
n = 100 : P(traitement meilleur) = 0,9862
Compiling model...compilation had 1 warning(s).
[1] DifferenceBetaOp.DifferenceAverageConditional(vdouble137_uses_F[1], vdouble136_uses_F[1]) has quality band Experimental which is less than the recommended quality band (Preview)
done.
n = 500 : P(traitement meilleur) = 1,0000
Compiling model...compilation had 1 warning(s).
[1] DifferenceBetaOp.DifferenceAverageConditional(vdouble140_uses_F[1], vdouble139_uses_F[1]) has quality band Experimental which is less than the recommended quality band (Preview)
done.
n = 1000 : P(traitement meilleur) = 1,0000
=> Plus de donnees = plus de certitude
Convergence de la certitude avec la taille d’echantillon
Taille (n)
P(traitement meilleur)
Interpretation
10
0.670
Faible evidence (proche du hasard)
50
0.926
Evidence moderee
100
0.986
Evidence forte
500
~1.000
Evidence très forte
1000
~1.000
Evidence quasi-certaine
Loi de convergence :
La certitude croit approximativement comme \(\sqrt{n}\) : - Doubler la confiance necessite quadrupler l’echantillon - Passer de 67% a 99% necessite ~10x plus de données (n=10 -> n=100 dans le tableau ci-dessus)
Implications pratiques :
Contexte
Taille recommandee
Justification
Test pilote
n = 50
Detection effet important (>90%)
Essai clinique
n = 100-500
Standard reglementaire
Decision critique
n > 500
Minimiser risque d’erreur
Avantage bayesien : Contrairement aux tests frequentistes qui donnent une reponse binaire (significatif/non-significatif), l’approche bayesienne permet un arret adaptatif : on peut arreter l’essai des que P(traitement meilleur) depasse un seuil predetermine (ex: 95%), ou au contraire continuer si l’evidence est insuffisante.
Exercice : Test A/B avec prior informatif
Dans le test clinique précédent, nous avons utilise Beta(1,1) comme prior uniforme. En pratique, on dispose souvent d’informations a priori issues d’études précédentes.
Objectif : Comparez l’analyse du test clinique avec un prior uniforme vs un prior informatif qui encode la connaissance d’études précédentes (taux de guerison historique = 25%).
étapes : 1. Reprenez les données : placebo 30/100, traitement 45/100 2. Analyse 1 : prior uniforme Beta(1,1) (déjà fait) 3. Analyse 2 : prior informatif Beta(5,15) pour le placebo (moyenne = 0.25, equivaut a 20 observations) 4. Comparez P(traitement meilleur) dans les deux cas
Indices : - Beta(5,15) encode 5 succes et 15 echecs “virtuels”, soit une moyenne de 5/(5+15) = 0.25 - Le prior informatif reduit la variance du posterior et accelere la convergence - Comment le prior informatif sur le placebo affecte-t-il la comparaison ?
// Exercice : Test A/B avec prior informatif// TODO: Reutiliser les donnees (placebo 30/100, traitement 45/100)// Indice: nPlacebo = 100, guerisPlacebo = 30, etc.// TODO: Analyse 1 - Prior uniforme Beta(1,1) (identique a la section 7)// Indice: Variable<double> tauxPlacebo = Variable.Beta(1, 1);// TODO: Analyse 2 - Prior informatif Beta(5,15) pour le placebo// Indice: Variable<double> tauxPlaceboInfo = Variable.Beta(5, 15);// Ce prior encode 20 "observations virtuelles" avec 25% de taux de guerison// TODO: Comparer P(traitement meilleur) dans les deux cas// Console.WriteLine($"Prior uniforme : P(traitement meilleur) = {p1:F3}");// Console.WriteLine($"Prior informatif : P(traitement meilleur) = {p2:F3}");Console.WriteLine("Exercice a completer : Test A/B avec prior informatif");
Exercice a completer : Test A/B avec prior informatif
9. Exemple guide : Classification Spam
Enonce
Construisez un classificateur bayesien pour detecter les spams bases sur 3 features : - Nombre de mots en majuscules - Presence du mot “gratuit” - Longueur du message (en centaines de caractères)
données
Objectif de l’exercice
Construire un classificateur de spam en utilisant le Bayes Point Machine implemente precedemment. Les features choisies representent des caractéristiques typiques des spams :
Feature
Description
Valeur typique spam
Majuscules
Nombre de mots en majuscules
Eleve (>15)
Gratuit
Presence du mot “gratuit” (0/1)
1
Longueur
Taille du message (en centaines de caractères)
Faible (<2)
Ces features sont simples mais illustrent les principes d’un filtre anti-spam reel.
// Exemple guide : Classification spam// Donnees d'entrainement// [nbMajuscules, presenceGratuit (0/1), longueur]double[,] spamFeatures ={{5,0,2.5},// Non spam{3,0,3.0},// Non spam{15,1,1.0},// Spam{20,1,0.5},// Spam{2,0,4.0},// Non spam{25,1,1.5},// Spam{8,0,2.0},// Non spam{18,1,0.8}// Spam};bool[] spamLabels ={false,false,true,true,false,true,false,true};// Entrainementvar spamClassifier =newSimpleBPM(3);spamClassifier.Entrainer(spamFeatures, spamLabels);Console.WriteLine("=== Classificateur Spam ===");// Test sur nouveaux emailsvar testEmails =new(double[],string)[]{(new[]{4.0,0.0,3.0},"Email normal"),(new[]{22.0,1.0,1.0},"OFFRE GRATUITE!!!"),(new[]{10.0,0.0,2.5},"Email avec quelques majuscules"),(new[]{30.0,1.0,0.5},"CLIQUEZ ICI GRATUIT")};Console.WriteLine("\nPredictions :");foreach(var(features, desc)in testEmails){double probSpam = spamClassifier.Predire(features);string verdict = probSpam >0.5?"SPAM":"OK"; Console.WriteLine($" {desc,-30} : P(spam)={probSpam:F3} -> {verdict}");}
Compiling model...done.
Iterating:
.........|.........|.........|.........|.........| 50
=== Classificateur Spam ===
Predictions :
Email normal : P(spam)=0,053 -> OK
OFFRE GRATUITE!!! : P(spam)=0,952 -> SPAM
Email avec quelques majuscules : P(spam)=0,334 -> OK
CLIQUEZ ICI GRATUIT : P(spam)=0,984 -> SPAM
Analyse du classificateur spam
résultats de prediction :
Email
Majuscules
Gratuit
Longueur
P(spam)
Verdict
Email normal
4
Non
3.0
0.053
OK
OFFRE GRATUITE!!!
22
Oui
1.0
0.952
SPAM
Quelques majuscules
10
Non
2.5
0.334
OK
CLIQUEZ ICI GRATUIT
30
Oui
0.5
0.984
SPAM
Facteurs discriminants appris :
Le modèle a appris que le spam est caracterise par : 1. Nombre eleve de majuscules (poids positif) 2. Presence du mot “gratuit” (poids positif fort) 3. Messages courts (poids negatif sur la longueur)
Cas interessants :
“Email avec quelques majuscules” (P=0.334) : Malgre 10 majuscules, l’absence de “gratuit” et la longueur normale le sauvent du classement spam.
Les deux emails avec “gratuit” ont P(spam) > 95%, montrant l’importance de cette feature.
Application industrielle : Ce type de classificateur bayesien est utilise dans les filtres anti-spam reels. L’avantage de l’approche probabiliste est de pouvoir définir un seuil de decision adapte au contexte : seuil bas (0.3) pour un filtre agressif, seuil haut (0.8) pour eviter les faux positifs dans un contexte professionnel.
// Visualisation du graphe de facteurs du classificateur spamFactorGraphHelper.GetLatestFactorGraphHtml().DisplayAs("text/html");
Model_09_03_26_01_17_51_55.svg
Graphe du classificateur spam - BPM a 3 features
Le graphe de l’exercice spam reprend la structure du BPM multi-features avec 3 dimensions :
Features encodees : 1. poids[0] : Nombre de mots en majuscules 2. poids[1] : Presence du mot “gratuit” (0/1) 3. poids[2] : Longueur du message
Application pratique : Ce type de graphe est le coeur des filtres bayesiens anti-spam (comme SpamBayes ou les filtres Gmail). L’avantage est de pouvoir ajouter de nouvelles features facilement en etendant le vecteur de poids, sans changer la structure du modèle.
Prediction : La méthode Predire() utilise les posterieurs pour calculer P(spam|x) en integrant l’incertitude sur les poids appris.
Classifiez des critiques de films comme positives (true) ou negatives (false) selon deux features : - Feature 0 : nombre de mots negatifs (“mauvais”, “nul”, “ennuyeux”…) - Feature 1 : presence du mot “chef-d’oeuvre” (0 ou 1)
Entrainer le BPM et classer 3 nouvelles critiques : [1,0], [0,1], [3,0].
Indice : Reutilisez exactement la structure BPM de la section 6 (Bayes Point Machine) avec 2 features.
// Exemple guide : Classification de critiques de films - BPM 2 featuresusing Microsoft.ML.Probabilistic.Math;// TODO: Definir les donnees d'entrainement// Feature 0 = nb mots negatifs, Feature 1 = chef-d-oeuvre (0 ou 1)// TODO: Entrainer le BPM (reutiliser la structure de l'exemple guide)// TODO: Inferer les poids du classifieur// TODO: Classer les nouvelles critiques (inference predictive)// Pour chaque critique : calculer P(positive | features)Console.WriteLine("Exercice a completer");
Exercice a completer
Conclusion
Ce notebook a couvert la classification bayesienne : regression logistique probit, Bayes Point Machine et test A/B clinique.
modèle
mécanisme
Apport bayesien
Regression probit
Score latent gaussien + seuil
Distributions sur les poids, pas d’estimations ponctuelles
Taux de guerison (prior uniforme, posterior conjugue)
Bernoulli
Predictions de classe
Binomial
Comptage de succes (observations cliniques)
Avantage cle : Contrairement a la classification déterministe, l’approche bayesienne propage l’incertitude des paramètres aux predictions. Les probabilites obtenues sont calibrees, permettant des decisions seuillees adaptees au cout d’erreur (ex : filtre anti-spam agressif vs conservateur).