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 n’importe quelle statistique en rééchantillonnant de façon 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 rendant possible l’analyse de statistiques complexes sans s’appuyer sur des formules mathématiques ou des hypothèses distributionnelles.
L’idée clé derrière le bootstrap est d’une simplicité élégante : votre échantillon est votre meilleure estimation de la population. En rééchantillonnant à partir de votre échantillon (avec remise), vous simulez ce qui se passerait si vous pouviez échantillonner de façon répétée à partir de la population. Cette approche est particulièrement précieuse pour l’écart type, où les formules traditionnelles d’intervalle de confiance supposent la normalité — une hypothèse qui échoue souvent en pratique.
Le bootstrap est devenu essentiel en science des données moderne parce qu’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. Quand cette hypothèse échoue (ce qui est courant), ces intervalles peuvent être très inexacts. Le bootstrap fournit une alternative sans hypothèse distributionnelle.
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 avec petits échantillons : Souvent plus précis que les méthodes paramétriques avec n < 30
- Gère les statistiques complexes : La même approche fonctionne pour l’écart type tronqué, le MAD ou des mesures de variabilité personnalisées
- Aperçu visuel : La distribution bootstrap vous montre ce qui se passe, pas seulement les 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 plusieurs fois
Analyser la distribution
Pourquoi avec remise?
Combien d’échantillons bootstrap? B = 1 000 suffit souvent pour des estimations grossières et des tests d’hypothèses. 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’intervalle 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 : prenez directement les percentiles de la distribution bootstrap.
IC par percentile
Pour 10 000 échantillons bootstrap, ce sont les 250e et 9 750e valeurs ordonnées. Simple mais peut être biaisé quand la distribution bootstrap est asymétrique.
2. Bootstrap de base (pivotal)
Utilise la relation entre la statistique d’échantillon et les statistiques bootstrap :
IC bootstrap de base
Où θ̂ est l’écart type de l’échantillon original. Cela « reflète » l’intervalle de percentile autour de l’estimation de l’échantillon.
3. BCa (corrigé du biais et accéléré)
La norme de référence pour la précision. Le BCa ajuste à la fois le biais dans la distribution bootstrap et l’accélération (comment l’erreur type change avec la valeur du paramètre). Plus complexe à calculer mais fournit des intervalles précis au second ordre.
| Méthode | Avantages | Inconvénients |
|---|---|---|
| Percentile | 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 | Coûteux en calcul |
Exemple résolu : Données non normales
Considérez 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 (quelques 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é élevé), reflétant la nature asymétrique à droite des données. L’IC chi-carré ne capture pas cette asymétrie.
Implémentation en Python
Implémentation bootstrap complète 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}]")