Le bootstrap : la révolution statistique de l’ère informatique
Le rééchantillonnage bootstrap est une technique statistique puissante qui estime la distribution d’échantillonnage de toute statistique en rééchantillonnant de manière répétée à partir de vos données observées. Introduit par Bradley Efron en 1979, il a révolutionné l’inférence statistique en permettant l’analyse de statistiques complexes sans formules mathématiques ni hypothèses distributionnelles.
L’intuition fondamentale du bootstrap est d’une élégante simplicité : votre échantillon est la meilleure estimation de la population dont vous disposez. En rééchantillonnant à partir de votre échantillon (avec remise), vous simulez ce qui se produirait si vous pouviez échantillonner la population de manière répétée. Cette approche est particulièrement précieuse pour l’écart type, dont les formules traditionnelles d’intervalle de confiance supposent la normalité — une hypothèse souvent mise en défaut en pratique.
Le bootstrap est devenu incontournable en science des données moderne car il fonctionne avec n’importe quelle statistique (médiane, corrélation, coefficients de régression, poids de réseaux neuronaux) et ne fait aucune hypothèse sur la distribution sous-jacente de vos données.
Pourquoi le bootstrap pour l’écart type ?
Les intervalles de confiance traditionnels pour l’écart type supposent que vos données proviennent d’une distribution normale. Lorsque cette hypothèse est violée (ce qui est fréquent), ces intervalles peuvent être très imprécis. Le bootstrap offre une alternative non paramétrique.
Quand les méthodes traditionnelles échouent
Avantages clés du bootstrap pour l’écart type :
- Aucune hypothèse distributionnelle : Fonctionne aussi bien avec des données normales, asymétriques ou à queues lourdes
- Performance en petits échantillons : Souvent plus précis que les méthodes paramétriques pour n < 30
- Statistiques complexes : La même approche s’applique à l’écart type tronqué, au MAD ou à toute mesure de variabilité personnalisée
- Aperçu visuel : La distribution bootstrap montre ce qui se passe, pas seulement des chiffres finaux
La procédure bootstrap
L’algorithme bootstrap est remarquablement simple. À partir de votre échantillon original de n observations :
Tirer un échantillon bootstrap
Calculer la statistique
Répéter de nombreuses fois
Analyser la distribution
Pourquoi avec remise ?
Combien d’échantillons bootstrap ? B = 1 000 suffit souvent pour des estimations approximatives et des tests d’hypothèse. Pour les intervalles de confiance, B = 10 000 fournit des percentiles stables. Pour des intervalles BCa de qualité publication, B = 15 000+ est recommandé.
Méthodes d’intervalles de confiance bootstrap
Plusieurs méthodes existent pour construire des intervalles de confiance à partir d’échantillons bootstrap, chacune avec ses compromis :
1. Méthode des percentiles (la plus simple)
L’approche la plus intuitive : prendre directement les percentiles de la distribution bootstrap.
IC par percentiles
Pour 10 000 échantillons bootstrap, il s’agit des 250e et 9 750e valeurs ordonnées. Simple mais potentiellement biaisé lorsque la distribution bootstrap est asymétrique.
2. Bootstrap de base (pivotal)
Utilise la relation entre la statistique de l’échantillon et les statistiques bootstrap :
IC bootstrap de base
Où θ̂ est l’écart type de l’échantillon original. Cette méthode « réfléchit » l’intervalle percentile autour de l’estimation de l’échantillon.
3. BCa (corrigé du biais et accéléré)
La référence en matière de précision. Le BCa corrige à la fois le biais de la distribution bootstrap et l’accélération (comment l’erreur type varie avec la valeur du paramètre). Plus complexe à calculer mais fournit des intervalles de précision au second ordre.
| Méthode | Avantages | Inconvénients |
|---|---|---|
| Percentiles | Simple, intuitif | Peut être biaisé avec des données asymétriques |
| De base | Intervalles symétriques | Peut produire des valeurs négatives |
| BCa | Le plus précis, respecte les transformations | Intensif en calcul |
Exemple détaillé : données non normales
Considérons 15 mesures de temps de réponse (en ms) : 245, 312, 287, 456, 234, 298, 267, 523, 289, 301, 278, 645, 256, 289, 312. Ces données sont asymétriques à droite (certaines réponses très lentes).
Calculer l’écart type de l’échantillon
Générer les échantillons bootstrap
Calculer les écarts types bootstrap
Trouver les percentiles
Former l’IC à 95 %
L’IC bootstrap est asymétrique (plus large du côté des valeurs élevées), reflétant la nature asymétrique à droite des données. L’IC chi-deux ne capture pas cette asymétrie.
Implémentation en Python
Implémentation complète du bootstrap avec plusieurs méthodes d’IC :
import numpy as np
from scipy import stats
def bootstrap_sd_ci(data, n_bootstrap=10000, ci=0.95, method='percentile'):
"""
Bootstrap confidence interval for standard deviation.
Parameters:
-----------
data : array-like - Original sample
n_bootstrap : int - Number of bootstrap samples
ci : float - Confidence level (e.g., 0.95)
method : str - 'percentile', 'basic', or 'bca'
Returns:
--------
tuple : (lower_bound, upper_bound, bootstrap_sds)
"""
data = np.array(data)
n = len(data)
original_sd = np.std(data, ddof=1)
# Generate bootstrap samples and calculate SDs
bootstrap_sds = np.array([
np.std(np.random.choice(data, size=n, replace=True), ddof=1)
for _ in range(n_bootstrap)
])
alpha = 1 - ci
if method == 'percentile':
lower = np.percentile(bootstrap_sds, 100 * alpha/2)
upper = np.percentile(bootstrap_sds, 100 * (1 - alpha/2))
elif method == 'basic':
lower = 2*original_sd - np.percentile(bootstrap_sds, 100*(1-alpha/2))
upper = 2*original_sd - np.percentile(bootstrap_sds, 100*alpha/2)
elif method == 'bca':
# Bias correction
prop_less = np.mean(bootstrap_sds < original_sd)
z0 = stats.norm.ppf(prop_less)
# Acceleration (jackknife estimate)
jackknife_sds = np.array([
np.std(np.delete(data, i), ddof=1) for i in range(n)
])
jack_mean = jackknife_sds.mean()
a = np.sum((jack_mean - jackknife_sds)**3) / \
(6 * np.sum((jack_mean - jackknife_sds)**2)**1.5)
# Adjusted percentiles
z_alpha = stats.norm.ppf([alpha/2, 1-alpha/2])
adj_percentiles = stats.norm.cdf(
z0 + (z0 + z_alpha) / (1 - a*(z0 + z_alpha))
) * 100
lower = np.percentile(bootstrap_sds, adj_percentiles[0])
upper = np.percentile(bootstrap_sds, adj_percentiles[1])
return lower, upper, bootstrap_sds
# Example usage
response_times = [245, 312, 287, 456, 234, 298, 267, 523, 289, 301, 278, 645, 256, 289, 312]
for method in ['percentile', 'basic', 'bca']:
lower, upper, _ = bootstrap_sd_ci(response_times, method=method)
print(f"{method.upper():12s} 95% CI: [{lower:.1f}, {upper:.1f}]")