Масштабирование параметра регуляризации для SVM

Beginner

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

Введение

Этот практикум демонстрирует влияние изменения параметра регуляризации при использовании методов опорных векторов (Support Vector Machines, SVM) для классификации. В классификации с использованием SVM мы заинтересованы в минимизации риска для уравнения:

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

где:

  • C используется для настройки величины регуляризации
  • L - функция потерь для наших выборок и параметров модели
  • Ω - штрафная функция для параметров модели

Советы по работе с ВМ

После запуска виртуальной машины (VM) кликните в левом верхнем углу, чтобы переключиться на вкладку Notebook и получить доступ к Jupyter Notebook для практики.

Иногда может потребоваться подождать несколько секунд, пока Jupyter Notebook полностью загрузится. Валидация операций не может быть автоматизирована из-за ограничений Jupyter Notebook.

Если вы столкнетесь с проблемами во время обучения, не стесняйтесь обращаться к Labby. Оставьте отзыв после занятия, и мы оперативно решим проблему для вас.

Импорт библиотек и генерация синтетического набора данных

Начнем с импорта необходимых библиотек и генерации синтетического набора данных, подходящего для L1 и 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)

Случай L1-штрафа

В случае L1-штрафа теория утверждает, что согласованность модели, в том смысле, чтобы найти правильный набор ненулевых параметров и их знаки, может быть достигнута путём изменения масштаба C. Мы демонстрируем это влияние, используя синтетический набор данных, который является разреженным, то есть только несколько признаков будут информативными и полезными для модели.

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))

## plot results without scaling C
results.plot(x="C", ax=axes[0], logx=True)
axes[0].set_ylabel("CV score")
axes[0].set_title("No scaling")

## plot results by scaling 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("Scaling C by 1 / n_samples")

_ = fig.suptitle("Effect of scaling C with L1 penalty")

Случай L2-штрафа

Мы можем повторить аналогичный эксперимент с l2-штрафом. В этом случае теория утверждает, что для достижения согласованности предсказаний параметр штрафа должен оставаться постоянным при увеличении числа выборок.

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))

## plot results without scaling C
results.plot(x="C", ax=axes[0], logx=True)
axes[0].set_ylabel("CV score")
axes[0].set_title("No scaling")

## plot results by scaling 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("Scaling C by 1 / n_samples")

_ = fig.suptitle("Effect of scaling C with L2 penalty")

Резюме

В этом практикуме было показано влияние изменения параметра регуляризации в методах опорных векторов (SVM) для обоих случаев L1 и L2 штрафов. Для L1-штрафа мы наблюдали, что ошибка кросс-валидации наиболее коррелирует с тестовой ошибкой, когда масштабируем C в зависимости от числа выборок. Для L2-штрафа наилучшие результаты получаются в случае, когда C не масштабируется.