Polydesk-logotype
Polydesk.ai — Header

DBSCAN (Density-Based Spatial Clustering of Applications with Noise)

DBSCAN est un algorithme de clustering basé sur la densité qui identifie les clusters comme des zones de haute densité séparées par des zones de faible densité, sans nécessiter de fixer le nombre de clusters à l’avance et en détectant automatiquement les outliers.

Publié en 1996 par Martin Ester, Hans-Peter Kriegel, Jörg Sander et Xiaowei Xu, DBSCAN est devenu la référence du clustering par densité. Contrairement à K-Means (qui cherche des clusters sphériques compacts), DBSCAN découvre des clusters de forme arbitraire : croissants, spirales, formes irrégulières. C’est le choix idéal quand vous ne connaissez pas le nombre de groupes, quand vos données contiennent du bruit, ou quand les clusters ont des géométries complexes.

Fiche rapide : DBSCAN
Nom complet
Density-Based Spatial Clustering of Applications with Noise
Auteurs
Ester, Kriegel, Sander, Xu (1996)
Type
Clustering par densité, non supervisé
Nombre de clusters
Déterminé automatiquement
Paramètres
eps (rayon de voisinage), min_samples (densité minimale)
Détecte les outliers
Oui (label = -1)
Forme des clusters
Arbitraire (non limité aux formes convexes)
Calcul Python
sklearn.cluster.DBSCAN

Les concepts fondamentaux de DBSCAN

DBSCAN repose sur trois types de points, définis par deux paramètres : epsilon (ε, le rayon de voisinage) et min_samples (le nombre minimum de points pour former une zone dense).

Points noyaux (Core Points)

Un point est un point noyau si son ε-voisinage (le cercle de rayon ε autour de lui) contient au moins min_samples points (lui-même inclus). Les points noyaux sont au cœur des clusters : ce sont les régions de haute densité.

Points frontières (Border Points)

Un point est un point frontière s’il est dans le ε-voisinage d’un point noyau, mais que son propre ε-voisinage contient moins de min_samples points. Il appartient au cluster mais n’est pas assez dense pour être un noyau. Il est en « bordure » du cluster.

Points de bruit (Noise / Outliers)

Un point est du bruit s’il n’est ni point noyau ni point frontière. Il est dans une zone de faible densité, trop éloigné de tout cluster. DBSCAN lui attribue le label -1. C’est ce qui rend DBSCAN naturellement apte à la détection d’anomalies.

L’algorithme DBSCAN pas à pas

Étape 1 : Choisir un point non visité du dataset.

Étape 2 : Calculer son ε-voisinage (tous les points à une distance ≤ ε).

Étape 3 : Si le voisinage contient ≥ min_samples points, ce point est un point noyau. Créer un nouveau cluster et y ajouter ce point et tous ses voisins.

Étape 4 : Pour chaque voisin qui est aussi un point noyau, ajouter récursivement ses propres voisins au cluster. C’est cette expansion récursive qui permet de construire des clusters de forme arbitraire.

Étape 5 : Si le voisinage contient < min_samples points, marquer temporairement le point comme bruit. (Il pourra être reclassé comme point frontière si un cluster ultérieur l’englobe.)

Étape 6 : Répéter jusqu’à ce que tous les points soient visités.

Expansion de cluster : la force de DBSCAN L’expansion récursive est ce qui permet à DBSCAN de trouver des clusters non convexes. Un cluster peut « serpenter » à travers l’espace en suivant une chaîne de points noyaux, chacun étendant le cluster dans sa direction. K-Means ne peut pas faire cela car il assigne chaque point au centroïde le plus proche, ce qui produit toujours des régions convexes.

Les deux paramètres de DBSCAN

eps (epsilon) : le rayon de voisinage

Epsilon définit la distance maximale entre deux points pour qu’ils soient considérés comme voisins. C’est le paramètre le plus critique. Un epsilon trop petit crée trop de clusters fragmentés et trop de bruit. Un epsilon trop grand fusionne des clusters distincts en un seul.

