Aproximación explícita del mapa de características para kernels RBF

Machine LearningMachine LearningBeginner
Practicar Ahora

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

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

Esta práctica ilustra la aproximación del mapa de características de un kernel RBF utilizando RBFSampler y Nystroem para aproximar el mapa de características de un kernel RBF para la clasificación con un SVM en el conjunto de datos de dígitos. Se comparan los resultados utilizando un SVM lineal en el espacio original, un SVM lineal utilizando las aproximaciones de mapeo y un SVM con kernel. Se muestran los tiempos y la precisión para diferentes cantidades de muestreos de Monte Carlo (en el caso de RBFSampler, que utiliza características de Fourier aleatorias) y diferentes subconjuntos de tamaño del conjunto de entrenamiento (para Nystroem) para el mapeo aproximado.

Consejos sobre la VM

Una vez finalizada la inicialización de la VM, haga clic en la esquina superior izquierda para cambiar a la pestaña Cuaderno y acceder a Jupyter Notebook para practicar.

A veces, es posible que tenga que esperar unos segundos a que Jupyter Notebook termine de cargarse. La validación de las operaciones no se puede automatizar debido a las limitaciones de Jupyter Notebook.

Si tiene problemas durante el aprendizaje, no dude en preguntar a Labby. Deje su retroalimentación después de la sesión y resolveremos rápidamente el problema para usted.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL sklearn(("Sklearn")) -.-> sklearn/DataPreprocessingandFeatureEngineeringGroup(["Data Preprocessing and Feature Engineering"]) sklearn(("Sklearn")) -.-> sklearn/AdvancedDataAnalysisandDimensionalityReductionGroup(["Advanced Data Analysis and Dimensionality Reduction"]) ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) sklearn/DataPreprocessingandFeatureEngineeringGroup -.-> sklearn/kernel_approximation("Kernel Approximation") sklearn/AdvancedDataAnalysisandDimensionalityReductionGroup -.-> sklearn/decomposition("Matrix Decomposition") ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills sklearn/kernel_approximation -.-> lab-49176{{"Aproximación explícita del mapa de características para kernels RBF"}} sklearn/decomposition -.-> lab-49176{{"Aproximación explícita del mapa de características para kernels RBF"}} ml/sklearn -.-> lab-49176{{"Aproximación explícita del mapa de características para kernels RBF"}} end

Importación del paquete de Python y del conjunto de datos, Carga del conjunto de datos

## Importaciones científicas estándar de Python
import matplotlib.pyplot as plt
import numpy as np
from time import time

## Importar conjuntos de datos, clasificadores y métricas de rendimiento
from sklearn import datasets, svm, pipeline
from sklearn.kernel_approximation import RBFSampler, Nystroem
from sklearn.decomposition import PCA

## El conjunto de datos de dígitos
digits = datasets.load_digits(n_class=9)

Gráficos de tiempos y precisión

## Para aplicar un clasificador a estos datos, necesitamos aplanar la imagen, para
## convertir los datos en una matriz (muestras, características):
n_samples = len(digits.data)
data = digits.data / 16.0
data -= data.mean(axis=0)

