Naive Bayes Gaussien : Guide Complet — Principes, Exemples et Implémentation Python

Naive Bayes Gaussien : Guide Complet — Principes, Exemples et Implémentation Python

Naive Bayes Gaussien : Guide complet — Principes, Exemples et Implémentation Python

Résumé — Le naive bayes gaussien (Gaussian Naive Bayes) est un algorithme de classification supervisée basé sur le théorème de Bayes et l’hypothèse d’indépendance conditionnelle entre les caractéristiques. Sa spécificité ? Il suppose que chaque caractéristique numérique suit une distribution normale (gaussienne) au sein de chaque classe. Extrêmement rapide à l’entraînement, léger en mémoire et souvent surprenant de pertinence, le naive bayes gaussien reste un classique incontournable du machine learning — particulièrement apprécié pour les prototypes, les jeux de données tabulaires et les problèmes où l’interprétabilité compte autant que la performance.


Principe mathématique du naive bayes gaussien

Le théorème de Bayes : fondement probabiliste

Tout commence avec le théorème de Bayes, formulé au XVIIIe siècle par le mathématicien Thomas Bayes. Ce théorème permet d’inverser un raisonnement probabiliste :

P(C_k | x) = P(x | C_k) * P(C_k) / P(x)

Où :
P(C_k | x) est la probabilité a posteriori : la probabilité que l’observation x appartienne à la classe C_k, connaissant ses caractéristiques.
P(x | C_k) est la vraisemblance : la probabilité d’observer x sachant que la classe est C_k.
P(C_k) est la probabilité a priori : la fréquence naturelle de la classe C_k dans les données.
P(x) est la probabilité marginale de x, identique pour toutes les classes, donc souvent ignorée lors de la comparaison.

En classification, on attribue l’observation x à la classe qui maximise la probabilité a posteriori :

ŷ = argmax P(C_k | x) = argmax [P(x | C_k) * P(C_k)]
          k               k

L’hypothèse d’indépendance conditionnelle

Le qualificatif “naive” (naïf) vient d’une hypothèse simplificatrice : on suppose que toutes les caractéristiques sont conditionnellement indépendantes sachant la classe. Autrement dit, connaissant la classe, la valeur d’une caractéristique n’apporte aucune information supplémentaire sur une autre caractéristique.

Cette hypothèse est rarement vérifiée dans la réalité — les variables sont presque toujours corrélées entre elles. Pourtant, le classifieur fonctionne étonnamment bien en pratique. Pourquoi ? Parce que l’algorithme a besoin d’estimer correctement quelle classe a la plus grande probabilité, pas nécessairement la probabilité exacte elle-même. Même si les probabilités sont biaisées, le classement des classes peut rester correct.

Grâce à cette hypothèse, la vraisemblance se factorise :

P(x | C_k) = P(x₁ | C_k) * P(x₂ | C_k) * ... * P(x_n | C_k)

Le modèle gaussien : continuíté et caractéristiques numériques

C’est ici que le naive bayes gaussien se distingue des autres variantes (MultinomialNB pour les comptages, BernoulliNB pour les variables binaires). Il suppose que chaque caractéristique x_i suit une distribution normale au sein de chaque classe :

P(x_i | C_k) = (1 / √(2πσ²_k,i)) * exp(-(x_i - μ_k,i)² / (2σ²_k,i))

Où :
μ_k,i est la moyenne de la caractéristique i dans la classe k
σ²_k,i est la variance de la caractéristique i dans la classe k

Ces deux paramètres sont simplement estimés par maximum de vraisemblance à partir des données d’entraînement : on calcule la moyenne et la variance échantillonnale pour chaque couple (classe, caractéristique).

Pour classer une nouvelle observation, l’algorithme évalue la densité gaussienne de chaque caractéristique sous chaque classe, multiplie ces densités entre elles, pondère par la probabilité a priori, et sélectionne la classe la plus probable.


Intuition : pourquoi ça marche ?

Imaginez que vous cherchiez à déterminer si un fruit est une pomme ou une orange en observant deux caractéristiques : sa masse et son diamètre.

En examinant un panier de fruits étiquetés, vous constatez que :
– Les pommes ont en moyenne une masse de 150 g (écart-type : 20 g) et un diamètre de 7,5 cm (écart-type : 0,5 cm).
– Les oranges ont en moyenne une masse de 180 g (écart-type : 25 g) et un diamètre de 8,2 cm (écart-type : 0,6 cm).

Vous recevez un fruit inconnu de 160 g et 7,8 cm de diamètre. Le naive bayes gaussien calcule la probabilité d’observer ces mesures sous l’hypothèse “pomme” et sous l’hypothèse “orange”, en utilisant les courbes en cloche (gaussiennes) estimées. La classe avec la probabilité la plus élevée gagne.

Bien sûr, dans la réalité, masse et diamètre sont corrélés — un fruit plus gros est généralement plus lourd. L’hypothèse d’indépendance est violée. Pourtant, le modèle prend souvent la bonne décision, car les deux caractéristiques pointent dans la même direction et renforcent mutuellement leur signal.


