소개
이 실습에서는 숫자 데이터셋에 대한 다양한 매니폴드 임베딩 기법을 탐색합니다. 숫자 데이터셋을 다른 기법으로 임베딩하고, 원본 데이터의 투영을 각 임베딩에 플롯하여, 서로 다른 임베딩 방법으로 얻은 결과를 비교합니다.
VM 팁
VM 시작이 완료되면 왼쪽 상단 모서리를 클릭하여 Notebook 탭으로 전환하여 연습을 위한 Jupyter Notebook에 접근합니다.
때때로 Jupyter Notebook 이 완전히 로드되기까지 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한으로 인해 작업의 유효성 검사를 자동화할 수 없습니다.
학습 중 문제가 발생하면 Labby 에게 문의하십시오. 세션 후 피드백을 제공하면 문제를 신속하게 해결해 드리겠습니다.
숫자 데이터셋 로드
이번 실습에서는 숫자 데이터셋을 로드하고, 사용 가능한 10 개 클래스 중 6 개만 사용합니다. 또한, 이 데이터셋에서 처음 100 개의 숫자를 플롯합니다.
## 숫자 데이터셋 로드
from sklearn.datasets import load_digits
digits = load_digits(n_class=6)
X, y = digits.data, digits.target
n_samples, n_features = X.shape
n_neighbors = 30
## 처음 100 개 숫자 플롯
import matplotlib.pyplot as plt
fig, axs = plt.subplots(nrows=10, ncols=10, figsize=(6, 6))
for idx, ax in enumerate(axs.ravel()):
ax.imshow(X[idx].reshape((8, 8)), cmap=plt.cm.binary)
ax.axis("off")
_ = fig.suptitle("64 차원 숫자 데이터셋에서 선택된 샘플", fontsize=16)
임베딩 함수 플롯
임베딩을 플롯하기 위한 도우미 함수를 정의합니다. 이 함수는 임베딩 데이터와 플롯 제목을 입력으로 받습니다. 함수는 임베딩 위에 각 숫자를 플롯하고, 숫자 그룹에 대한 주석 상자를 표시합니다.
import numpy as np
from matplotlib import offsetbox
from sklearn.preprocessing import MinMaxScaler
def plot_embedding(X, title):
_, ax = plt.subplots()
X = MinMaxScaler().fit_transform(X)
for digit in digits.target_names:
ax.scatter(
*X[y == digit].T,
marker=f"${digit}$",
s=60,
color=plt.cm.Dark2(digit),
alpha=0.425,
zorder=2,
)
shown_images = np.array([[1.0, 1.0]]) ## just something big
for i in range(X.shape[0]):
## 임베딩 위에 각 숫자를 플롯합니다.
## 숫자 그룹에 대한 주석 상자를 표시합니다.
dist = np.sum((X[i] - shown_images) ** 2, 1)
if np.min(dist) < 4e-3:
## 너무 가까운 점은 표시하지 않습니다.
continue
shown_images = np.concatenate([shown_images, [X[i]]], axis=0)
imagebox = offsetbox.AnnotationBbox(
offsetbox.OffsetImage(digits.images[i], cmap=plt.cm.gray_r), X[i]
)
imagebox.set(zorder=1)
ax.add_artist(imagebox)
ax.set_title(title)
ax.axis("off")
임베딩 기법 비교
다양한 방법을 사용하여 서로 다른 임베딩 기법을 비교합니다. 각 투영을 수행하는 데 필요한 투영된 데이터와 계산 시간을 저장합니다.
from sklearn.decomposition import TruncatedSVD
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.ensemble import RandomTreesEmbedding
from sklearn.manifold import (
Isomap,
LocallyLinearEmbedding,
MDS,
SpectralEmbedding,
TSNE,
)
from sklearn.neighbors import NeighborhoodComponentsAnalysis
from sklearn.pipeline import make_pipeline
from sklearn.random_projection import SparseRandomProjection
embeddings = {
"Random projection embedding": SparseRandomProjection(
n_components=2, random_state=42
),
"Truncated SVD embedding": TruncatedSVD(n_components=2),
"Linear Discriminant Analysis embedding": LinearDiscriminantAnalysis(
n_components=2
),
"Isomap embedding": Isomap(n_neighbors=n_neighbors, n_components=2),
"Standard LLE embedding": LocallyLinearEmbedding(
n_neighbors=n_neighbors, n_components=2, method="standard"
),
"Modified LLE embedding": LocallyLinearEmbedding(
n_neighbors=n_neighbors, n_components=2, method="modified"
),
"Hessian LLE embedding": LocallyLinearEmbedding(
n_neighbors=n_neighbors, n_components=2, method="hessian"
),
"LTSA LLE embedding": LocallyLinearEmbedding(
n_neighbors=n_neighbors, n_components=2, method="ltsa"
),
"MDS embedding": MDS(
n_components=2, n_init=1, max_iter=120, n_jobs=2, normalized_stress="auto"
),
"Random Trees embedding": make_pipeline(
RandomTreesEmbedding(n_estimators=200, max_depth=5, random_state=0),
TruncatedSVD(n_components=2),
),
"Spectral embedding": SpectralEmbedding(
n_components=2, random_state=0, eigen_solver="arpack"
),
"t-SNE embeedding": TSNE(
n_components=2,
n_iter=500,
n_iter_without_progress=150,
n_jobs=2,
random_state=0,
),
"NCA embedding": NeighborhoodComponentsAnalysis(
n_components=2, init="pca", random_state=0
),
}
projections, timing = {}, {}
for name, transformer in embeddings.items():
if name.startswith("Linear Discriminant Analysis"):
data = X.copy()
data.flat[:: X.shape[1] + 1] += 0.01 ## Make X invertible
else:
data = X
print(f"Computing {name}...")
start_time = time()
projections[name] = transformer.fit_transform(data, y)
timing[name] = time() - start_time
결과 플롯
각 방법으로 얻은 결과 투영을 플롯합니다.
for name in timing:
title = f"{name} (time {timing[name]:.3f}s)"
plot_embedding(projections[name], title)
plt.show()
요약
이 실험에서는 숫자 데이터셋에 대한 다양한 매니폴드 임베딩 기법을 탐색했습니다. 숫자 데이터셋을 다양한 기법으로 임베딩하고, 원본 데이터의 투영을 각 임베딩에 플롯하여 서로 다른 임베딩 방법으로 얻은 결과를 비교했습니다. 결과는 각 임베딩 방법이 임베딩 공간에서 유사한 숫자를 함께 그룹화하는 데 얼마나 효과적인지에 대한 통찰력을 제공합니다.