Simplifie grandement l’estimation de la vraisemblance.
La règle de décision devient : \[ \hat{y} = \underset{c_k}{\mathrm{argmax}} P(Y=c_k) \prod_{j=1}^{p} P(x_j | Y=c_k) \]
Discussion :
L’hypothèse est souvent fausse en pratique.
Malgré cela, le classifieur peut bien fonctionner.
Astuce de calcul
Pour éviter les problèmes de sous-flux numérique (underflow) dus à la multiplication de nombreuses petites probabilités, on travaille souvent avec les log-probabilités : \[ \hat{y} = \underset{c_k}{\mathrm{argmax}} \left( \log P(Y=c_k) + \sum_{j=1}^{p} \log P(x_j | Y=c_k) \right) \]
5 Estimation des Paramètres
Estimation de la probabilité a priori \(P(Y=c_k)\) :
Fréquence relative de la classe \(c_k\) dans les données d’apprentissage \(\mathcal{D}_n\).
\(P(Y=c_k) = \frac{\text{Nombre d'exemples de la classe } c_k}{n}\)
Estimation de la vraisemblance \(P(x_j | Y=c_k)\) :
Dépend de la nature de la variable \(x_j\).
5.1 Variables Explicatives Catégorielles
Pour une variable \(x_j\) prenant des valeurs dans un ensemble discret \(\{v_1, \dots, v_M\}\).
\(P(x_j=v_m | Y=c_k) = \frac{\text{Nombre d'exemples où } x_j=v_m \text{ et } Y=c_k}{\text{Nombre d'exemples où } Y=c_k}\).
Problème des “zéros fréquences” : Si une modalité \(v_m\) n’apparaît jamais avec la classe \(c_k\) dans \(\mathcal{D}_n\), alors \(P(x_j=v_m | Y=c_k)=0\).
Cela annule toute la probabilité a posteriori si cette modalité apparaît dans une nouvelle observation.
Solution : Lissage de Laplace (ou estimateur de Laplace).
\(P(x_j=v_m | Y=c_k) = \frac{(\text{Nombre d'exemples où } x_j=v_m \text{ et } Y=c_k) + \alpha}{(\text{Nombre d'exemples où } Y=c_k) + \alpha M}\).
\(\alpha\) est un paramètre de lissage (souvent \(\alpha=1\)).
5.2 Variables Explicatives Continues
Hypothèse courante : \(P(x_j | Y=c_k)\) suit une distribution Gaussienne (Normale).
Estimation des paramètres de la Gaussienne pour chaque classe \(c_k\) et chaque variable \(x_j\):
\(\mu_{jk}\): Moyenne empirique de la variable \(x_j\) pour les exemples de la classe \(c_k\).
\(\sigma^2_{jk}\): Variance empirique de la variable \(x_j\) pour les exemples de la classe \(c_k\).
Calcul de \(P(x_j | Y=c_k)\) à l’aide de la fonction de densité de probabilité (PDF) de la loi Normale : \[ P(x_j | Y=c_k) = \frac{1}{\sqrt{2\pi\sigma^2_{jk}}} \exp\left(-\frac{(x_j - \mu_{jk})^2}{2\sigma^2_{jk}}\right) \]
Autres approches pour les variables continues :
Discrétisation.
Estimateurs de densité par noyau (Kernel Density Estimators - KDE).
6 Algorithme du Classifieur Naïf de Bayes
Phase d’Apprentissage (Training) sur \(\mathcal{D}_n\):
Pour chaque classe \(c_k \in \{c_1, \dots, c_K\}\):
Calculer \(P(Y=c_k)\).
Pour chaque variable explicative \(x_j\):
Si \(x_j\) est catégorielle : Estimer \(P(x_j=v_m | Y=c_k)\) pour chaque modalité \(v_m\) (avec lissage).
Si \(x_j\) est continue : Estimer \(\mu_{jk}\) et \(\sigma^2_{jk}\) pour la distribution Gaussienne.
Phase de Prédiction (Inférence) pour une nouvelle observation \(x_{new}\):
Pour chaque classe \(c_k \in \{c_1, \dots, c_K\}\):
Prédire la classe \(\hat{y}_{new} = \underset{c_k}{\mathrm{argmax}} \text{ Score}(c_k)\).
7 Exemple Pratique: Gaussian Naive Bayes (Python)
Utilisons le jeu de données Iris (classification multiclasse).
Code
from sklearn.naive_bayes import GaussianNBfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import accuracy_scorefrom sklearn.datasets import load_iris# Charger le jeu de données Irisiris = load_iris()X, y = iris.data, iris.target# Diviser les données en ensembles d'entraînement et de testX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)# Initialiser et entraîner le modèle Gaussian Naive Bayesgnb = GaussianNB()gnb.fit(X_train, y_train)# Faire des prédictions sur l'ensemble de testy_pred = gnb.predict(X_test)# Évaluer la performance du modèleaccuracy = accuracy_score(y_test, y_pred)print(f"Accuracy du Gaussian Naive Bayes sur le jeu de test Iris: {accuracy:.4f}")# Matrice de confusionfrom sklearn.metrics import confusion_matrixconf_matrix = confusion_matrix(y_test, y_pred)print("Matrice de confusion:")print(conf_matrix)# Afficher les probabilités prédites pour les 5 premières observations de testprint("\nProbabilités prédites pour les 5 premières observations de test:")print(gnb.predict_proba(X_test[:5]))
Accuracy du Gaussian Naive Bayes sur le jeu de test Iris: 0.9778
Matrice de confusion:
[[19 0 0]
[ 0 12 1]
[ 0 0 13]]
Probabilités prédites pour les 5 premières observations de test:
[[4.15880005e-088 9.95527834e-001 4.47216606e-003]
[1.00000000e+000 1.31031235e-013 2.21772205e-020]
[9.83170191e-285 2.70138564e-012 1.00000000e+000]
[9.54745274e-092 9.74861431e-001 2.51385686e-002]
[1.08679560e-103 8.31910700e-001 1.68089300e-001]]
8 Cas Particulier : Classification Binaire
\(K=2\). Les classes sont souvent notées \({0, 1}\) ou \({-1, 1}\).
La règle de décision peut être formulée en comparant \(P(Y=1 | X=x)\) à \(P(Y=0 | X=x)\).
Si \(P(Y=1 | X=x) \> P(Y=0 | X=x)\), alors prédire classe 1.
Ou, en utilisant le ratio des probabilités a posteriori : \(\\frac{P(Y=1 | X=x)}{P(Y=0 | X=x)} \> 1\).
En termes de log-odds : \(\log \dfrac{P(Y=1 | X=x)}{P(Y=0 | X=x)} > 0\).
Fonction de Perte \(L\) et Risque \(R\):
La règle de Bayes minimise le risque \(R(f) = E[L(Y, f(X))]\) pour la perte 0-1 (\(L(y, \hat{y}) = 1 \text{ si } y \neq \hat{y} \text{ sinon } 0\)).
9 Exemple Pratique: Binomial Naive Bayes (Python)
Illustrons avec un exemple simple de classification de texte (spam ou non-spam), où les caractéristiques sont la présence ou l’absence de mots. Nous utiliserons BernoulliNB de scikit-learn.
Code
import numpy as npfrom sklearn.feature_extraction.text import CountVectorizerfrom sklearn.naive_bayes import BernoulliNBfrom sklearn.model_selection import train_test_split # Bien que nous utilisions un petit jeu de données icifrom sklearn.metrics import accuracy_score, confusion_matrix# Données d'exemple : messages et leurs étiquettes (1 pour spam, 0 pour non-spam)corpus = [ ("offre spécial argent gratuit gagner prix", 1), # Spam ("cliquer lien gagner argent facile rapide", 1), # Spam ("prix incroyable opportunité unique", 1), # Spam ("réunion projet important demain matin", 0), # Non-spam ("discussion budget équipe après-midi", 0), # Non-spam ("confirmation rendez-vous docteur lundi", 0), # Non-spam ("gagner loterie gratuit maintenant", 1), # Spam ("exclusif promotion argent facile", 1), # Spam ("rapport mensuel vente disponible", 0), # Non-spam ("invitation séminaire marketing digital", 0), # Non-spam ("urgent action requise compte sécurité", 1), # Spam (pourrait être phishing) ("ne pas manquer offre limitée", 1), # Spam ("mise à jour logiciel important installer", 0), # Non-spam ("compte rendu réunion disponible partage", 0), # Non-spam ("félicitations sélectionné prix spécial", 1), # Spam ("demande information produit service", 0), # Non-spam ("gratuit essai limité temps", 1), # Spam ("planification vacances équipe semaine prochaine", 0), # Non-spam ("opportunité investissement incroyable rendement élevé", 1), # Spam ("question facture service client", 0) # Non-spam]texts = [text for text, label in corpus]labels = np.array([label for text, label in corpus])# Extraction de caractéristiques : Convertir le texte en vecteurs de présence/absence de mots# binary=True assure que nous comptons la présence (1) ou l'absence (0) d'un mot, pas sa fréquence.vectorizer = CountVectorizer(binary=True)X = vectorizer.fit_transform(texts)# Pour cet exemple, nous allons entraîner et tester sur le même petit ensemble pour illustrer.# Dans un cas réel, utilisez train_test_split sur un ensemble de données plus grand.X_train, X_test, y_train, y_test = X, X, labels, labels # Simplification pour l'illustration# Initialiser et entraîner le modèle Bernoulli Naive Bayes# alpha=1.0 est le lissage de Laplace (par défaut)bnb = BernoulliNB()bnb.fit(X_train, y_train)# Faire des prédictionsy_pred = bnb.predict(X_test)# Évaluer la performance du modèleaccuracy = accuracy_score(y_test, y_pred)print(f"Accuracy du Bernoulli Naive Bayes sur le jeu de test simplifié: {accuracy:.4f}")conf_matrix = confusion_matrix(y_test, y_pred)print("\nMatrice de confusion:")print(conf_matrix)# Afficher les probabilités prédites pour les premières observationsprint("\nProbabilités prédites (non-spam, spam) pour les premières observations de test:")print(np.round(bnb.predict_proba(X_test[:4]), 3))# Afficher les classes prédites pour les premières observationsprint("\nClasses prédites pour les premières observations de test:")print(y_pred[:4])print("Vraies classes pour les premières observations de test:")print(y_test[:4])
Accuracy du Bernoulli Naive Bayes sur le jeu de test simplifié: 1.0000
Matrice de confusion:
[[10 0]
[ 0 10]]
Probabilités prédites (non-spam, spam) pour les premières observations de test:
[[0. 1. ]
[0.001 0.999]
[0.008 0.992]
[0.994 0.006]]
Classes prédites pour les premières observations de test:
[1 1 1 0]
Vraies classes pour les premières observations de test:
[1 1 1 0]
Gère bien la grande dimensionnalité (beaucoup de variables explicatives).
Performances souvent bonnes même si l’hypothèse de naïveté est violée.
Gère nativement les données manquantes (en ignorant la variable pour cette observation lors du produit/somme).
Fournit des probabilités de classe, ce qui peut être utile.
L’hypothèse d’indépendance conditionnelle est rarement vraie en pratique.
Peut conduire à des estimations de probabilités a posteriori peu fiables (souvent trop extrêmes, proches de 0 ou 1).
Sensible aux “zéros fréquences” pour les variables catégorielles si le lissage n’est pas appliqué.
Pour les variables continues, l’hypothèse de distribution Gaussienne peut être trop restrictive.
11 Variantes du Classifieur Naïf de Bayes
Gaussian Naive Bayes : Suppose des features continues suivant une distribution Gaussienne (comme vu).
Multinomial Naive Bayes : Souvent utilisé pour la classification de texte, où les features sont des comptes de mots (ou TF-IDF). Suppose une distribution multinomiale pour les features.
Bernoulli Naive Bayes : Utilisé quand les features sont binaires (présence/absence). Suppose une distribution de Bernoulli pour les features.
Categorical Naive Bayes : Pour des features catégorielles (comme vu).
12 Diagramme (Mermaid)
Illustrons le calcul pour une nouvelle observation :
Le Classifieur Naïf de Bayes est un algorithme probabiliste basé sur le théorème de Bayes.
Son efficacité repose sur l’hypothèse “naïve” d’indépendance conditionnelle des variables.
Différentes variantes existent selon la nature des données explicatives.
Simple, rapide et souvent étonnamment performant.
Excellent point de départ pour des problèmes de classification.
14 Pour aller plus loin (Références)
Chapitre 4 du livre “Introduction au Machine Learning” (Azencott, 2020) pour une discussion sur l’inférence bayésienne et la classification naïve bayésienne. [Source 52, 665]