Approximation explicite de la carte de caractéristiques pour les noyaux RBF

Machine LearningMachine LearningBeginner
Pratiquer maintenant

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

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Ce laboratoire illustre l'approximation de la carte de caractéristiques d'un noyau RBF en utilisant RBFSampler et Nystroem pour approximer la carte de caractéristiques d'un noyau RBF pour la classification avec un SVM sur l'ensemble de données des chiffres. Les résultats obtenus avec un SVM linéaire dans l'espace original, un SVM linéaire utilisant les mappages approximatifs et un SVM à noyau sont comparés. Les temps d'exécution et la précision pour différents nombres d'échantillonnages Monte Carlo (dans le cas de RBFSampler, qui utilise des caractéristiques de Fourier aléatoires) et différents sous-ensembles de taille du jeu d'entraînement (pour Nystroem) pour le mappage approximatif sont présentés.

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 à Jupyter Notebook pour la pratique.

Parfois, vous devrez peut-être attendre quelques secondes pour que Jupyter Notebook ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limitations de Jupyter Notebook.

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.


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{{"Approximation explicite de la carte de caractéristiques pour les noyaux RBF"}} sklearn/decomposition -.-> lab-49176{{"Approximation explicite de la carte de caractéristiques pour les noyaux RBF"}} ml/sklearn -.-> lab-49176{{"Approximation explicite de la carte de caractéristiques pour les noyaux RBF"}} end

Importation du package Python et du jeu de données, Chargement du jeu de données

## Importations scientifiques standard de Python
import matplotlib.pyplot as plt
import numpy as np
from time import time

## Importation de jeux de données, de classifieurs et de mesures de performance
from sklearn import datasets, svm, pipeline
from sklearn.kernel_approximation import RBFSampler, Nystroem
from sklearn.decomposition import PCA

## Le jeu de données des chiffres
digits = datasets.load_digits(n_class=9)

Courbes de temps d'exécution et de précision

## Pour appliquer un classifieur sur ces données, nous devons aplatir l'image, pour
## transformer les données en une matrice (échantillons, caractéristiques) :
n_samples = len(digits.data)
data = digits.data / 16.0
data -= data.mean(axis=0)

## Nous apprenons les chiffres sur la première moitié des chiffres
data_train, targets_train = (data[: n_samples // 2], digits.target[: n_samples // 2])

## Maintenant, prédisons la valeur du chiffre sur la deuxième moitié :
data_test, targets_test = (data[n_samples // 2 :], digits.target[n_samples // 2 :])

## Créez un classifieur : un classifieur à vecteurs de support
kernel_svm = svm.SVC(gamma=0.2)
linear_svm = svm.LinearSVC(dual="auto")

## créez un pipeline à partir d'une approximation de noyau et d'un svm linéaire
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"))
])

## ajustez et prédisez en utilisant svm linéaire et svm à noyau :
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)

## tracez les résultats :
plt.figure(figsize=(16, 4))
accuracy = plt.subplot(121)
## deuxième axe y pour les temps d'exécution
timescale = plt.subplot(122)

accuracy.plot(sample_sizes, nystroem_scores, label="Approx. noyau Nystroem")
timescale.plot(sample_sizes, nystroem_times, "--", label="Approx. noyau Nystroem")

accuracy.plot(sample_sizes, fourier_scores, label="Approx. noyau Fourier")
timescale.plot(sample_sizes, fourier_times, "--", label="Approx. noyau Fourier")

## lignes horizontales pour les noyaux rbf et linéaires exacts :
accuracy.plot([sample_sizes[0], sample_sizes[-1]], [linear_svm_score, linear_svm_score], label="svm linéaire")
timescale.plot([sample_sizes[0], sample_sizes[-1]], [linear_svm_time, linear_svm_time], "--", label="svm linéaire")

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

## ligne verticale pour la dimensionnalité du jeu de données = 64
accuracy.plot([64, 64], [0.7, 1], label="n_features")

## légendes et étiquettes
accuracy.set_title("Précision de la classification")
timescale.set_title("Temps d'entraînement")
accuracy.set_xlim(sample_sizes[0], sample_sizes[-1])
accuracy.set_xticks(())
accuracy.set_ylim(np.min(fourier_scores), 1)
timescale.set_xlabel("Étapes d'échantillonnage = dimension de la caractéristique transformée")
accuracy.set_ylabel("Précision de la classification")
timescale.set_ylabel("Temps d'entraînement en secondes")
accuracy.legend(loc="best")
timescale.legend(loc="best")
plt.tight_layout()
plt.show()

Surfaces de décision du SVM à noyau RBF et du SVM linéaire

## visualisez la surface de décision, projetée sur les deux premières
## composantes principales du jeu de données
pca = PCA(n_components=8).fit(data_train)

X = pca.transform(data_train)

## Générez une grille le long des deux premières composantes principales
multiples = np.arange(-2, 2, 0.1)
## pas le long de la première composante
first = multiples[:, np.newaxis] * pca.components_[0, :]
## pas le long de la deuxième composante
second = multiples[:, np.newaxis] * pca.components_[1, :]
## combinez
grid = first[np.newaxis, :, :] + second[:, np.newaxis, :]
flat_grid = grid.reshape(-1, data.shape[1])

## titre pour les graphiques
titles = [
    "SVC avec noyau rbf",
    "SVC (noyau linéaire)\n avec carte de caractéristiques rbf de Fourier\nn_components=100",
    "SVC (noyau linéaire)\n avec carte de caractéristiques rbf de Nystroem\nn_components=100",
]

plt.figure(figsize=(18, 7.5))
plt.rcParams.update({"font.size": 14})
## prédisez et tracez
for i, clf in enumerate((kernel_svm, nystroem_approx_svm, fourier_approx_svm)):
    ## Tracez la frontière de décision. Pour cela, nous allons attribuer une couleur à chaque
    ## point dans la grille [x_min, x_max]x[y_min, y_max].
    plt.subplot(1, 3, i + 1)
    Z = clf.predict(flat_grid)

    ## Placez le résultat dans un graphique en couleur
    Z = Z.reshape(grid.shape[:-1])
    levels = np.arange(10)
    lv_eps = 0.01  ## Ajustez une correspondance entre les niveaux de contour calculés et la couleur.
    plt.contourf(
        multiples,
        multiples,
        Z,
        levels=levels - lv_eps,
        cmap=plt.cm.tab10,
        vmin=0,
        vmax=10,
        alpha=0.7,
    )
    plt.axis("off")

    ## Tracez également les points d'entraînement
    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()

Sommaire

Ce laboratoire a illustré l'approximation de la carte de caractéristiques d'un noyau RBF en utilisant RBFSampler et Nystroem pour approximer la carte de caractéristiques d'un noyau RBF pour la classification avec un SVM sur l'ensemble de données des chiffres. Les résultats obtenus avec un SVM linéaire dans l'espace original, un SVM linéaire utilisant les mappages approximatifs et un SVM à noyau ont été comparés. Les temps d'exécution et la précision pour différents nombres d'échantillonnages Monte Carlo (dans le cas de RBFSampler, qui utilise des caractéristiques de Fourier aléatoires) et différents sous-ensembles de taille du jeu d'entraînement (pour Nystroem) pour le mappage approximatif ont été présentés. Enfin, les surfaces de décision des classifieurs ont été visualisées projetées sur les deux premières composantes principales des données.