Implémentation Python avec scikit-learn

Prérequis et installation

Assurez-vous que scikit-learn est installé dans votre environnement :

pip install scikit-learn numpy matplotlib seaborn

Exemple complet : classification synthétique

L’exemple suivant génère un jeu de données synthétique, entraîne un naive bayes gaussien, puis évalue ses performances de manière exhaustive :

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import (
    accuracy_score,
    precision_score,
    recall_score,
    f1_score,
    classification_report,
    confusion_matrix,
    ConfusionMatrixDisplay
)

# 1. Génération du jeu de données
X, y = make_classification(
    n_samples=1000,
    n_features=10,
    n_informative=6,
    n_redundant=2,
    n_clusters_per_class=1,
    n_classes=3,
    random_state=42
)

print(f"Jeu de données : {X.shape[0]} échantillons, {X.shape[1]} caractéristiques")
print(f"Nombre de classes : {len(np.unique(y))}")
print(f"Distribution des classes : {np.bincount(y)}")

# 2. Séparation entraînement / test (80/20)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# 3. Création et entraînement du modèle
gnb = GaussianNB()
gnb.fit(X_train, y_train)

# 4. Prédictions
y_pred = gnb.predict(X_test)
y_proba = gnb.predict_proba(X_test)

# 5. Évaluation des performances
print("\n" + "=" * 50)
print("RÉSULTATS DU NAIVE BAYES GAUSSIEN")
print("=" * 50)
print(f"Accuracy  : {accuracy_score(y_test, y_pred):.4f}")
print(f"Precision : {precision_score(y_test, y_pred, average='weighted'):.4f}")
print(f"Rappel    : {recall_score(y_test, y_pred, average='weighted'):.4f}")
print(f"F1-Score  : {f1_score(y_test, y_pred, average='weighted'):.4f}")

# 6. Rapport de classification détaillé
print("\n" + classification_report(y_test, y_pred))

# 7. Matrice de confusion
cm = confusion_matrix(y_test, y_pred)
print("Matrice de confusion :")
print(cm)

# 8. Visualisation de la matrice de confusion
fig, ax = plt.subplots(figsize=(8, 6))
disp = ConfusionMatrixDisplay(
    confusion_matrix=cm,
    display_labels=[f"Classe {i}" for i in range(3)]
)
disp.plot(cmap="Blues", ax=ax)
ax.set_title("Matrice de confusion — Naive Bayes Gaussien")
plt.tight_layout()
plt.savefig("confusion_matrix_gnb.png", dpi=150)
print("\nMatrice de confusion sauvegardée sous 'confusion_matrix_gnb.png'")

Probabilités et calibration

Une force du naive bayes gaussien est sa capacité à fournir des probabilités de classe via la méthode predict_proba() :

# Probabilités pour les 5 premières observations
for i in range(5):
    print(f"Échantillon {i} : Classe prédite = {y_pred[i]}")
    for j, proba in enumerate(y_proba[i]):
        print(f"  P(Classe {j}) = {proba:.4f}")
    print()

Ces probabilités sont utiles pour :
Décisions avec seuil personnalisé : exiger une probabilité minimale avant de valider une prédiction.
Détection d’observations ambiguës : les échantillons avec des probabilités équivalentes méritent une révision manuelle.
Règle métier : combiner la sortie probabiliste avec des contraintes métier spécifiques.

Cependant, il est important de noter que les probabilités produites par le naive bayes gaussien sont souvent mal calibrées — elles tendent à être extrêmes (proches de 0 ou 1) en raison de l’hypothèse d’indépendance qui multiplie les densités. Si des probabilités fiables sont critiques, envisagez d’appliquer un CalibratedClassifierCV de scikit-learn.


Hyperparamètres du GaussianNB

Contrairement à de nombreux algorithmes de machine learning, le naive bayes gaussien possède très peu d’hyperparamètres. Cette simplicité est un avantage considérable : il n’y a pratiquement pas de réglage à effectuer.

var_smoothing

C’est le seul hyperparamètre réglable de GaussianNB.

gnb = GaussianNB(var_smoothing=1e-9)  # valeur par défaut

Rôle : ajoute une petite valeur à toutes les variances estimées pour éviter la division par zéro. Mathématiquement :

σ²_utilisée = σ²_estimée + var_smoothing * max(variance)

Pourquoi c’est important : si une caractéristique a une variance nulle dans une classe (tous les échantillons ont exactement la même valeur), la densité gaussienne n’est pas définie. Sans lissage, le modèle planterait.

Comment le régler : dans la grande majorité des cas, la valeur par défaut de 1e-9 est parfaite. Si vous rencontrez des problèmes numériques avec des données très hétérogènes, une augmentation progressive (1e-8, 1e-7) peut stabiliser le modèle.

class_prior_ / priors

Cet attribut est appris automatiquement à partir des fréquences des classes dans les données d’entraînement. Vous pouvez le spécifier manuellement via le paramètre priors :

