Une extension de DBSCAN qui teste tous les rayons de voisinage à la fois et garde les groupes les plus stables. Il trouve dans la même analyse un grand groupe diffus et un petit groupe très serré, là où DBSCAN impose un seul rayon. Un seul réglage compte vraiment : la taille minimale d'un groupe.
Une carte du relief vue par un niveau d'eau qui monte. Les îles qui restent émergées longtemps sont de vrais sommets ; celles qui disparaissent vite ne sont que des bosses.
La distance au k-ième voisin sert de mesure : petite dans une zone dense, grande dans une zone vide. Les distances sont corrigées pour que les points isolés restent loin de tout.
En faisant varier le seuil de densité, les groupes se séparent ou disparaissent. On obtient un arbre, comme si l'on lançait DBSCAN avec tous les rayons possibles.
Un groupe qui survit sur une large plage de densités est retenu ; ceux qui ont moins de membres que la taille minimale sont traités comme du bruit. Chaque point reçoit aussi une probabilité d'appartenance.
Montant, heure, nombre de transactions du porteur sur 24 h, distance au domicile, nouveau marchand ou non. Montants et distances passent au logarithme pour ne pas écraser le reste.
HDBSCAN trouve les achats habituels (4 474), les achats chez un nouveau marchand (485) et un groupe serré de 39 transactions : gros montants, en pleine nuit, loin du domicile, en rafale. Seules 2 transactions restent en bruit.
Les fraudes confirmées plus tard servent seulement à vérifier : les 39 transactions du petit groupe sont toutes des fraudes, et la 40e est en bruit. HDBSCAN révèle ici un schéma de fraude organisé, pas seulement des cas isolés. Sur des données réelles, les frontières sont bien moins nettes.
Noms donnés pour R (paquet dbscan) et Python (scikit-learn, qui intègre HDBSCAN depuis la version 1.3).
La taille minimale d'un groupe. C'est le réglage principal : en dessous, un regroupement est traité comme du bruit. Ici, 25 permet de voir le groupe des 39 transactions ; avec 50, il bascule dans le bruit.
Le nombre de voisins pour mesurer la densité, égal par défaut à min_cluster_size. Plus il est grand, plus l'algorithme est prudent et plus il déclare de bruit. En R, minPts règle les deux à la fois.
"eom" (défaut) favorise les groupes les plus stables, parfois grands. "leaf" retient les groupes les plus fins de l'arbre, utile pour obtenir des micro-segments homogènes.
# Comportements de paiement : HDBSCAN en R
library(dbscan)
transactions <- read.csv("transactions.csv")
variables <- c("montant", "heure", "nb_transactions_24h", "distance_km", "nouveau_marchand")
X <- transactions[, variables]
# Log sur les montants et distances, très étirés vers le haut
X$montant <- log1p(X$montant)
X$distance_km <- log1p(X$distance_km)
X <- scale(X)
# Un seul réglage : minPts, taille minimale d'un groupe (et densité de référence)
modele <- hdbscan(X, minPts = 25)
transactions$groupe <- modele$cluster # 0 = bruit
print(modele)
# Profil médian de chaque groupe
print(aggregate(transactions[, variables], by = list(groupe = transactions$groupe), FUN = median))
# Contrôle après coup, avec les fraudes confirmées plus tard
print(table(groupe = transactions$groupe, fraude = transactions$fraude_confirmee))
# Comportements de paiement : HDBSCAN en Python
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import HDBSCAN
transactions = pd.read_csv("transactions.csv")
variables = ["montant", "heure", "nb_transactions_24h", "distance_km", "nouveau_marchand"]
X = transactions[variables].copy()
# Log sur les montants et distances, très étirés vers le haut
X["montant"] = np.log1p(X["montant"])
X["distance_km"] = np.log1p(X["distance_km"])
X = StandardScaler().fit_transform(X)
# Un seul réglage : la taille minimale d'un groupe
modele = HDBSCAN(min_cluster_size=25, copy=True).fit(X)
transactions["groupe"] = modele.labels_
# Taille et profil médian de chaque groupe (-1 = bruit)
print(transactions.groupby("groupe")[variables].median().assign(n=transactions["groupe"].value_counts()).to_string())
# Contrôle après coup, avec les fraudes confirmées plus tard
print(pd.crosstab(transactions["groupe"], transactions["fraude_confirmee"]))
DBSCAN utilise un seul rayon eps pour toutes les zones, ce qui échoue quand les densités varient. HDBSCAN explore tous les rayons et garde les groupes les plus stables. Il remplace le choix délicat de eps par celui, plus intuitif, de la taille minimale d'un groupe.
Demandez-vous à partir de combien de cas un groupe vous intéresse. Pour une segmentation marketing, quelques centaines ; pour repérer une fraude organisée, quelques dizaines. On teste ensuite deux ou trois valeurs et on garde celle dont les groupes sont stables et interprétables.
Oui, de deux façons. Les points classés en bruit sont atypiques, et chaque point reçoit un score d'aberration (GLOSH), disponible dans le paquet R dbscan et dans le paquet Python hdbscan. HDBSCAN repère aussi des micro-groupes d'anomalies semblables, ce qu'un score individuel ne montre pas.
Plus simple et plus rapide, mais un seul rayon eps pour toutes les zones. Suffit quand les densités sont homogènes.
Voir la fiche → pour scorer les cas isolésDonne un score d'anomalie à chaque transaction. Complémentaire : HDBSCAN voit les groupes suspects, Isolation Forest les cas isolés.
Voir la fiche → pour explorerOrdonne les points par densité et laisse choisir l'échelle en regardant le graphe d'accessibilité.
Voir la fiche →Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.
Nous utilisons des cookies de mesure d'audience et de suivi publicitaire pour comprendre la fréquentation du site et l'efficacité de nos annonces. Rien n'est déposé sans votre accord. En savoir plus