Mise à l'échelle du paramètre de régularisation pour les SVM

Beginner

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

Introduction

Ce laboratoire démontre l'effet de la mise à l'échelle du paramètre de régularisation lors de l'utilisation de Machines à Vecteurs de Support (SVM) pour la classification. En classification SVM, nous sommes intéressés par la minimisation du risque pour l'équation :

C \sum_{i=1, n} \mathcal{L} (f(x_i), y_i) + \Omega (w)

où :

  • C est utilisé pour définir la quantité de régularisation
  • L est une fonction de perte de nos échantillons et de nos paramètres de modèle.
  • Ω est une fonction de pénalité de nos paramètres de modèle

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 la pratique.

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 limites 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ésoudrons rapidement le problème pour vous.

Importation des bibliothèques et génération d'un ensemble de données synthétique

Nous commençons par importer les bibliothèques nécessaires et en générer un ensemble de données synthétique approprié pour la régularisation L1 et L2.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.svm import LinearSVC
from sklearn.model_selection import validation_curve, ShuffleSplit

n_samples, n_features = 100, 300
X, y = make_classification(n_samples=n_samples, n_features=n_features, n_informative=5, random_state=1)

rng = np.random.RandomState(1)
y = np.sign(0.5 - rng.rand(n_samples))
X = rng.randn(n_samples, n_features // 5) + y[:, np.newaxis]
X += 5 * rng.randn(n_samples, n_features // 5)

Cas de la pénalité L1

Dans le cas de la pénalité L1, la théorie stipule que la cohérence du modèle, en termes de recherche de l'ensemble correct de paramètres non nuls ainsi que de leurs signes, peut être atteinte en mettant à l'échelle C. Nous démontrons cet effet en utilisant un ensemble de données synthétique qui est sparse, ce qui signifie qu'un seul nombre restreint de fonctionnalités sera informative et utile pour le modèle.

model_l1 = LinearSVC(penalty="l1", loss="squared_hinge", dual=False, tol=1e-3)

Cs = np.logspace(-2.3, -1.3, 10)
train_sizes = np.linspace(0.3, 0.7, 3)
labels = [f"fraction: {train_size}" for train_size in train_sizes]

results = {"C": Cs}
for label, train_size in zip(labels, train_sizes):
    cv = ShuffleSplit(train_size=train_size, test_size=0.3, n_splits=50, random_state=1)
    train_scores, test_scores = validation_curve(
        model_l1, X, y, param_name="C", param_range=Cs, cv=cv
    )
    results[label] = test_scores.mean(axis=1)
results = pd.DataFrame(results)

fig, axes = plt.subplots(nrows=1, ncols=2, sharey=True, figsize=(12, 6))

## trace les résultats sans mettre à l'échelle C
results.plot(x="C", ax=axes[0], logx=True)
axes[0].set_ylabel("CV score")
axes[0].set_title("Pas de mise à l'échelle")

## trace les résultats en mettant à l'échelle C
for train_size_idx, label in enumerate(labels):
    results_scaled = results[[label]].assign(
        C_scaled=Cs * float(n_samples * train_sizes[train_size_idx])
    )
    results_scaled.plot(x="C_scaled", ax=axes[1], logx=True, label=label)
axes[1].set_title("Mise à l'échelle de C par 1 / n_samples")

_ = fig.suptitle("Effet de la mise à l'échelle de C avec une pénalité L1")

Cas de la pénalité L2

Nous pouvons répéter une expérience similaire avec la pénalité l2. Dans ce cas, la théorie stipule que pour atteindre la cohérence de la prédiction, le paramètre de pénalité devrait être maintenu constant à mesure que le nombre d'échantillons augmente.

model_l2 = LinearSVC(penalty="l2", loss="squared_hinge", dual=True)
Cs = np.logspace(-4.5, -2, 10)

labels = [f"fraction: {train_size}" for train_size in train_sizes]
results = {"C": Cs}
for label, train_size in zip(labels, train_sizes):
    cv = ShuffleSplit(train_size=train_size, test_size=0.3, n_splits=50, random_state=1)
    train_scores, test_scores = validation_curve(
        model_l2, X, y, param_name="C", param_range=Cs, cv=cv
    )
    results[label] = test_scores.mean(axis=1)
results = pd.DataFrame(results)

fig, axes = plt.subplots(nrows=1, ncols=2, sharey=True, figsize=(12, 6))

## trace les résultats sans mettre à l'échelle C
results.plot(x="C", ax=axes[0], logx=True)
axes[0].set_ylabel("CV score")
axes[0].set_title("Pas de mise à l'échelle")

## trace les résultats en mettant à l'échelle C
for train_size_idx, label in enumerate(labels):
    results_scaled = results[[label]].assign(
        C_scaled=Cs * float(n_samples * train_sizes[train_size_idx])
    )
    results_scaled.plot(x="C_scaled", ax=axes[1], logx=True, label=label)
axes[1].set_title("Mise à l'échelle de C par 1 / n_samples")

_ = fig.suptitle("Effet de la mise à l'échelle de C avec une pénalité L2")

Résumé

Ce laboratoire a démontré l'effet de la mise à l'échelle du paramètre de régularisation dans les SVM pour les deux pénalités L1 et L2. Pour la pénalité L1, nous avons observé que l'erreur de validation croisée est la mieux corrélée avec l'erreur de test lorsque l'on met à l'échelle C avec le nombre d'échantillons. Pour la pénalité L2, le meilleur résultat provient du cas où C n'est pas mis à l'échelle.