Méthode du k-distance graph pour choisir epsilon : calculez la distance au k-ième plus proche voisin pour chaque point (k = min_samples), triez ces distances par ordre croissant et tracez le graphique. Le « coude » de la courbe indique la valeur optimale d’epsilon.

from sklearn.neighbors import NearestNeighbors
import numpy as np
import matplotlib.pyplot as plt

# Calcul des distances au k-ième voisin
k = 5  # = min_samples
neighbors = NearestNeighbors(n_neighbors=k)
neighbors.fit(X_scaled)
distances, _ = neighbors.kneighbors(X_scaled)

# Trier les distances au k-ième voisin
k_distances = np.sort(distances[:, k-1])

# Tracer le k-distance graph
plt.figure(figsize=(8, 5))
plt.plot(k_distances, color='#7c3aed', lw=2)
plt.xlabel('Points (triés par distance)')
plt.ylabel(f'Distance au {k}-ième voisin')
plt.title('K-Distance Graph (coude = epsilon optimal)')
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()

min_samples : la densité minimale

Le nombre minimum de points dans le ε-voisinage d’un point pour qu’il soit considéré comme point noyau. Règles de pouce :

min_samples ≥ nombre de dimensions + 1 : règle classique de la littérature. Pour des données 2D, min_samples = 3 minimum.

Valeurs plus élevées (10-20) : produisent des clusters plus denses et plus de points classés comme bruit. Plus robuste mais risque de manquer de petits clusters.

Valeurs basses (3-5) : détectent des clusters moins denses et classent moins de points comme bruit. Risque de connecter des clusters distincts.

En pratique, commencez avec min_samples = 5 (défaut scikit-learn) et ajustez en fonction des résultats.

DBSCAN en Python avec scikit-learn

Usage de base

from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
import numpy as np

# Standardiser les données
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# DBSCAN
dbscan = DBSCAN(eps=0.5, min_samples=5)
labels = dbscan.fit_predict(X_scaled)

# Résultats
n_clusters = len(set(labels)) - (1 if -1 in labels else 0)
n_noise = (labels == -1).sum()
print(f"Clusters trouvés : {n_clusters}")
print(f"Points de bruit : {n_noise}")
print(f"Points noyaux : {len(dbscan.core_sample_indices_)}")

Visualisation avec distinction core/border/noise

import matplotlib.pyplot as plt

# Masque des points noyaux
core_mask = np.zeros(len(labels), dtype=bool)
core_mask[dbscan.core_sample_indices_] = True

# Visualisation
fig, ax = plt.subplots(figsize=(10, 7))

# Points noyaux (gros)
ax.scatter(X_scaled[core_mask, 0], X_scaled[core_mask, 1],
           c=labels[core_mask], cmap='viridis', s=40, alpha=0.8,
           label='Noyaux')

# Points frontières (petits)
border_mask = ~core_mask & (labels != -1)
ax.scatter(X_scaled[border_mask, 0], X_scaled[border_mask, 1],
           c=labels[border_mask], cmap='viridis', s=15, alpha=0.5,
           label='Frontières')

# Bruit (croix noires)
noise_mask = labels == -1
ax.scatter(X_scaled[noise_mask, 0], X_scaled[noise_mask, 1],
           c='black', marker='x', s=20, alpha=0.5,
           label='Bruit')

ax.legend()
ax.set_title(f'DBSCAN : {n_clusters} clusters, {n_noise} outliers')
plt.tight_layout()
plt.show()
from sklearn.metrics import silhouette_score

best_score = -1
best_params = {}

