RBF 커널 특징 맵 근사

Beginner

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

소개

이 실습에서는 RBF 커널의 특징 맵을 RBFSampler 및 Nystroem 을 사용하여 근사하여 SVM 을 사용한 숫자 데이터셋 분류에 대한 특징 맵을 근사합니다. 원래 공간에서 선형 SVM, 근사 매핑을 사용한 선형 SVM, 커널화된 SVM 을 사용한 결과를 비교합니다. 다양한 수의 몬테 카를로 샘플링 (RBFSampler 의 경우 랜덤 푸리에 특징을 사용) 과 근사 매핑을 위한 훈련 세트의 서로 다른 크기의 부분 집합에 대한 시간 및 정확도를 보여줍니다.

VM 팁

VM 시작이 완료되면 왼쪽 상단 모서리를 클릭하여 Notebook 탭으로 전환하여 Jupyter Notebook에 접근할 수 있습니다.

때때로 Jupyter Notebook 이 완전히 로드되기까지 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한으로 인해 작업 검증을 자동화할 수 없습니다.

학습 중 문제가 발생하면 Labby 에 문의하십시오. 세션 후 피드백을 제공하면 문제를 신속하게 해결해 드리겠습니다.

Python 패키지 및 데이터셋 가져오기, 데이터셋 로드

## 표준 과학 Python 가져오기
import matplotlib.pyplot as plt
import numpy as np
from time import time

## 데이터셋, 분류기 및 성능 지표 가져오기
from sklearn import datasets, svm, pipeline
from sklearn.kernel_approximation import RBFSampler, Nystroem
from sklearn.decomposition import PCA

## 숫자 데이터셋
digits = datasets.load_digits(n_class=9)

시간 및 정확도 플롯

## 이 데이터에 분류기를 적용하려면 이미지를 평면화하여 데이터를 (샘플, 특징) 행렬로 변환해야 합니다.
n_samples = len(digits.data)
data = digits.data / 16.0
data -= data.mean(axis=0)

## 숫자를 첫 번째 절반에서 학습합니다.
data_train, targets_train = (data[: n_samples // 2], digits.target[: n_samples // 2])

## 이제 두 번째 절반의 숫자 값을 예측합니다.
data_test, targets_test = (data[n_samples // 2 :], digits.target[n_samples // 2 :])

## 분류기 (지지 벡터 분류기) 를 만듭니다.
kernel_svm = svm.SVC(gamma=0.2)
linear_svm = svm.LinearSVC(dual="auto")

## 커널 근사 및 선형 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(dual="auto"))
])

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

## 선형 및 커널 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)

## 결과를 플롯합니다.
plt.figure(figsize=(16, 4))
accuracy = plt.subplot(121)
## 시간 측정을 위한 두 번째 y 축
timescale = plt.subplot(122)

accuracy.plot(sample_sizes, nystroem_scores, label="Nystroem 근사 커널")
timescale.plot(sample_sizes, nystroem_times, "--", label="Nystroem 근사 커널")

accuracy.plot(sample_sizes, fourier_scores, label="Fourier 근사 커널")
timescale.plot(sample_sizes, fourier_times, "--", label="Fourier 근사 커널")

## 정확한 rbf 및 선형 커널에 대한 수평선
accuracy.plot([sample_sizes[0], sample_sizes[-1]], [linear_svm_score, linear_svm_score], label="선형 SVM")
timescale.plot([sample_sizes[0], sample_sizes[-1]], [linear_svm_time, linear_svm_time], "--", label="선형 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")

## 데이터 차원 = 64 에 대한 수직선
accuracy.plot([64, 64], [0.7, 1], label="n_features")

## 범례 및 레이블
accuracy.set_title("분류 정확도")
timescale.set_title("훈련 시간")
accuracy.set_xlim(sample_sizes[0], sample_sizes[-1])
accuracy.set_xticks(())
accuracy.set_ylim(np.min(fourier_scores), 1)
timescale.set_xlabel("샘플링 단계 = 변환된 특징 차원")
accuracy.set_ylabel("분류 정확도")
timescale.set_ylabel("초 단위 훈련 시간")
accuracy.legend(loc="best")
timescale.legend(loc="best")
plt.tight_layout()
plt.show()

RBF 커널 SVM 및 선형 SVM 의 결정 경계

## 데이터의 첫 두 주요 구성 요소로 투영하여 결정 경계를 시각화합니다.
pca = PCA(n_components=8).fit(data_train)

X = pca.transform(data_train)

## 첫 두 주요 구성 요소에 따라 그리드를 생성합니다.
multiples = np.arange(-2, 2, 0.1)
## 첫 번째 구성 요소에 따른 단계
first = multiples[:, np.newaxis] * pca.components_[0, :]
## 두 번째 구성 요소에 따른 단계
second = multiples[:, np.newaxis] * pca.components_[1, :]
## 결합
grid = first[np.newaxis, :, :] + second[:, np.newaxis, :]
flat_grid = grid.reshape(-1, data.shape[1])

## 플롯 제목
titles = [
    "rbf 커널을 사용한 SVC",
    "SVC (선형 커널)\nFourier rbf 특징 맵\nn_components=100",
    "SVC (선형 커널)\nNystroem rbf 특징 맵\nn_components=100",
]

plt.figure(figsize=(18, 7.5))
plt.rcParams.update({"font.size": 14})
## 예측 및 플롯
for i, clf in enumerate((kernel_svm, nystroem_approx_svm, fourier_approx_svm)):
    ## 결정 경계를 플롯합니다. 이를 위해 메쉬 [x_min, x_max]x[y_min, y_max] 의 각 점에 색상을 할당합니다.
    plt.subplot(1, 3, i + 1)
    Z = clf.predict(flat_grid)

    ## 결과를 색상 플롯에 넣습니다.
    Z = Z.reshape(grid.shape[:-1])
    levels = np.arange(10)
    lv_eps = 0.01  ## 계산된 등고선 레벨에서 색상으로의 매핑을 조정합니다.
    plt.contourf(
        multiples,
        multiples,
        Z,
        levels=levels - lv_eps,
        cmap=plt.cm.tab10,
        vmin=0,
        vmax=10,
        alpha=0.7,
    )
    plt.axis("off")

    ## 훈련 점도 플롯합니다.
    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()

요약

이 실험에서는 RBFSampler 과 Nystroem 을 사용하여 RBF 커널의 특징 맵을 근사하여 숫자 데이터셋에 SVM 을 사용한 분류 작업에 대한 결과를 보여주었습니다. 원래 공간에서 선형 SVM, 근사 매핑을 사용한 선형 SVM, 커널화된 SVM 을 사용한 결과를 비교했습니다. 다양한 수의 몬테 카를로 샘플링 (RBFSampler 의 경우 랜덤 푸리에 특징을 사용) 과 근사 매핑을 위한 훈련 세트의 서로 다른 크기의 하위 집합에 대한 시간 및 정확도를 보여주었습니다. 마지막으로, 분류기의 결정 경계를 데이터의 첫 두 주요 구성 요소에 투영하여 시각화했습니다.