Sous-échantillonnage (Undersampling) des classes majoritaires avec RandomUnderSampler de imblearn

Le sous-échantillonnage (undersampling) des classes majoritaires avec RandomUnderSampler de la bibliothèque imblearn est une méthode permettant de rééquilibrer un dataset en réduisant le nombre d’exemples dans la classe majoritaire. Ce processus consiste à sélectionner aléatoirement une sous-partie des exemples de la classe majoritaire afin de la rendre plus petite et ainsi équilibrer la distribution des classes.

Fonctions :

  • RandomUnderSampler()

    Le RandomUnderSampler est utilisé pour effectuer un sous-échantillonnage aléatoire des classes majoritaires dans un jeu de données déséquilibré. L'objectif est de réduire le nombre d'exemples dans la classe majoritaire pour équilibrer la distribution des classes, ce qui peut aider à améliorer la performance du modèle en réduisant le biais vers la classe majoritaire.

    Importation :

    from imblearn.under_sampling import RandomUnderSampler

    Attributs :

    Paramètre Description
    sampling_strategy Stratégie de sous-échantillonnage. Peut être 'auto' pour équilibrer les classes, ou un nombre pour spécifier un ratio.
    random_state Contrôle la reproductibilité de l'échantillonnage aléatoire. Par défaut, None.
    replacement Détermine si l'échantillonnage est effectué avec ou sans remplacement. Par défaut, False.

    Exemple de code :

    from sklearn.datasets import make_classification
    from imblearn.under_sampling import RandomUnderSampler
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    # 1. Génération d'un jeu de données déséquilibré
    X, y = make_classification(n_samples=1000, n_features=2, n_redundant=0,
                               n_clusters_per_class=1, weights=[0.9, 0.1],
                               random_state=42)
    
    # Affichage de la distribution initiale
    print("Distribution avant undersampling :")
    print(pd.Series(y).value_counts())
    
    # 2. Application du RandomUnderSampler
    rus = RandomUnderSampler(random_state=42)
    X_resampled, y_resampled = rus.fit_resample(X, y)
    
    # Affichage de la nouvelle distribution
    print("\nDistribution après undersampling :")
    print(pd.Series(y_resampled).value_counts())
    
    # 3. Visualisation du résultat
    sns.set(style="whitegrid")
    fig, axes = plt.subplots(1, 2, figsize=(12, 5))
    
    # Avant undersampling
    sns.scatterplot(x=X[:, 0], y=X[:, 1], hue=y, palette='Set1', ax=axes[0])
    axes[0].set_title('Avant undersampling')
    
    # Après undersampling
    sns.scatterplot(x=X_resampled[:, 0], y=X_resampled[:, 1], hue=y_resampled, palette='Set1', ax=axes[1])
    axes[1].set_title('Après undersampling')
    
    plt.tight_layout()
    plt.show()
    Résultat du code

    Explication du code :

    Importation des bibliothèques
    from sklearn.datasets import make_classification
    from imblearn.under_sampling import RandomUnderSampler
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns

    Cette section importe les bibliothèques nécessaires :

    • make_classification est une fonction de sklearn qui génère un jeu de données artificiel pour un problème de classification.
    • RandomUnderSampler est une classe de la bibliothèque imblearn utilisée pour rééquilibrer les classes en réduisant la taille de la classe majoritaire.
    • pandas (pd) est utilisée pour manipuler les données sous forme de tableau.
    • matplotlib.pyplot et seaborn permettent de visualiser les données avec des graphiques.
    Génération d’un jeu de données déséquilibré
    X, y = make_classification(n_samples=1000, n_features=2, n_redundant=0,
            n_clusters_per_class=1, weights=[0.9, 0.1],
            random_state=42)

    Cette ligne génère un jeu de données composé de 1000 échantillons. Il contient 2 variables explicatives (n_features=2) sans variable redondante (n_redundant=0), et avec un fort déséquilibre de classes : 90 % des données appartiennent à la classe 0 et 10 % à la classe 1, comme défini par weights=[0.9, 0.1].

    Affichage de la distribution initiale des classes
    print("Distribution avant undersampling :")
    print(pd.Series(y).value_counts())

    Ces lignes permettent d'afficher combien d'exemples il y a dans chaque classe avant l'application du sous-échantillonnage. Cela permet de vérifier le déséquilibre du jeu de données généré.

    Application du sous-échantillonnage
    rus = RandomUnderSampler(random_state=42)
    X_resampled, y_resampled = rus.fit_resample(X, y)

    Un objet RandomUnderSampler est instancié, puis appliqué au jeu de données d’origine à l’aide de la méthode fit_resample(). Cette méthode sous-échantillonne la classe majoritaire de manière aléatoire afin de créer un nouveau jeu de données équilibré, en supprimant des échantillons de la classe majoritaire.

    Affichage de la distribution après rééchantillonnage
    print("\nDistribution après undersampling :")
    print(pd.Series(y_resampled).value_counts())

    Cette ligne permet de vérifier la nouvelle répartition des classes après sous-échantillonnage. On observe que les deux classes ont désormais le même nombre d'exemples, ce qui supprime le biais d’origine.

    Visualisation des données avant et après undersampling
    sns.set(style="whitegrid")
    fig, axes = plt.subplots(1, 2, figsize=(12, 5))

    Le style graphique est défini à l’aide de Seaborn pour une meilleure lisibilité. Une figure avec deux sous-graphes est ensuite créée pour comparer visuellement les jeux de données avant et après rééchantillonnage.

    sns.scatterplot(x=X[:, 0], y=X[:, 1], hue=y, palette='Set1', ax=axes[0])
    axes[0].set_title('Avant undersampling')

    Ce graphique représente les données d’origine. Les points sont colorés selon leur classe. On observe que la classe majoritaire est nettement plus représentée.

    sns.scatterplot(x=X_resampled[:, 0], y=X_resampled[:, 1], hue=y_resampled, palette='Set1', ax=axes[1])
    axes[1].set_title('Après undersampling')

    Ce second graphique représente les données après rééchantillonnage. Les deux classes sont désormais représentées de manière équilibrée. Cela permet de visualiser l’effet direct de l’undersampling.

    plt.tight_layout()
    plt.show()

    Ces lignes ajustent l’espacement entre les graphiques pour éviter tout chevauchement et affichent la figure finale à l’écran.