Une détection d’outliers robuste commence par choisir la méthode adaptée aux données. Z-score, IQR, MAD, Isolation Forest ou DBSCAN ne répondent pas au même problème. Je vous montre quand les utiliser, où ça casse, et comment éviter les faux diagnostics trop rapides.
Quand le Z-score suffit-il ?
Le Z-score suffit quand je veux faire un premier contrôle rapide sur une variable numérique, et que les données sont à peu près distribuées normalement. Pas parfaites, hein. Juste pas trop tordues, pas trop asymétriques, avec une forme qui ressemble vaguement à une cloche.
Le principe est simple. Je prends la moyenne, qui représente le centre des données, puis l’écart-type, qui mesure à quel point les valeurs s’éloignent naturellement de ce centre. Le Z-score dit combien d’écarts-types séparent une observation de la moyenne.
Une règle courante consiste à dire qu’une valeur avec |Z| > 3 mérite d’être regardée. Ça veut dire qu’elle est à plus de 3 écarts-types de la moyenne. Je dis bien “mérite d’être regardée”, pas “c’est forcément une erreur”. Dans un projet client, je m’en sers souvent comme filtre de contrôle qualité rapide, pour sortir une première liste de valeurs suspectes avant de discuter métier.
Comme on dit à Brive, un bon plan de marquage vaut mieux qu’un bon reporting ! Si besoin, consultez moi - faites appel à un super consultant en tracking client et server side.
import numpy as np
# Données avec une valeur manifestement très élevée
values = np.array([10, 11, 12, 11, 13, 12, 14, 10, 11, 12, 250])
# Calcul du Z-score
mean = np.mean(values)
std = np.std(values)
z_scores = (values - mean) / std
# Récupération des valeurs dont le Z-score absolu dépasse 3
outliers = values[np.abs(z_scores) > 3]
print(z_scores)
print(outliers)
Dans cet exemple, 250 ressort comme une valeur suspecte. C’est exactement le genre de test que je peux lancer en quelques secondes sur une colonne de montant, de durée, de température, de nombre de clics, peu importe.
Le gros point faible, c’est que la moyenne et l’écart-type sont eux-mêmes très sensibles aux valeurs extrêmes. Si j’ai déjà des outliers dans mes données, ils peuvent tirer la moyenne vers eux et gonfler l’écart-type. Résultat, certaines anomalies deviennent moins visibles. C’est un peu le paradoxe du Z-score : il peut devenir fragile précisément au moment où j’ai besoin d’un détecteur robuste.
Dès que la distribution n’est pas propre, pas normale, ou qu’elle part franchement de travers, je préfère souvent passer à une méthode basée sur les quantiles, comme l’IQR.
Pourquoi choisir l’IQR ?
Je choisis l’IQR parce qu’il tient mieux la route quand les données sont sales, asymétriques, ou pleines de quelques valeurs extrêmes. Le Z-score marche bien quand la distribution ressemble à une courbe normale, la fameuse cloche. Mais dans la vraie vie, surtout sur des données métier, c’est rarement aussi propre. J’ai vu ça souvent chez des clients avec des montants de commande, des délais de traitement, des volumes de tickets. Une poignée de gros cas suffit à tirer la moyenne et l’écart-type, et le Z-score devient moins fiable.
L’IQR veut dire InterQuartile Range, ou écart interquartile. L’idée est simple. On coupe les données en quatre parties.
- Q1 est le premier quartile. 25% des valeurs sont en dessous.
- Q3 est le troisième quartile. 75% des valeurs sont en dessous.
- IQR = Q3 – Q1. C’est la largeur de la zone centrale des données.
Ensuite, on pose deux bornes classiques. La borne basse vaut Q1 – 1.5 * IQR. La borne haute vaut Q3 + 1.5 * IQR. Les points qui tombent en dehors de ces bornes sont considérés comme des outliers.
Le vrai avantage, c’est que cette méthode repose sur les quartiles. Pas sur la moyenne. Pas sur l’écart-type. Donc une valeur énorme ne va pas exploser le calcul aussi facilement. C’est pour ça que je préfère souvent commencer par l’IQR quand je ne connais pas encore bien mes données.
Il faut quand même rester lucide. L’IQR regarde une variable à la fois. C’est une méthode univariée, donc elle ne détecte pas les anomalies qui apparaissent seulement dans une combinaison de variables. Et le facteur 1.5, c’est un choix pratique très utilisé, pas une loi physique. On peut l’ajuster selon le métier.
import pandas as pd
# Petite série avec une valeur aberrante
s = pd.Series([10, 11, 12, 12, 13, 14, 15, 100])
q1 = s.quantile(0.25)
q3 = s.quantile(0.75)
iqr = q3 - q1
lower = q1 - 1.5 * iqr
upper = q3 + 1.5 * iqr
outliers = s[(s < lower) | (s > upper)]
print(q1, q3, iqr)
print(lower, upper)
print(outliers.tolist())
| Critère | Z-score | IQR |
| Données normales | Très adapté | Adapté aussi |
| Données non normales | Moins fiable | Souvent meilleur réflexe |
| Robustesse | Sensible aux extrêmes | Moins sensible aux extrêmes |
| Simplicité | Simple à calculer | Simple à calculer et à expliquer |
Quand utiliser MAD ?
J’utilise MAD quand je veux détecter des outliers de façon robuste sur une seule variable, surtout si mes données ne suivent pas une belle distribution normale, ou si j’ai déjà pas mal de valeurs extrêmes dans le jeu de données.
MAD veut dire Median Absolute Deviation, ou déviation absolue médiane. C’est, en gros, une version plus solide de l’idée du Z-score. Le Z-score compare une valeur à la moyenne avec l’écart-type. Le problème, c’est que la moyenne et l’écart-type se font vite tirer vers le haut ou vers le bas par quelques valeurs extrêmes. MAD remplace ça par la médiane, beaucoup moins sensible aux gros écarts.
Le calcul est assez simple.
- Je calcule la médiane des données.
- Je calcule la distance absolue entre chaque point et cette médiane.
- Je prends la médiane de ces distances. C’est ça, le MAD.
Ensuite, je calcule un score modifié. Si ce score dépasse un seuil, souvent autour de 3, je peux signaler la valeur comme suspecte. Je dis “suspecte”, pas “fausse”. Le seuil reste un choix métier ou analytique. Un panier moyen à 2 000 € peut être une erreur, ou juste un très bon client.
import numpy as np
x = np.array([42, 45, 43, 44, 46, 100, 41, 43, 44])
median = np.median(x)
absolute_deviations = np.abs(x - median)
mad = np.median(absolute_deviations)
modified_z_scores = 0.6745 * (x - median) / mad
threshold = 3
outliers = x[np.abs(modified_z_scores) > threshold]
print("Médiane :", median)
print("MAD :", mad)
print("Scores modifiés :", modified_z_scores)
print("Outliers :", outliers)
Dans la vraie vie, je ne recode pas toujours ça à la main. Scipy propose scipy.stats.median_abs_deviation, qui évite les erreurs bêtes et rend le code plus propre.
La limite, c’est que MAD est surtout un outil univarié. Il regarde une variable à la fois. Si un outlier n’apparaît que dans une combinaison de variables, par exemple prix normal mais durée anormale pour ce prix, MAD ne le verra pas forcément.
Sur des données business comme ventes, prix, durées ou panier moyen, j’ai souvent plus confiance dans MAD ou IQR que dans un Z-score lancé trop vite. C’est moins élégant sur le papier parfois, mais beaucoup plus fiable quand les données sont sales, asymétriques, ou franchement humaines.
À quoi sert Isolation Forest ?
Isolation Forest sert à détecter des anomalies quand elles ne se voient plus sur une seule colonne, mais dans la combinaison de plusieurs variables. Je l’utilise typiquement quand un montant seul n’est pas bizarre, une fréquence seule non plus, mais que les deux ensemble racontent autre chose. C’est souvent là que les règles simples commencent à casser.
L’idée est assez intuitive. L’algorithme construit plusieurs arbres qui découpent les données au hasard. À chaque découpe, il sépare les points selon une variable et une valeur choisies aléatoirement. Les points vraiment atypiques sont souvent isolés plus vite, parce qu’ils sont rares et différents du reste. Donc, quand un point a un chemin court dans les arbres, ça indique souvent une anomalie.
Ce que j’aime avec Isolation Forest, c’est qu’il tient bien quand on a plusieurs variables à surveiller en même temps. Pas besoin de résumer le problème à une seule métrique. Il peut capter des anomalies globales, du genre “ce profil complet ne ressemble pas aux autres”.
- Adapté au multivarié. Il regarde les combinaisons de variables, pas juste une colonne isolée.
- Utile en haute dimension. Il reste pratique quand on a beaucoup de colonnes, même si ça demande quand même du bon sens côté préparation des données.
- Efficace sur des anomalies globales. Il repère les points qui sortent franchement de la masse.
Il y a quand même des limites. Il faut régler quelques paramètres, surtout contamination, qui correspond à la proportion d’anomalies qu’on pense avoir dans le jeu de données. Si je mets 0.05, je dis en gros “j’estime qu’environ 5% des lignes sont suspectes”. Ce n’est pas une vérité mathématique. C’est une méthode heuristique, donc probabiliste dans l’esprit : elle donne un signal robuste, pas un jugement absolu.
import pandas as pd
from sklearn.ensemble import IsolationForest
# Création d'un petit jeu de données
df = pd.DataFrame({
"montant": [20, 25, 22, 30, 28, 500],
"frequence": [2, 3, 2, 4, 3, 1]
})
# Entraînement du modèle
model = IsolationForest(contamination=0.15, random_state=42)
df["prediction"] = model.fit_predict(df[["montant", "frequence"]])
# Identification des anomalies
anomalies = df[df["prediction"] == -1]
print(df)
print(anomalies)
| Valeur scikit-learn | Interprétation |
| -1 | Anomalie détectée |
| 1 | Point considéré comme normal |
Isolation Forest isole donc des comportements rares. DBSCAN, lui, regarde plutôt la densité locale des points. C’est une autre façon de poser la question : au lieu de demander “ce point est-il facile à isoler ?”, on demande “ce point vit-il dans une zone dense ou tout seul dans son coin ?”.
Quand DBSCAN repère mieux les anomalies ?
DBSCAN repère mieux les anomalies quand elles ressemblent à des points isolés dans des zones de faible densité. C’est là qu’il devient vraiment utile. Je l’utilise surtout sur des données spatiales, des coordonnées GPS, des comportements utilisateurs, ou des jeux de données où les groupes ont des formes bizarres. Pas des jolis ronds propres comme dans les exemples de cours.
Le principe est assez simple. DBSCAN cherche des zones denses. Il regarde autour de chaque point, forme des groupes quand il trouve assez de voisins proches, puis il marque comme bruit les points qui ne rentrent dans aucun groupe dense. Dans scikit-learn, ces points de bruit sont généralement labellisés -1. C’est souvent là que vos anomalies se cachent.
Il y a deux paramètres à comprendre, sinon on pilote à l’aveugle.
- eps correspond à la distance maximale autour d’un point pour chercher ses voisins. Trop petit, presque tout devient anomalie. Trop grand, tout finit dans le même cluster.
- min_samples correspond au nombre minimum de points nécessaires pour considérer une zone comme dense. Plus il est élevé, plus DBSCAN devient strict.
Son gros avantage, c’est qu’il fonctionne en multivarié, donc avec plusieurs variables en même temps. Il ne force pas non plus les clusters à être sphériques. Ça change tout quand la structure n’est pas linéaire. J’ai déjà vu ça chez un client sur des trajets logistiques : un Z-score sortait trois alertes sans intérêt, alors que DBSCAN repérait des détours vraiment suspects.
Mais il n’est pas magique. Il est très sensible à eps et min_samples. Et si vos clusters ont des densités très différentes, il peut mal se comporter. Un groupe très dense et un autre plus étalé dans le même dataset, c’est souvent pénible à régler.
from sklearn.cluster import DBSCAN
import pandas as pd
# Exemple avec deux variables numériques
X = df[["distance", "montant"]]
# Entraîner DBSCAN et récupérer les labels
dbscan = DBSCAN(eps=0.8, min_samples=5)
labels = dbscan.fit_predict(X)
# Ajouter les labels au DataFrame
df["cluster"] = labels
# Filtrer les anomalies labellisées -1
outliers = df[df["cluster"] == -1]
print(outliers)
| Méthode | Cas idéal | Point fort | Limite principale |
| Z-score | Données normales, une variable | Simple et rapide | Sensible aux valeurs extrêmes |
| IQR | Données asymétriques simples | Robuste et lisible | Univarié, assez basique |
| MAD | Données bruitées avec médiane fiable | Très robuste aux extrêmes | Moins intuitif à expliquer |
| Isolation Forest | Anomalies multivariées complexes | Bon sur grands volumes | Moins interprétable |
| DBSCAN | Points isolés et clusters non linéaires | Détecte le bruit naturellement | Sensible aux paramètres et aux densités variables |
Alors quelle méthode allez-vous tester en premier ?
Je retiens une chose simple : il n’y a pas une méthode magique pour détecter les outliers. Le Z-score va vite, mais il suppose des données propres et plutôt normales. L’IQR et MAD sont plus robustes pour une variable, surtout quand les valeurs extrêmes perturbent les calculs. Isolation Forest devient plus utile quand l’anomalie vient d’une combinaison de variables. DBSCAN aide quand la densité des points raconte quelque chose.
Le vrai gain, c’est de choisir la méthode en fonction de vos données, pas par habitude. Vous détectez mieux, vous nettoyez mieux, et vos analyses deviennent plus fiables.
FAQ
- Qu’est-ce qu’un outlier en data ?
Un outlier est une valeur qui s’écarte fortement du reste des données. Ça peut être une vraie anomalie, une erreur de saisie, un événement rare ou simplement un comportement inhabituel. Le piège, c’est de le supprimer trop vite sans comprendre ce qu’il représente. - Quelle méthode utiliser pour une détection d’outliers simple ?
Pour une seule variable, je commence souvent par IQR ou MAD. Le Z-score est pratique si les données sont à peu près normales, mais il est sensible aux valeurs extrêmes. IQR et MAD sont généralement plus robustes quand les distributions sont moins propres. - Pourquoi le Z-score peut-il être fragile ?
Le Z-score dépend de la moyenne et de l’écart-type. Si une valeur extrême est déjà présente, elle peut influencer ces deux mesures et fausser le résultat. C’est pour ça que je l’utilise surtout sur des données bien comprises et plutôt normalement distribuées. - Quand utiliser Isolation Forest plutôt qu’IQR ou MAD ?
Isolation Forest devient intéressant quand l’anomalie vient de plusieurs variables en même temps. IQR et MAD regardent surtout une variable isolée. Isolation Forest détecte plutôt des observations rares dans un espace multivarié, ce qui colle mieux à beaucoup de cas business. - DBSCAN est-il fiable pour détecter les outliers ?
DBSCAN peut très bien fonctionner quand les outliers sont des points isolés en dehors de zones denses. Il est utile pour des structures complexes. Son vrai point faible, c’est le réglage de eps et min_samples. Si ces paramètres sont mal choisis, les résultats peuvent vite devenir trompeurs.
A propos de l’auteur
Je suis Franck Scandolera, expert et formateur en tracking avancé server-side, Analytics Engineering, automatisation No/Low Code avec n8n, IA appliquée en entreprise et SEO/GEO. J’accompagne des équipes qui doivent fiabiliser leurs données avant de les exploiter dans des dashboards, des modèles ou des automatisations business. J’ai travaillé avec des références comme Logis Hôtel, Yelloh Village, BazarChic, la Fédération Française de Football ou Texdecor. Je dirige l’agence webAnalyste et l’organisme Formations Analytics. Si vous voulez structurer vos données, vos automatisations ou vos cas d’usage IA, contactez-moi.
⭐ Data Analyst, Analytics Engineer et expert dans l’automatisation IA ⭐
Ref clients : Logis Hôtel, Yelloh Village, BazarChic, Fédération Football Français, Texdecor…
Mon terrain de jeu :
Data Analyst & Analytics engineering : tracking propre RGPD, entrepôt de données (GTM server, BigQuery…), modèles (dbt/Dataform), dashboards décisionnels (Looker, SQL, Python).
Automatisation IA des taches Data, Marketing, RH, compta etc : conception de workflows intelligents robustes (n8n, Make, App Script, scraping) connectés aux API de vos outils et LLM (OpenAI, Mistral, Claude…).
Engineering IA pour créer des applications et agent IA sur mesure : intégration de LLM (OpenAI, Mistral…), RAG, assistants métier, génération de documents complexes, APIs, backends Node.js/Python.