for eps in [0.3, 0.5, 0.7, 1.0, 1.5]:
    for ms in [3, 5, 10, 15]:
        db = DBSCAN(eps=eps, min_samples=ms)
        labels = db.fit_predict(X_scaled)
        n_clusters = len(set(labels)) - (1 if -1 in labels else 0)

        if n_clusters >= 2:
            # Silhouette seulement sur les points non-bruit
            mask = labels != -1
            if mask.sum() > n_clusters:
                score = silhouette_score(X_scaled[mask], labels[mask])
                if score > best_score:
                    best_score = score
                    best_params = {'eps': eps, 'min_samples': ms,
                                   'clusters': n_clusters}

print(f"Meilleurs paramètres : {best_params}")
print(f"Silhouette score : {best_score:.4f}")

DBSCAN vs K-Means : quand utiliser lequel

Critère DBSCAN K-Means
Nombre de clusters Automatique À fixer (K)
Forme des clusters Arbitraire Sphérique uniquement
Détection d’outliers Oui (natif) Non
Vitesse O(n log n) à O(n²) O(n · K · d · t), très rapide
Scalabilité Bonne (< 100K points) Excellente (millions de points)
Haute dimension Dégradée Dégradée (moins critique)
Densité variable Problématique Pas un problème
Sensibilité aux outliers Robuste (les isole) Sensible (les intègre)
Prédiction (nouvelles données) Pas de .predict() Oui (.predict())
Reproductibilité Déterministe (hors points frontières) Dépend de l’initialisation

En résumé : K-Means quand vous connaissez K et que vos clusters sont globalement sphériques. DBSCAN quand K est inconnu, que les formes sont irrégulières, ou que les données contiennent du bruit.

Limites de DBSCAN

Clusters de densité variable

Le principal talon d’Achille de DBSCAN : comme epsilon est un paramètre global, il ne peut pas gérer des clusters de densités très différentes. Un epsilon adapté au cluster dense va fragmenter le cluster peu dense, et inversement. C’est pour cette raison qu’HDBSCAN a été développé.

Haute dimension

En haute dimension, la distance euclidienne perd son pouvoir discriminant (fléau de la dimensionnalité). Les voisinages ε deviennent soit vides (epsilon trop petit) soit englobent tout (epsilon trop grand). Solution : appliquer PCA ou UMAP avant DBSCAN.

Pas de prédiction sur de nouvelles données

L’implémentation scikit-learn de DBSCAN n’a pas de méthode .predict(). Pour assigner de nouveaux points, il faut soit relancer l’algorithme sur l’ensemble complet, soit utiliser une heuristique (distance au centroïde ou au point noyau le plus proche).

Sensibilité aux paramètres

Un mauvais choix d’epsilon ou de min_samples peut produire des résultats très différents : un seul cluster géant ou des milliers de micro-clusters. Le k-distance graph aide, mais ne remplace pas l’expérimentation.

Alternatives et évolutions

HDBSCAN (Hierarchical DBSCAN)

L’évolution majeure de DBSCAN. HDBSCAN construit une hiérarchie de clusters à différents niveaux de densité, puis extrait les clusters les plus persistants. Avantages : un seul paramètre principal (min_cluster_size), gère les densités variables, souvent de meilleurs résultats que DBSCAN. C’est souvent le premier choix pour le clustering exploratoire.

OPTICS

Produit un ordonnancement des points par densité plutôt qu’un clustering fixe. Cet ordonnancement peut être coupé à différents niveaux pour extraire des clusters. Plus flexible que DBSCAN mais plus complexe à interpréter. Disponible dans scikit-learn : sklearn.cluster.OPTICS.

Applications de DBSCAN

Détection d’anomalies : les points classés bruit (label -1) sont des anomalies candidates. Utilisé en détection de fraude, sécurité réseau, contrôle qualité.

Analyse géospatiale : clustering de coordonnées GPS (incidents, transactions, check-ins) pour identifier les zones d’activité. La métrique Haversine est adaptée aux coordonnées géographiques.

Traitement d’images : segmentation de pixels par couleur ou texture, regroupement de points d’intérêt en computer vision.

