Plotar Sgdocsvm vs Ocsvm

Beginner

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

Introdução

Neste laboratório, demonstraremos como utilizar o Gradiente Descendente Estocástico (SGD) para aproximar a solução de uma Máquina de Vetores de Suporte de Uma Classe (One-Class SVM) no caso de um kernel RBF.

Compararemos os resultados desta aproximação com os resultados de utilizar uma One-Class SVM com uma abordagem kernel. O objetivo deste laboratório não é mostrar os benefícios da aproximação em termos de tempo de computação, mas sim demonstrar que resultados semelhantes podem ser obtidos utilizando SGD num conjunto de dados de brinquedo.

Dicas da Máquina Virtual

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 de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

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

Importar Bibliotecas

Começamos importando as bibliotecas necessárias para este laboratório: NumPy, Matplotlib e scikit-learn.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import OneClassSVM
from sklearn.linear_model import SGDOneClassSVM
from sklearn.kernel_approximation import Nystroem
from sklearn.pipeline import make_pipeline

Gerar Dados

Vamos gerar um conjunto de dados de brinquedo para este laboratório. Vamos gerar 500 amostras de treino e 20 amostras de teste. Também vamos gerar 20 amostras anormais.

random_state = 42
rng = np.random.RandomState(random_state)

## Gerar dados de treino
X = 0.3 * rng.randn(500, 2)
X_train = np.r_[X + 2, X - 2]
## Gerar algumas observações regulares e novas
X = 0.3 * rng.randn(20, 2)
X_test = np.r_[X + 2, X - 2]
## Gerar algumas observações anormais e novas
X_outliers = rng.uniform(low=-4, high=4, size=(20, 2))

Ajustar o SVM de Uma Classe

Primeiro, ajustaremos um SVM de uma classe com um kernel RBF ao nosso conjunto de dados.

## Hiperparâmetros do OCSVM
nu = 0.05
gamma = 2.0

## Ajustar o SVM de Uma Classe
clf = OneClassSVM(gamma=gamma, kernel="rbf", nu=nu)
clf.fit(X_train)
y_pred_train = clf.predict(X_train)
y_pred_test = clf.predict(X_test)
y_pred_outliers = clf.predict(X_outliers)
n_error_train = y_pred_train[y_pred_train == -1].size
n_error_test = y_pred_test[y_pred_test == -1].size
n_error_outliers = y_pred_outliers[y_pred_outliers == 1].size

Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

Ajustar o SVM de Uma Classe usando SGD

Em seguida, ajustaremos um SVM de uma classe usando SGD. Usaremos uma aproximação de kernel para aplicar SGD ao nosso conjunto de dados.

## Ajustar o SVM de Uma Classe usando uma aproximação de kernel e SGD
transform = Nystroem(gamma=gamma, random_state=random_state)
clf_sgd = SGDOneClassSVM(
    nu=nu, shuffle=True, fit_intercept=True, random_state=random_state, tol=1e-4
)
pipe_sgd = make_pipeline(transform, clf_sgd)
pipe_sgd.fit(X_train)
y_pred_train_sgd = pipe_sgd.predict(X_train)
y_pred_test_sgd = pipe_sgd.predict(X_test)
y_pred_outliers_sgd = pipe_sgd.predict(X_outliers)
n_error_train_sgd = y_pred_train_sgd[y_pred_train_sgd == -1].size
n_error_test_sgd = y_pred_test_sgd[y_pred_test_sgd == -1].size
n_error_outliers_sgd = y_pred_outliers_sgd[y_pred_outliers_sgd == 1].size

Z_sgd = pipe_sgd.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z_sgd = Z_sgd.reshape(xx.shape)

Plotar Resultados

Finalmente, plotaremos os resultados do nosso SVM de uma classe e do nosso SVM de uma classe usando SGD.

## plotar os conjuntos de nível da função de decisão
plt.figure(figsize=(9, 6))
plt.title("SVM de Uma Classe")
plt.contourf(xx, yy, Z, levels=np.linspace(Z.min(), 0, 7), cmap=plt.cm.PuBu)
a = plt.contour(xx, yy, Z, levels=[0], linewidths=2, colors="darkred")
plt.contourf(xx, yy, Z, levels=[0, Z.max()], colors="palevioletred")

s = 20
b1 = plt.scatter(X_train[:, 0], X_train[:, 1], c="white", s=s, edgecolors="k")
b2 = plt.scatter(X_test[:, 0], X_test[:, 1], c="blueviolet", s=s, edgecolors="k")
c = plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c="gold", s=s, edgecolors="k")
plt.axis("tight")
plt.xlim((-4.5, 4.5))
plt.ylim((-4.5, 4.5))
plt.legend(
    [a.collections[0], b1, b2, c],
    [
        "fronteira aprendida",
        "observações de treinamento",
        "novas observações regulares",
        "novas observações anormais",
    ],
    loc="upper left",
)
plt.xlabel(
    "erro treinamento: %d/%d; erros novos regulares: %d/%d; erros novos anormais: %d/%d"
    % (
        n_error_train,
        X_train.shape[0],
        n_error_test,
        X_test.shape[0],
        n_error_outliers,
        X_outliers.shape[0],
    )
)
plt.show()

plt.figure(figsize=(9, 6))
plt.title("SVM de Uma Classe Online")
plt.contourf(xx, yy, Z_sgd, levels=np.linspace(Z_sgd.min(), 0, 7), cmap=plt.cm.PuBu)
a = plt.contour(xx, yy, Z_sgd, levels=[0], linewidths=2, colors="darkred")
plt.contourf(xx, yy, Z_sgd, levels=[0, Z_sgd.max()], colors="palevioletred")

s = 20
b1 = plt.scatter(X_train[:, 0], X_train[:, 1], c="white", s=s, edgecolors="k")
b2 = plt.scatter(X_test[:, 0], X_test[:, 1], c="blueviolet", s=s, edgecolors="k")
c = plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c="gold", s=s, edgecolors="k")
plt.axis("tight")
plt.xlim((-4.5, 4.5))
plt.ylim((-4.5, 4.5))
plt.legend(
    [a.collections[0], b1, b2, c],
    [
        "fronteira aprendida",
        "observações de treinamento",
        "novas observações regulares",
        "novas observações anormais",
    ],
    loc="upper left",
)
plt.xlabel(
    "erro treinamento: %d/%d; erros novos regulares: %d/%d; erros novos anormais: %d/%d"
    % (
        n_error_train_sgd,
        X_train.shape[0],
        n_error_test_sgd,
        X_test.shape[0],
        n_error_outliers_sgd,
        X_outliers.shape[0],
    )
)
plt.show()

Resumo

Neste laboratório, demonstramos como usar o Gradiente Descendente Estocástico (SGD) para aproximar a solução de um SVM de uma classe com um kernel RBF. Comparamos os resultados desta aproximação com os resultados de usar um SVM de uma classe com uma abordagem kernel. Geramos um conjunto de dados de brinquedo e plotamos os resultados dos nossos modelos.