Discrétisation des fonctionnalités pour la classification

Machine LearningMachine LearningBeginner
Pratiquer maintenant

This tutorial is from open-source community. Access the source code

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

En apprentissage automatique, la discrétisation des fonctionnalités est une méthode permettant de réduire le nombre de variables continues dans un ensemble de données en créant des boîtes ou des intervalles pour les représenter. Cette méthode peut s'avérer utile dans les cas où le nombre de variables continues est important et où l'algorithme doit être simplifié pour faciliter l'analyse. Dans ce laboratoire, nous allons démontrer la discrétisation des fonctionnalités sur des ensembles de données de classification synthétiques.

Conseils sur la machine virtuelle

Une fois le démarrage de la machine virtuelle terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Carnet de notes pour accéder au carnet Jupyter pour pratiquer.

Parfois, vous devrez peut-être attendre quelques secondes pour que le carnet Jupyter ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limitations du carnet Jupyter.

Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez votre feedback après la session et nous réglerons rapidement le problème pour vous.

Importation des bibliothèques

Dans cette étape, nous allons importer les bibliothèques requises pour le laboratoire. Nous utiliserons la bibliothèque scikit-learn pour les tâches d'apprentissage automatique, numpy pour les opérations mathématiques et matplotlib pour la visualisation des données.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_moons, make_circles, make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import KBinsDiscretizer
from sklearn.svm import SVC, LinearSVC
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.utils._testing import ignore_warnings
from sklearn.exceptions import ConvergenceWarning

Préparer les données

Dans cette étape, nous allons préparer les ensembles de données de classification synthétiques pour la discrétisation des fonctionnalités. Nous utiliserons la bibliothèque scikit-learn pour générer trois ensembles de données différents : des lunules, des cercles concentriques et des données linéairement séparables.

h = 0.02  ## pas dans la grille
n_samples = 100
datasets = [
    make_moons(n_samples=n_samples, noise=0.2, random_state=0),
    make_circles(n_samples=n_samples, noise=0.2, factor=0.5, random_state=1),
    make_classification(
        n_samples=n_samples,
        n_features=2,
        n_redundant=0,
        n_informative=2,
        random_state=2,
        n_clusters_per_class=1,
    ),
]

Définir les classifieurs et les paramètres

Dans cette étape, nous allons définir les classifieurs et les paramètres à utiliser dans le processus de discrétisation des fonctionnalités. Nous allons créer une liste de classifieurs qui inclut la régression logistique, la machine à vecteurs de support linéaire (SVM), le classifieur à gradient boosting et la SVM avec un noyau de fonction de base radiale. Nous allons également définir un ensemble de paramètres pour chaque classifieur à utiliser dans l'algorithme GridSearchCV.

## liste de (estimateur, param_grid), où param_grid est utilisé dans GridSearchCV
## Les espaces de paramètres dans cet exemple sont limités à une bande étroite pour réduire
## son temps d'exécution. Dans un cas d'utilisation réel, un espace de recherche plus large pour les algorithmes
## devrait être utilisé.
classifiers = [
    (
        make_pipeline(StandardScaler(), LogisticRegression(random_state=0)),
        {"logisticregression__C": np.logspace(-1, 1, 3)},
    ),
    (
        make_pipeline(StandardScaler(), LinearSVC(random_state=0, dual="auto")),
        {"linearsvc__C": np.logspace(-1, 1, 3)},
    ),
    (
        make_pipeline(
            StandardScaler(),
            KBinsDiscretizer(encode="onehot"),
            LogisticRegression(random_state=0),
        ),
        {
            "kbinsdiscretizer__n_bins": np.arange(5, 8),
            "logisticregression__C": np.logspace(-1, 1, 3),
        },
    ),
    (
        make_pipeline(
            StandardScaler(),
            KBinsDiscretizer(encode="onehot"),
            LinearSVC(random_state=0, dual="auto"),
        ),
        {
            "kbinsdiscretizer__n_bins": np.arange(5, 8),
            "linearsvc__C": np.logspace(-1, 1, 3),
        },
    ),
    (
        make_pipeline(
            StandardScaler(), GradientBoostingClassifier(n_estimators=5, random_state=0)
        ),
        {"gradientboostingclassifier__learning_rate": np.logspace(-2, 0, 5)},
    ),
    (
        make_pipeline(StandardScaler(), SVC(random_state=0)),
        {"svc__C": np.logspace(-1, 1, 3)},
    ),
]

names = [get_name(e).replace("StandardScaler + ", "") for e, _ in classifiers]

Visualiser les données

Dans cette étape, nous allons visualiser les ensembles de données de classification synthétiques avant la discrétisation des fonctionnalités. Nous allons tracer les points d'entraînement et de test pour chaque ensemble de données.

fig, axes = plt.subplots(
    nrows=len(datasets), ncols=len(classifiers) + 1, figsize=(21, 9)
)