Bioinformatique : clustering de séquences génétiques, identification de sous-populations cellulaires. Souvent après une réduction par PCA + UMAP.

NLP : clustering de documents ou d’embeddings de phrases pour la découverte de thèmes, souvent via UMAP + HDBSCAN.

Verdict

DBSCAN est l’algorithme de référence quand vous ne savez pas combien de clusters existent, quand les clusters ont des formes non convexes, ou quand vos données contiennent des outliers à identifier. Sa force principale : il ne force pas les données dans un nombre prédéfini de groupes, ce qui en fait un outil d’exploration honnête.

Sa limite principale (densité globale fixe) est résolue par HDBSCAN, qui est souvent le meilleur premier choix pour le clustering exploratoire. En pratique, essayez les deux : DBSCAN pour sa simplicité (deux paramètres), HDBSCAN pour sa robustesse (un seul paramètre clé). Et dans les deux cas, réduisez d’abord la dimensionnalité avec PCA ou UMAP si vous avez plus de 50 features.


Questions fréquentes sur DBSCAN

Comment choisir la valeur d’epsilon pour DBSCAN ?

La méthode standard est le k-distance graph : calculez la distance au k-ième plus proche voisin (k = min_samples) pour chaque point, triez ces distances et tracez la courbe. Le « coude » indique la valeur d’epsilon optimale. En dessous de ce coude, la plupart des points ont des voisins proches (clusters). Au-dessus, les distances augmentent fortement (bruit). En pratique, testez aussi 2-3 valeurs autour du coude et comparez les résultats via le silhouette score.

Quelle est la différence entre DBSCAN et HDBSCAN ?

DBSCAN utilise un epsilon fixe (global), ce qui le rend inadapté aux clusters de densités très différentes. HDBSCAN (Hierarchical DBSCAN) construit une hiérarchie de clusters à tous les niveaux de densité et en extrait les clusters les plus stables. Il a un seul paramètre principal (min_cluster_size) au lieu de deux. HDBSCAN gère mieux les densités variables, produit généralement de meilleurs résultats et nécessite moins de tuning. Pour un nouveau projet, HDBSCAN est souvent le meilleur premier choix.

DBSCAN peut-il prédire le cluster de nouvelles données ?

Non, l’implémentation scikit-learn de DBSCAN n’a pas de méthode .predict(). Pour assigner de nouvelles observations, vous pouvez : relancer DBSCAN sur le dataset complet (original + nouveaux points), utiliser une approche par plus proche voisin (assigner chaque nouveau point au cluster du point noyau le plus proche), ou utiliser HDBSCAN qui supporte .approximate_predict(). Si la prédiction sur de nouvelles données est essentielle, K-Means (qui a .predict()) ou HDBSCAN sont de meilleures options.

Pourquoi DBSCAN met tous les points dans un seul cluster ou tout en bruit ?

Un seul cluster géant signifie qu’epsilon est trop grand : le voisinage est si large que tous les points se connectent. Solution : réduisez epsilon. Tout en bruit signifie qu’epsilon est trop petit ou min_samples trop élevé : aucun point n’a assez de voisins pour être un point noyau. Solution : augmentez epsilon ou réduisez min_samples. Utilisez le k-distance graph pour trouver la bonne plage d’epsilon. Et n’oubliez pas de standardiser les données avant, car des échelles différentes faussent les distances.

DBSCAN fonctionne-t-il en haute dimension ?

Mal. En haute dimension (100+ features), les distances euclidiennes deviennent peu discriminantes et DBSCAN peine à distinguer les zones denses des zones éparses. La solution standard est de réduire d’abord la dimensionnalité avec PCA (50 composantes) ou UMAP (2-50 dimensions), puis d’appliquer DBSCAN sur l’espace réduit. Le pipeline UMAP (min_dist=0.0) + HDBSCAN est devenu le standard pour le clustering de données complexes de haute dimension.

Polydesk.ai — Footer