Примечание
Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере с помощью JupyterLite или Binder.
Аппроксимация явного отображения признаков для RBF-ядер
Пример, иллюстрирующий аппроксимацию отображения признаков RBF-ядра.
В нем показано, как использовать RBFSampler и Nystroem для аппроксимации отображения признаков RBF-ядра при классификации методом SVM на наборе данных цифр. Сравниваются результаты линейного SVM в исходном пространстве, линейного SVM с использованием приближенных отображений и SVM с ядром. Показаны время выполнения и точность при разном количестве выборок Монте-Карло (в случае RBFSampler, использующего случайные преобразования Фурье) и при разных размерах подмножеств обучающей выборки (для Nystroem) для приближенного отображения.
Обратите внимание, что набор данных здесь недостаточно велик, чтобы продемонстрировать преимущества аппроксимации ядра, поскольку точный SVM работает достаточно быстро.
Увеличение количества выбираемых измерений явно приводит к улучшению результатов классификации, но обходится дороже. Это означает, что параметр n_components задает компромисс между временем выполнения и точностью. Обратите внимание, что обучение линейного SVM и приближенного SVM с ядром можно значительно ускорить с помощью стохастического градиентного спуска через SGDClassifier. Для SVM с ядром это сделать не так просто.
Импорт пакета Python и набора данных, загрузка набора данных
# Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause # Standard scientific Python imports from time import time import matplotlib.pyplot as plt import numpy as np # Import datasets, classifiers and performance metrics from sklearn import datasets, pipeline, svm from sklearn.decomposition import PCA from sklearn.kernel_approximation import Nystroem, RBFSampler # The digits dataset digits = datasets.load_digits(n_class=9)
Графики времени выполнения и точности
Чтобы применить классификатор к этим данным, нужно преобразовать изображения в плоский формат, чтобы получить матрицу вида (образцы, признаки):
n_samples = len(digits.data)
data = digits.data / 16.0
data -= data.mean(axis=0)
# We learn the digits on the first half of the digits
data_train, targets_train = (data[: n_samples // 2], digits.target[: n_samples // 2])
# Now predict the value of the digit on the second half:
data_test, targets_test = (data[n_samples // 2 :], digits.target[n_samples // 2 :])
# data_test = scaler.transform(data_test)
# Create a classifier: a support vector classifier
kernel_svm = svm.SVC(gamma=0.2)
linear_svm = svm.LinearSVC(random_state=42)
# create pipeline from kernel approximation
# and linear svm
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(random_state=42)),
]
)
nystroem_approx_svm = pipeline.Pipeline(
[
("feature_map", feature_map_nystroem),
("svm", svm.LinearSVC(random_state=42)),
]
)
# fit and predict using linear and kernel svm:
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)
# plot the results:
plt.figure(figsize=(16, 4))
accuracy = plt.subplot(121)
# second y axis for timings
timescale = plt.subplot(122)
accuracy.plot(sample_sizes, nystroem_scores, label="Nystroem approx. kernel")
timescale.plot(sample_sizes, nystroem_times, "--", label="Nystroem approx. kernel")
accuracy.plot(sample_sizes, fourier_scores, label="Fourier approx. kernel")
timescale.plot(sample_sizes, fourier_times, "--", label="Fourier approx. kernel")
# horizontal lines for exact rbf and linear kernels:
accuracy.plot(
[sample_sizes[0], sample_sizes[-1]],
[linear_svm_score, linear_svm_score],
label="linear svm",
)
timescale.plot(
[sample_sizes[0], sample_sizes[-1]],
[linear_svm_time, linear_svm_time],
"--",
label="linear svm",
)
accuracy.plot(
[sample_sizes[0], sample_sizes[-1]],
[kernel_svm_score, kernel_svm_score],
label="rbf svm",
)
timescale.plot(
[sample_sizes[0], sample_sizes[-1]],
[kernel_svm_time, kernel_svm_time],
"--",
label="rbf svm",
)
# vertical line for dataset dimensionality = 64
accuracy.plot([64, 64], [0.7, 1], label="n_features")
# legends and labels
accuracy.set_title("Classification accuracy")
timescale.set_title("Training times")
accuracy.set_xlim(sample_sizes[0], sample_sizes[-1])
accuracy.set_xticks(())
accuracy.set_ylim(np.min(fourier_scores), 1)
timescale.set_xlabel("Sampling steps = transformed feature dimension")
accuracy.set_ylabel("Classification accuracy")
timescale.set_ylabel("Training time in seconds")
accuracy.legend(loc="best")
timescale.legend(loc="best")
plt.tight_layout()
plt.show()

Решающие поверхности SVM с RBF-ядром и линейного SVM
На втором графике показаны решающие поверхности SVM с RBF-ядром и линейного SVM с приближенными отображениями ядра. На графике отображены решающие поверхности классификаторов, спроецированные на первые две главные компоненты данных. К этой визуализации следует относиться с осторожностью, поскольку она представляет собой лишь интересный срез решающей поверхности в 64 измерениях. В частности, обратите внимание, что точка данных (изображенная точкой) не обязательно будет отнесена к классу, соответствующему области, в которой она находится, поскольку она может не лежать на плоскости, задаваемой первыми двумя главными компонентами. Использование RBFSampler и Nystroem подробно описано в разделе Аппроксимация ядра.
# visualize the decision surface, projected down to the first
# two principal components of the dataset
pca = PCA(n_components=8, random_state=42).fit(data_train)
X = pca.transform(data_train)
# Generate grid along first two principal components
multiples = np.arange(-2, 2, 0.1)
# steps along first component
first = multiples[:, np.newaxis] * pca.components_[0, :]
# steps along second component
second = multiples[:, np.newaxis] * pca.components_[1, :]
# combine
grid = first[np.newaxis, :, :] + second[:, np.newaxis, :]
flat_grid = grid.reshape(-1, data.shape[1])
# title for the plots
titles = [
"SVC with rbf kernel",
"SVC (linear kernel)\n with Fourier rbf feature map\nn_components=100",
"SVC (linear kernel)\n with Nystroem rbf feature map\nn_components=100",
]
plt.figure(figsize=(18, 7.5))
plt.rcParams.update({"font.size": 14})
# predict and plot
for i, clf in enumerate((kernel_svm, nystroem_approx_svm, fourier_approx_svm)):
# Plot the decision boundary. For that, we will assign a color to each
# point in the mesh [x_min, x_max]x[y_min, y_max].
plt.subplot(1, 3, i + 1)
Z = clf.predict(flat_grid)
# Put the result into a color plot
Z = Z.reshape(grid.shape[:-1])
levels = np.arange(10)
lv_eps = 0.01 # Adjust a mapping from calculated contour levels to color.
plt.contourf(
multiples,
multiples,
Z,
levels=levels - lv_eps,
cmap=plt.cm.tab10,
vmin=0,
vmax=10,
alpha=0.7,
)
plt.axis("off")
# Plot also the training points
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()

Общее время выполнения скрипта: (0 минут 1.770 секунды)
Похожие примеры
© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/miscellaneous/plot_kernel_approximation.html