Utiliser winsorize() de scipy.stats pour remplacer les valeurs aberrantes

Les valeurs extrêmes ou aberrantes peuvent avoir un impact important sur les modèles statistiques et les algorithmes de machine learning. La fonction winsorize() du module scipy.stats.mstats permet de limiter l’influence de ces valeurs sans les supprimer, en les ramenant à des bornes prédéfinies. Ce tutoriel vous montre comment utiliser efficacement cette fonction pour nettoyer vos données.


Qu’est-ce que la Winsorization ?

La Winsorization consiste à limiter les valeurs d’une distribution à des bornes spécifiques définies par des quantiles. Par exemple, on peut décider que toutes les valeurs situées au-dessus du 95e percentile seront remplacées par la valeur du 95e percentile, et que toutes celles sous le 5e percentile seront remplacées par celle du 5e percentile. Cela permet de contrôler les effets des extrêmes sans altérer la structure du jeu de données.


Fonction winsorize() de scipy

La fonction winsorize() se trouve dans scipy.stats.mstats, et peut être utilisée sur des tableaux numpy ou pandas. Elle retourne un tableau dans lequel les valeurs extrêmes ont été remplacées selon les paramètres spécifiés.

Syntaxe

winsorize(data, limits)

Installation

Si vous n’avez pas encore installé scipy, faites-le via pip :

pip install scipy

Exemple simple avec numpy

from scipy.stats.mstats import winsorize
import numpy as np

# Créons un tableau contenant des valeurs extrêmes
data = np.array([10, 12, 13, 14, 15, 16, 17, 100, 120])

# Appliquons la Winsorization avec 10% à chaque extrémité
winsorized_data = winsorize(data, limits=[0.1, 0.1])

print("Données originales :", data)
print("Données après winsorize :", winsorized_data)

Explication

Dans cet exemple, la fonction a remplacé :


Utilisation avec pandas dans un DataFrame

import pandas as pd
from scipy.stats.mstats import winsorize

# Créons un DataFrame
df = pd.DataFrame({
    'revenu': [1500, 1600, 1650, 1700, 1750, 1800, 30000]
})

# Appliquer winsorize à la colonne 'revenu'
winsorized = winsorize(df['revenu'], limits=[0.1, 0.1])

# Ajouter une nouvelle colonne avec les données corrigées
df['revenu_winsorized'] = winsorized

print(df)

Résultat attendu

Les extrémités du tableau ont été écrêtées : la valeur 30000 (outlier) a été remplacée par une valeur proche du 90e percentile.


Visualisation de l’effet de winsorize()

import matplotlib.pyplot as plt

plt.figure(figsize=(10,5))
plt.subplot(1, 2, 1)
plt.hist(df['revenu'], bins=10, color='gray')
plt.title("Avant Winsorization")

plt.subplot(1, 2, 2)
plt.hist(df['revenu_winsorized'], bins=10, color='green')
plt.title("Après Winsorization")

plt.tight_layout()
plt.show()

Ce graphique permet d’observer comment les valeurs extrêmes sont ramenées dans des limites raisonnables tout en conservant la distribution globale.


Choisir les bons seuils de Winsorization

Le choix de limits dépend du contexte :

Astuce

Vous pouvez analyser les quantiles via pandas avant d’appliquer winsorize :

df['revenu'].quantile([0.01, 0.05, 0.95, 0.99])

Avantages de winsorize()


Limites


Conclusion

winsorize() de scipy.stats.mstats est un outil précieux pour les data scientists qui souhaitent nettoyer leurs données tout en conservant l’intégrité du jeu. Il est particulièrement utile dans les contextes où la suppression de données est risquée ou coûteuse. Comme pour tout traitement des données, une bonne compréhension du domaine et une analyse exploratoire préalable sont essentielles pour choisir les bons paramètres de Winsorization.