Escalonamento do Parâmetro de Regularização para Máquinas de Vetores de Suporte (SVM)

Beginner

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

Introdução

Este laboratório demonstra o efeito da escala do parâmetro de regularização ao utilizar Máquinas de Vetores de Suporte (SVMs) para classificação. Na classificação SVM, estamos interessados na minimização de risco para a equação:

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

onde:

  • C é usado para definir a quantidade de regularização
  • L é uma função de perda das nossas amostras e dos nossos parâmetros do modelo.
  • Ω é uma função de penalidade dos nossos parâmetros do modelo

Dicas da VM

Após o arranque da VM, clique no canto superior esquerdo para mudar para a aba Notebook para aceder ao Jupyter Notebook para a prática.

Por vezes, pode ser necessário esperar alguns segundos para o Jupyter Notebook terminar o carregamento. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se tiver problemas durante a aprendizagem, não hesite em contactar o Labby. Forneça feedback após a sessão e resolveremos prontamente o problema para si.

Importar Bibliotecas e Gerar Conjunto de Dados Sintético

Começamos importando as bibliotecas necessárias e gerando um conjunto de dados sintético apropriado para regularização L1 e 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)

Caso de Penalidade L1

No caso L1, a teoria afirma que a consistência do modelo, em termos de encontrar o conjunto correto de parâmetros não nulos e seus sinais, pode ser alcançada escalando C. Demonstramos esse efeito usando um conjunto de dados sintético esparso, o que significa que apenas algumas características serão informativas e úteis para o modelo.

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"fração: {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))

## plotar resultados sem escalar C
results.plot(x="C", ax=axes[0], logx=True)
axes[0].set_ylabel("Pontuação CV")
axes[0].set_title("Sem escala")

## plotar resultados escalando 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("Escalando C por 1 / n_samples")

_ = fig.suptitle("Efeito da escala de C com penalidade L1")

Caso de Penalidade L2

Podemos repetir um experimento semelhante com a penalidade l2. Neste caso, a teoria diz que, para alcançar a consistência de previsão, o parâmetro de penalidade deve ser mantido constante à medida que o número de amostras aumenta.

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

labels = [f"fração: {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))

## plotar resultados sem escalar C
results.plot(x="C", ax=axes[0], logx=True)
axes[0].set_ylabel("Pontuação CV")
axes[0].set_title("Sem escala")

## plotar resultados escalando 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("Escalando C por 1 / n_samples")

_ = fig.suptitle("Efeito da escala de C com penalidade L2")

Resumo

Este laboratório demonstrou o efeito da escala do parâmetro de regularização em SVMs para penalidades L1 e L2. Para a penalidade L1, observamos que o erro de validação cruzada correlaciona-se melhor com o erro de teste quando se escala C com o número de amostras. Para a penalidade L2, o melhor resultado provém do caso em que C não é escalado.