## Aprendemos los dígitos en la primera mitad de los dígitos
data_train, targets_train = (data[: n_samples // 2], digits.target[: n_samples // 2])

## Ahora predecimos el valor del dígito en la segunda mitad:
data_test, targets_test = (data[n_samples // 2 :], digits.target[n_samples // 2 :])

## Creamos un clasificador: un clasificador de vectores de soporte
kernel_svm = svm.SVC(gamma=0.2)
linear_svm = svm.LinearSVC(dual="auto")

## crear pipeline a partir de la aproximación del kernel y el svm lineal
feature_map_fourier = RBFSampler(gamma=0.2, random_state=1)
feature_map_nystroem = Nystroem(gamma=0.2, random_state=1)

fourier_approx_svm = pipeline.Pipeline([
  ("feature_map", feature_map_fourier),
  ("svm", svm.LinearSVC(dual="auto"))
])

nystroem_approx_svm = pipeline.Pipeline([
  ("feature_map", feature_map_nystroem),
  ("svm", svm.LinearSVC(dual="auto"))
])

## ajustar y predecir utilizando svm lineal y con kernel:
kernel_svm_time = time()
kernel_svm.fit(data_train, targets_train)
kernel_svm_score = kernel_svm.score(data_test, targets_test)
kernel_svm_time = time() - kernel_svm_time

linear_svm_time = time()
linear_svm.fit(data_train, targets_train)
linear_svm_score = linear_svm.score(data_test, targets_test)
linear_svm_time = time() - linear_svm_time

sample_sizes = 30 * np.arange(1, 10)
fourier_scores = []
nystroem_scores = []
fourier_times = []
nystroem_times = []

for D in sample_sizes:
  fourier_approx_svm.set_params(feature_map__n_components=D)
  nystroem_approx_svm.set_params(feature_map__n_components=D)

  start = time()
  nystroem_approx_svm.fit(data_train, targets_train)
  nystroem_times.append(time() - start)

  start = time()
  fourier_approx_svm.fit(data_train, targets_train)
  fourier_times.append(time() - start)

  fourier_score = fourier_approx_svm.score(data_test, targets_test)
  nystroem_score = nystroem_approx_svm.score(data_test, targets_test)
  nystroem_scores.append(nystroem_score)
  fourier_scores.append(fourier_score)

## graficar los resultados:
plt.figure(figsize=(16, 4))
accuracy = plt.subplot(121)
## segundo eje y para los tiempos
timescale = plt.subplot(122)

accuracy.plot(sample_sizes, nystroem_scores, label="Aprox. kernel de Nystroem")
timescale.plot(sample_sizes, nystroem_times, "--", label="Aprox. kernel de Nystroem")

accuracy.plot(sample_sizes, fourier_scores, label="Aprox. kernel de Fourier")
timescale.plot(sample_sizes, fourier_times, "--", label="Aprox. kernel de Fourier")

## líneas horizontales para los kernels rbf y lineal exactos:
accuracy.plot([sample_sizes[0], sample_sizes[-1]], [linear_svm_score, linear_svm_score], label="svm lineal")
timescale.plot([sample_sizes[0], sample_sizes[-1]], [linear_svm_time, linear_svm_time], "--", label="svm lineal")

accuracy.plot([sample_sizes[0], sample_sizes[-1]], [kernel_svm_score, kernel_svm_score], label="svm rbf")
timescale.plot([sample_sizes[0], sample_sizes[-1]], [kernel_svm_time, kernel_svm_time], "--", label="svm rbf")

## línea vertical para la dimensionalidad del conjunto de datos = 64
accuracy.plot([64, 64], [0.7, 1], label="n_features")

## leyendas y etiquetas
accuracy.set_title("Precisión de clasificación")
timescale.set_title("Tiempos de entrenamiento")
accuracy.set_xlim(sample_sizes[0], sample_sizes[-1])
accuracy.set_xticks(())
accuracy.set_ylim(np.min(fourier_scores), 1)
timescale.set_xlabel("Pasos de muestreo = dimensión de la característica transformada")
accuracy.set_ylabel("Precisión de clasificación")
timescale.set_ylabel("Tiempo de entrenamiento en segundos")
accuracy.legend(loc="best")
timescale.legend(loc="best")
plt.tight_layout()
plt.show()

Superficies de decisión del SVM con kernel RBF y del SVM lineal

## visualizar la superficie de decisión, proyectada hacia los primeros
## dos componentes principales del conjunto de datos
pca = PCA(n_components=8).fit(data_train)

X = pca.transform(data_train)

## Generar una cuadrícula a lo largo de los primeros dos componentes principales
multiples = np.arange(-2, 2, 0.1)
## pasos a lo largo del primer componente
first = multiples[:, np.newaxis] * pca.components_[0, :]
## pasos a lo largo del segundo componente
second = multiples[:, np.newaxis] * pca.components_[1, :]
## combinar
grid = first[np.newaxis, :, :] + second[:, np.newaxis, :]
flat_grid = grid.reshape(-1, data.shape[1])

## título para las gráficas
titles = [
    "SVC con kernel rbf",
    "SVC (kernel lineal)\n con mapa de características rbf de Fourier\nn_componentes=100",
    "SVC (kernel lineal)\n con mapa de características rbf de Nystroem\nn_componentes=100",
]

plt.figure(figsize=(18, 7.5))
plt.rcParams.update({"font.size": 14})
## predecir y graficar
for i, clf in enumerate((kernel_svm, nystroem_approx_svm, fourier_approx_svm)):
    ## Graficar el límite de decisión. Para eso, asignaremos un color a cada
    ## punto en la malla [x_min, x_max]x[y_min, y_max].
    plt.subplot(1, 3, i + 1)
    Z = clf.predict(flat_grid)

    ## Poner el resultado en una gráfica de color
    Z = Z.reshape(grid.shape[:-1])
    levels = np.arange(10)
    lv_eps = 0.01  ## Ajustar una asignación de los niveles de contorno calculados al color.
    plt.contourf(
        multiples,
        multiples,
        Z,
        levels=levels - lv_eps,
        cmap=plt.cm.tab10,
        vmin=0,
        vmax=10,
        alpha=0.7,
    )
    plt.axis("off")

    ## Graficar también los puntos de entrenamiento
    plt.scatter(
        X[:, 0],
        X[:, 1],
        c=targets_train,
        cmap=plt.cm.tab10,
        edgecolors=(0, 0, 0),
        vmin=0,
        vmax=10,
    )

    plt.title(titles[i])
plt.tight_layout()
plt.show()

Resumen

Esta práctica ilustró la aproximación del mapa de características de un kernel RBF utilizando RBFSampler y Nystroem para aproximar el mapa de características de un kernel RBF para la clasificación con un SVM en el conjunto de datos de dígitos. Se compararon los resultados utilizando un SVM lineal en el espacio original, un SVM lineal utilizando las aproximaciones de mapeo y un SVM con kernel. Se mostraron los tiempos y la precisión para diferentes cantidades de muestreos de Monte Carlo (en el caso de RBFSampler, que utiliza características de Fourier aleatorias) y diferentes subconjuntos de tamaño del conjunto de entrenamiento (para Nystroem) para el mapeo aproximado. Finalmente, se visualizaron las superficies de decisión de los clasificadores proyectadas sobre los primeros dos componentes principales de los datos.