cm_piyg = plt.cm.PiYG
cm_bright = ListedColormap(["#b30065", "#178000"])

## itérer sur les ensembles de données
for ds_cnt, (X, y) in enumerate(datasets):
    print(f"\ndataset {ds_cnt}\n---------")

    ## diviser en partie d'entraînement et de test
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.5, random_state=42
    )

    ## créer la grille pour les couleurs d'arrière-plan
    x_min, x_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5
    y_min, y_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

    ## tracer d'abord l'ensemble de données
    ax = axes[ds_cnt, 0]
    if ds_cnt == 0:
        ax.set_title("Données d'entrée")
    ## tracer les points d'entraînement
    ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap=cm_bright, edgecolors="k")
    ## et les points de test
    ax.scatter(
        X_test[:, 0], X_test[:, 1], c=y_test, cmap=cm_bright, alpha=0.6, edgecolors="k"
    )
    ax.set_xlim(xx.min(), xx.max())
    ax.set_ylim(yy.min(), yy.max())
    ax.set_xticks(())
    ax.set_yticks(())

Implémenter la discrétisation des fonctionnalités

Dans cette étape, nous allons implémenter la discrétisation des fonctionnalités sur les ensembles de données à l'aide de la classe KBinsDiscretizer de scikit-learn. Cela discrétisera les fonctionnalités en créant un ensemble de classes et en encodant ensuite en one-hot les valeurs discrètes. Nous allons ensuite ajuster les données à un classifieur linéaire et évaluer les performances.

## itérer sur les classifieurs
for est_idx, (name, (estimator, param_grid)) in enumerate(zip(names, classifiers)):
    ax = axes[ds_cnt, est_idx + 1]

    clf = GridSearchCV(estimator=estimator, param_grid=param_grid)
    with ignore_warnings(category=ConvergenceWarning):
        clf.fit(X_train, y_train)
    score = clf.score(X_test, y_test)
    print(f"{name}: {score:.2f}")

    ## tracer la frontière de décision. Pour cela, nous allons attribuer une couleur à chaque
    ## point dans la grille [x_min, x_max]*[y_min, y_max].
    if hasattr(clf, "decision_function"):
        Z = clf.decision_function(np.column_stack([xx.ravel(), yy.ravel()]))
    else:
        Z = clf.predict_proba(np.column_stack([xx.ravel(), yy.ravel()]))[:, 1]

    ## mettre le résultat dans un graphique en couleur
    Z = Z.reshape(xx.shape)
    ax.contourf(xx, yy, Z, cmap=cm_piyg, alpha=0.8)

    ## tracer les points d'entraînement
    ax.scatter(
        X_train[:, 0], X_train[:, 1], c=y_train, cmap=cm_bright, edgecolors="k"
    )
    ## et les points de test
    ax.scatter(
        X_test[:, 0],
        X_test[:, 1],
        c=y_test,
        cmap=cm_bright,
        edgecolors="k",
        alpha=0.6,
    )
    ax.set_xlim(xx.min(), xx.max())
    ax.set_ylim(yy.min(), yy.max())
    ax.set_xticks(())
    ax.set_yticks(())

    if ds_cnt == 0:
        ax.set_title(name.replace(" + ", "\n"))
    ax.text(
        0.95,
        0.06,
        (f"{score:.2f}").lstrip("0"),
        size=15,
        bbox=dict(boxstyle="round", alpha=0.8, facecolor="white"),
        transform=ax.transAxes,
        horizontalalignment="right",
    )

Visualiser les résultats

Dans cette étape, nous allons visualiser les résultats du processus de discrétisation des fonctionnalités. Nous allons tracer la précision de classification sur l'ensemble de test pour chaque classifieur et ensemble de données.

plt.tight_layout()

## Ajouter des titres supérieurs au-dessus de la figure
plt.subplots_adjust(top=0.90)
suptitles = [
    "Classifieurs linéaires",
    "Discrétisation des fonctionnalités et classifieurs linéaires",
    "Classifieurs non-linéaires",
]
for i, suptitle in zip([1, 3, 5], suptitles):
    ax = axes[0, i]
    ax.text(
        1.05,
        1.25,
        suptitle,
        transform=ax.transAxes,
        horizontalalignment="center",
        size="x-large",
    )
plt.show()

Sommaire

Dans ce laboratoire, nous avons démontré la discrétisation des fonctionnalités sur des ensembles de données de classification synthétiques à l'aide de scikit-learn. Nous avons préparé les données, défini des classifieurs et des paramètres, implémenté la discrétisation des fonctionnalités et visualisé les résultats. Cette technique de prétraitement peut être utile pour réduire la complexité d'un ensemble de données et améliorer les performances des classifieurs linéaires. Cependant, elle devrait être utilisée avec prudence et en conjonction avec d'autres techniques pour éviter le surapprentissage.