Biais de collision : comment le filtrage des données crée des corrélations fausses
Un biais de collision se produit lorsqu'une variable C est influencée par deux autres variables A et B via des chemins causaux : A → C ← B. Conditionner sur C — qu'il s'agisse d'un filtrage ou d'une stratification — génère une corrélation artificielle entre A et B.
Exemples concrets :
- Âge → Utilisation → Qualité (les objets survivants semblent plus qualitatifs).
- QI → Admission à l’université → Richesse familiale (parmi les étudiants, les plus riches semblent moins intelligents).
- Talent → Succès → Éthique du travail (les individus talentueux ayant réussi semblent plus paresseux).
En science des données, cela conduit à des modèles trompeurs : les algorithmes comme le gradient boosting appliqués à des données filtrées héritent de ce biais.
Simulation avec des données uniformes
Nous générons 1 000 points indépendants pour A et B selon une loi uniforme sur [0, 100]. Le marqueur de collision est activé si A > 50 ou B > 50.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from statsmodels.nonparametric.smoothers_lowess import lowess
NUMBER_OF_VALUES = 1000
A_RANGE = (0, 100)
B_RANGE = (0, 100)
A_THRESHOLD = 50
B_THRESHOLD = 50
a = np.random.uniform(*A_RANGE, NUMBER_OF_VALUES)
b = np.random.uniform(*B_RANGE, NUMBER_OF_VALUES)
data = pd.DataFrame({'a': a, 'b': b})
data['flag'] = (data['a'] > A_THRESHOLD) | (data['b'] > B_THRESHOLD)
print(f"Corrélation entre A et B : {data['a'].corr(data['b']):.2f}")
print(f"Corrélation lorsque flag est vrai : {data[data['flag']]['a'].corr(data[data['flag']]['b']):.2f}")
Résultats :
- Jeu de données complet : corr ≈ 0,00
- Sous-ensemble filtré : corr ≈ -0,34
La visualisation en nuage de points montre comment l’élimination des points non survivants (bleus) déplace la tendance vers le bas.
sns.scatterplot(data=data, x='a', y='b', hue='flag', palette={True: 'red', False: 'blue'}, alpha=0.5)
sns.regplot(data=data, x='a', y='b', scatter=False, color='black')
plt.show()
Après filtrage, le graphique lmplot affiche une pente négative : le quadrant supérieur droit devient vide, rompant l’équilibre.
Scénario réaliste : distribution normale
On utilise maintenant np.random.normal : A ~ N(50,5), B ~ N(30,5). La collision est probabiliste : on normalise les valeurs, calcule la probabilité de sélection comme max(a_norm, b_norm)*1,5, on clippe entre [0,1], puis on attribue le marqueur selon un tirage aléatoire.
a = np.random.normal(loc=50, scale=5, size=NUMBER_OF_VALUES)
b = np.random.normal(loc=30, scale=5, size=NUMBER_OF_VALUES)
normal_data = pd.DataFrame({'a': a, 'b': b})
a_norm = (normal_data['a'] - normal_data['a'].min()) / (normal_data['a'].max() - normal_data['a'].min() + 1e-6)
b_norm = (normal_data['b'] - normal_data['b'].min()) / (normal_data['b'].max() - normal_data['b'].min() + 1e-6)
selection_prob = np.maximum(a_norm, b_norm) * 1.5
selection_prob = np.clip(selection_prob, 0, 1)
normal_data['flag'] = np.random.random(len(normal_data)) < selection_prob
print(f"Corrélation dans le jeu complet : {normal_data['a'].corr(normal_data['b']):.2f}")
print(f"Corrélation lorsque flag est vrai : {normal_data[normal_data['flag']]['a'].corr(normal_data[normal_data['flag']]['b']):.2f}")
Résultats :
- Jeu de données complet : corr ≈ 0,03
- Sous-ensemble filtré : corr ≈ -0,09
L’effet est plus faible mais reste significatif dans les tests A/B, les études terrain ou les pipelines d’apprentissage automatique.
Comment éviter le biais de collision dans l’analyse
- Dessinez des DAGs : utilisez des graphes acycliques orientés pour identifier les collisions avant toute analyse.
- Évitez le filtrage basé sur le résultat : analysez la population complète ou appliquez un poids inverse de probabilité de censure (IPCW).
- Comparez les corrélations avant et après stratification : observez les écarts entre groupes.
- Utilisez des variables instrumentales : pour l’inférence causale quand un biais est suspecté.
- Exploitez les réseaux bayésiens : modélisez explicitement les dépendances et relations conditionnelles.
Points clés
- Le biais de collision survient lorsqu’on conditionne sur une cause commune, créant des corrélations négatives artificielles.
- La simulation avec des données uniformes donne une corrélation ≈ -0,34 ; avec des données normales, ≈ -0,09 — l’effet dépend de la structure des données.
- Ce phénomène est lié au biais de survie, au paradoxe de Berkson et au biais de sélection.
- Dessinez toujours un DAG avant de filtrer les données.
- En apprentissage automatique : les données filtrées produisent des modèles biaisés, entraînant une sous- ou surestimation de l’importance des caractéristiques.
— Editorial Team
Aucun commentaire pour le moment.