gnb = GaussianNB(priors=[0.3, 0.5, 0.2])

Cela peut être utile lorsque :
– Les données d’entraînement ne reflètent pas la distribution réelle (sur-échantillonnage d’une classe rare).
– Vous disposez d’une connaissance métier sur la prévalence des classes.
– Vous voulez expérimenter l’impact de différentes distributions a priori.


Avantages et limites du naive bayes gaussien

Avantages majeurs

Avantage Description
Rapidité extrême L’entraînement ne consiste qu’à calculer des moyennes et variances. Quelques millisecondes même sur des centaines de milliers d’échantillons.
Très peu de mémoire Le modèle ne stocke que μ et σ² par caractéristique et par classe. L’empreinte mémoire est négligeable.
Fonctionne bien en haute dimension L’indépendance conditionnelle simplifie le problème et évite la malédiction de la dimensionnalité qui affecte d’autres algorithmes.
Pas de surapprentissage (en général) Le modèle est si simple qu’il est naturellement régulé. Il ne “mémorise” pas le bruit.
Interprétabilité Les paramètres (μ, σ²) sont directement compréhensibles. On peut expliquer chaque prédiction.
Gestion du déséquilibre (partielle) Les probabilités a priori reflètent naturellement la fréquence des classes.
Pas de scaling nécessaire Contrairement aux SVM ou KNN, le naive bayes gaussien n’est pas sensible aux échelles différentes des caractéristiques, car chaque variable est normalisée par sa propre variance.

Limites à connaître

Limite Description
Hypothèse d’indépendance irréaliste Les corrélations entre caractéristiques sont ignorées, ce qui peut dégrader les performances.
Performance parfois inférieure Sur des problèmes complexes avec des interactions non linéaires fortes, Random Forests ou XGBoost surpassent généralement le GNB.
Probabilités mal calibrées Les probabilités obtenues par predict_proba() sont souvent trop confiantes.
Sensible aux valeurs aberrantes Une valeur extrême peut considérablement fausser l’estimation de la moyenne et de la variance.
Suppose une distribution gaussienne Si les données sont nettement non-gaussiennes (bimodales, exponentielles), le modèle perd en efficacité.
Pas de gestion native des valeurs manquantes Il faut imputer ou supprimer les valeurs NaN avant l’entraînement.

4 cas d’usage pratiques du naive bayes gaussien

Cas d’usage 1 : Diagnostic médical rapide

Le GNB excelle dans les tâches de dépistage où la rapidité et l’interprétabilité sont cruciales. Imaginez un système analysant des résultats sanguins (glycémie, cholestérol, pression artérielle) pour estimer le risque de diabète. Chaque marqueur est approximativement gaussien dans chaque groupe (diabétique / non diabétique), et le GNB fournit une estimation probabilitaire instantanée — idéal pour le triage en milieu rural où les ressources sont limitées.

Cas d’usage 2 : Détection de fraude en temps réel

Dans les transactions bancaires, le temps de réponse est critique. Le GNB peut analyser des dizaines de signaux (montant, lieu, heure, historique du titulaire) en quelques microsecondes. Même si un modèle plus complexe serait légèrement plus précis, le GNB offre un excellent compromis vitesse/précision pour le premier filtre de détection, relayant les cas ambigus à un modèle plus sophistiqué.

Cas d’usage 3 : Contrôle qualité industriel

Sur une chaîne de production, des capteurs mesurent en continu la température, la pression, la vibration et l’humidité. Le GNB, entraîné sur des données historiques étiquetées (produit conforme / défectueux), peut classifier chaque pièce en temps réel. Sa légèreté permet même un déploiement sur des microcontrôleurs embarqués, sans connexion cloud.

Cas d’usage 4 : Classification de données sensorielles IoT

Les données provenant de capteurs environnementaux (IoT) — température, humidité, luminosité, qualité de l’air — suivent généralement des distributions proches de la gaussienne. Le GNB permet de classifier automatiquement les états environnementaux (“normal”, “alerte”, “dangereux”) avec un coût de calcul quasi nul, parfait pour les dispositifs à faible consommation énergétique fonctionnant sur batterie.


Quand choisir le GaussianNB ?

Résumons les situations où le naive bayes gaussien est un excellent premier choix :

  • Données numériques continues (ou pouvant être rendues continues par transformation).
  • Besoin de rapidité : entraînement et inférence en temps réel.
  • Ressources limitées : embarqué, edge computing, IoT.
  • Interprétabilité requise : on doit pouvoir expliquer la décision.
  • Baseline rapide : établir une référence minimale avant d’essayer des modèles plus complexes.
  • Petits jeux de données : le GNB converge rapidement et ne souffre pas autant que d’autres algorithmes du manque de données.

À l’inverse, envisagez d’autres algorithmes si vos données contiennent principalement des catégories nominales (préférez Decision Trees ou Random Forests), si les corrélations entre caractéristiques sont essentielles au problème, ou si la précision maximale est le seul objectif sans contrainte de temps ou de ressources.


Voir aussi


Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.