C. ์ปค๋ PCA๋ฅผ ์ฌ์ฉํ ๋น์ ํ ๋งคํ
์ฌํ๊น์ง ๋ง์ ๋จธ์ ๋ฌ๋ ์๊ณ ๋ฆฌ์ฆ์ ์ ๋ ฅ ๋ฐ์ดํฐ๊ฐ ์ ํ์ ์ผ๋ก ๊ตฌ๋ถ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฐ์ ์ ํฉ๋๋ค. ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ๋ค-์๋ฌ๋ฆฐ, ๋ก์ง์คํฑ ํ๊ท, SVM-์ ์ ํ์ ์ผ๋ก ์๋ฒฝํ๊ฒ ๋ถ๋ฆฌ๋์ง ์๋ ์ด์ ๋ฅผ ์ก์๋๋ฌธ์ด๋ผ๊ณ ์ด์ผ๊ธฐํฉ๋๋ค.
์ค์ ์์๋ ๋ ์์ฃผ ๋น์ ํ ๋ฌธ์ ๋ค์ ๋ง๋ฅ๋จ๋ฆฝ๋๋ค. ์ด ๊ฒฝ์ฐ์ ํญ์ PCA๋ LDA์ ๊ฐ์ ์ฐจ์ ์ถ์ ๊ธฐ๋ฒ์ด ์ต์ ์ด๋ผ๊ณ ๋ ๋งํ ์ ์๊ฒ ์ฃ . ์ด์ ๋ถํฐ ์์๋ณผ ๊ฒ์ PCA์ ์ปค๋ํ ๋ฒ์ ์ธ KPCA์ ๋๋ค.
1. ์ปค๋ ํจ์์ ์ปค๋ ํธ๋ฆญ
์์ ์ธ์ ์์ ์ปค๋ SVM์ ๋ํด ์ด์ผ๊ธฐํ ๊ฒ์ ๋ ์ฌ๋ ค๋ณด๋ฉด, ๋น์ ํ ๋ฌธ์ ๋ฅผ ํ๊ธฐ ์ํด ๊ณ ์ฐจ์ ๊ณต๊ฐ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ํฌ์ํด ํ์์ต๋๋ค. k ๊ณ ์ฐจ์ ๋ถ๋ถ ๊ณต๊ฐ์ ์๋ ์ํ์ ๋ณํํ๊ธฐ ์ํด ๋น์ ํ ๋งคํ ํจ์๋ฅผ ์ ์ํฉ๋๋ค.
์ด ํจ์๋ฅผ d์ฐจ์ ๋ณด๋ค ๋ ํฐ k์ฐจ์์ผ๋ก ๋งคํํ๊ธฐ ์ํด ์๋ณธ ํน์ฑ์ ๋น์ ํ ์กฐํฉ์ ๋ง๋ญ๋๋ค. 2์ฐจ์์ ํน์ฑ๋ฒกํฐ๋ฅผ ๋งคํ ๊ฐ๋ฅํ 3์ฐจ์ ๊ณต๊ฐ์ ์๋์ ๊ฐ์ต๋๋ค.
์ค๊ฐ ์ ๋ฆฌ๋ฅผ ํ๋ฉด, ์ปค๋ PCA๋ก ๋น์ ํ ๋งคํ์ ์ํํด์ ๊ณ ์ฐจ์ ๊ณต๊ฐ์ผ๋ก ๋ณํํ๊ณ , ํ์ค PCA๋ก ์ํ์ด ์ ํ ๋ถ๋ฅ๊ธฐ๋ก ๊ตฌ๋ถ๋ ์ ์๋ ์ ์ฐจ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ํฌ์์ํค๋ ๊ฒ์ ๋๋ค.
์ด ๋ฐฉ์์ ๋จ์ ์ ๊ณ์ฐ ๋น์ฉ์ด ๋งค์ฐ ๋น์ธ๋ค๋ ์ ์ ๋๋ค. ์ด ๋ถ๋ถ์์ ์ปค๋ ํธ๋ฆญ(kernel trick)์ด ๋ฑ์ฅํฉ๋๋ค. ์ปค๋ ํธ๋ฆญ์ ์ฌ์ฉํ๋ฉด ์๋ณธ ํน์ฑ ๊ณต๊ฐ์์ ๋ ๊ณ ์ฐจ์ ํน์ฑ ๋ฒกํฐ์ ์ ์ฌ๋๋ฅผ ๊ณ์ฐํ ์ ์์ต๋๋ค. ์ปค๋ ํธ๋ฆญ์ ์ญํ ์ ์์๋ณด๊ธฐ ์ ์ ๋ค์ PCA ๋ฐฉ์์ ์์์ ์๊ฐํด๋ณผ๊น์?
ํน์ฑ k์ j์ ๊ณต๋ถ์ฐ์ ์๋์ ๊ฐ์ต๋๋ค.
์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ ํน์ฑ ํ๊ท ๋ฎค๋ฅผ 0์ ๋ง์ถ์์ผ๋ฏ๋ก ์๋์ ๊ฐ์ด ๊ฐ๋จํ ์ธ ์ ์์ต๋๋ค.
์ด ์์ ๋ ํน์ฑ ๊ฐ์ ๊ณต๋ถ์ฐ์ ๋๋ค. ์ด์ ๊ณต๋ถ์ฐ ํ๋ ฌ์ ์ผ๋ฐ์์ผ๋ก ๋ง๋ค์ด์ค๋๋ค.
๋ฒ ๋ฅธํ๋ฅดํธ ์์ฝํ๋ ์ด ๋ฐฉ์์ ์ผ๋ฐํํด ํ์ด๋ฅผ ํตํ ๋น์ ํ ํน์ฑ ์กฐํฉ์ผ๋ก ์๋ณธ ํน์ฑ๊ณต๊ฐ์ ์ํ๊ฐ ์ ๊ณฑ์ ๋์ฒดํ์ต๋๋ค. ๊ทธ ์์ด ์๋์ ๊ฐ ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋์ ๊ณ ์ ๋ฒกํฐ๋ฅผ ์ป๊ธฐ ์ํด ์๋ ์์ ํ์ด์ค๋๋ค.
์ฌ๊ธฐ์ ๋๋ค์ v๋ ๊ณต๋ถ์ฐ ํ๋ ฌ์ ๊ณ ์ณ๊ฐ๊ณผ ๊ณ ์ ๋ฒกํฐ์ ๋๋ค. a๋ ์ปค๋(์ ์ฌ๋) ํ๋ ฌ K์ ๊ณ ์ ๋ฒกํฐ๋ฅผ ์ถ์ถํจ์ผ๋ก์จ ๊ตฌํ ์ ์์ต๋๋ค.
์ปค๋ SVM์ ์๊ฐํด๋ณด๋ฉด ์ปค๋ ํธ๋ฆญ์ ์ฌ์ฉํด ์ํ x๋ผ๋ฆฌ์ ํ์ด ํจ์ ์ ๊ณฑ์ ์ปค๋ ํจ์ K๋ก ๋ฐ๊ฟ ๊ณ ์ ๋ฒกํฐ๋ฅผ ๊ณ์ฐํ ํ์๊ฐ ์์์ต๋๋ค.
์ปค๋ PCA๋ ๊ทธ๋ฅ PCA์ฒ๋ผ ํฌ์ํ๋ ฌ์ ๊ตฌ์ฑํ ๊ฒ ์๋๋ผ ๊ฐ๊ฐ ์ฑ๋ถ์ ์ด๋ฏธ ํฌ์๋ ์ํ์ ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ปค๋์ ๋ ๋ฒกํฐ ์ฌ์ด์ ์ ๊ณฑ์ ๊ณ์ฐํ ์ ์๋ ํจ์์ ๋๋ค. ์ฆ ์ ์ฌ๋๋ฅผ ์ธก์ ํ ์ ์๋ ํจ์์ธ ๊ฒ์ด์ฃ .
๊ฐ์ฅ ๋๋ฆฌ ์ฌ์ฉ๋๋ ์ปค๋์ ์๋์ ๊ฐ์ต๋๋ค.
1. ๋คํญ ํฐ๋ - ์ธํ๋ ์๊ณ๊ฐ์ด๊ณ P๋ ์ฌ์ฉ์๊ฐ ์ง์ ํ ๊ฑฐ๋ญ์ ๊ณฑ
2. ํ์ดํผ๋ณผ๋ฆญ ํ์ ํธ ์ปค๋
3. ๋ฐฉ์ฌ ๊ธฐ์ ํจ์ ํน์ ๊ฐ์ฐ์์ ์ปค๋
์ง๊ธ๊น์ง ๋ฐฐ์ด ๊ฒ์ ์์ฝํ๋ฉด ์ปค๋ PCA๋ฅผ ๊ตฌํํ๊ธฐ ์ํด ๋ค์ ์ธ ๋จ๊ณ๋ฅผ ์ ์ํ ์ ์์ต๋๋ค.
์ปค๋ ํ๋ ฌ K๋ฅผ ๊ณ์ฐํ๊ณ ์ํ์ ๋ชจ๋ ์์ ๋ํด ๊ตฌํฉ๋๋ค.
์๋ ์์ ์ฌ์ฉํด ์ปค๋ ํ๋ ฌ K๋ฅผ ์ค์์ ๋ง์ถฐ์ค๋๋ค. ์ฌ๊ธฐ์ฌ In์ ๋ชจ๋ ๊ฐ์ด 1/n์ธ n * n ์ฐจ์ ํ๋ ฌ์ ๋๋ค.
3. ๊ณ ์ณ๊ฐ ํฌ๊ธฐ๋๋ก ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌํด์ ์ค์์ ๋ง์ถ ์ปค๋ ํ๋ ฌ ์ค ์ต์์ k๊ฐ ๋ฒกํฐ๋ฅผ ๊ณ ๋ฆ ๋๋ค. ์ฌ๊ธฐ์ ๊ณ ์ ๋ฒกํฐ๋ ์ฃผ์ฑ๋ถ ์ถ์ ์๋๋๋ค.์ด๋ฏธ ์ด ์ถ์ ํฌ์๋ ์ํ์ ๋๋ค.
์ฌ๊ธฐ์ ์ ์ปค๋ ํ๋ ฌ์ ์ค์์ ๋ง์ถ์๋์ง ๊ถ๊ธํ์์ฃ ? ์์ ์ฐ๋ฆฌ๋ ์ด๋ฏธ ํ์คํ ์ ์ฒ๋ฆฌ๋ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฌ๋ค๊ณ ๊ฐ์ ํ๊ณ , ๊ณต๋ถ์ฐ ํ๋ ฌ ๊ตฌ์ฑ ํ ๋น์ ํ ํน์ฑ ์กฐํฉ์ ์ ๊ณฑ์ ํ์ด๋ฅผ ์ด์ฉํ ๋น์ ํ ํน์ฑ ์กฐํฉ์ผ๋ก ์ ๊ณฑ ๋์ฒดํ ๋ ๋ชจ๋ ํน์ฑ ํ๊ท ์ด 0์์ ๊ธฐ์ตํ์์ฃ ?
ํ์ง๋ง ์๋ก์ ํน์ฑ ๊ณต๊ฐ์ ๊ณ์ฐํ์ง ์๊ธฐ ๋๋ฌธ์ ์ด ํน์ฑ ๊ณต๊ฐ์ด ์ค์์ธ์ง ํ์ ํ ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
2. ํ์ด์ฌ์ผ๋ก ์ปค๋ PCA ๊ตฌํํ๊ธฐ
์ฌ์ดํ์ด์ ๋ํ์ด ํฌํผ ํจ์๋ฅผ ์ฌ์ฉํด ์ปค๋ PCA๋ฅผ ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค.
from scipy.spatial.distance import pdist, squareform
from scipy import exp
from scipy.linalg import eigh
import numpy as np
def rbf_kernel_pca(X, gamma, n_components):
# MxN ์ฐจ์์ ๋ฐ์ดํฐ์
์์ ์ํ ๊ฐ์ ์ ํด๋ฆฌ๋์ ๊ฑฐ๋ฆฌ์ ์ ๊ณฑ์ ๊ณ์ฐํฉ๋๋ค.
sq_dists = pdist(X, 'sqeuclidean')
# ์ํ ๊ฐ์ ๊ฑฐ๋ฆฌ๋ฅผ ์ ๋ฐฉ ๋์นญ ํ๋ ฌ๋ก ๋ณํํฉ๋๋ค.
mat_sq_dists = squareform(sq_dists)
# ์ปค๋ ํ๋ ฌ์ ๊ณ์ฐํฉ๋๋ค.
K = exp(-gamma * mat_sq_dists)
# ์ปค๋ ํ๋ ฌ์ ์ค์์ ๋ง์ถฅ๋๋ค.
N = K.shape[0]
one_n = np.ones((N, N)) / N
K = K - one_n.dot(K) - K.dot(one_n) + one_n.dot(K).dot(one_n)
# ์ค์์ ๋ง์ถฐ์ง ์ปค๋ ํ๋ ฌ์ ๊ณ ์ณ๊ฐ๊ณผ ๊ณ ์ ๋ฒกํฐ๋ฅผ ๊ตฌํฉ๋๋ค.
# scipy.linalg.eigh ํจ์๋ ์ค๋ฆ์ฐจ์์ผ๋ก ๋ฐํํฉ๋๋ค.
eigvals, eigvecs = eigh(K)
eigvals, eigvecs = eigvals[::-1], eigvecs[:, ::-1]
# ์ต์์ k ๊ฐ์ ๊ณ ์ ๋ฒกํฐ๋ฅผ ์ ํํฉ๋๋ค(๊ฒฐ๊ณผ๊ฐ์ ํฌ์๋ ์ํ์
๋๋ค).
X_pc = np.column_stack([eigvecs[:, i]
for i in range(n_components)])
return X_pc
์ฐจ์ ์ถ์์ RBF ์ปค๋ PCA๋ฅผ ์ฌ์ฉํ๋ ๋จ์ ์ ์ฌ์ ์ ๋๋ค ๋งค๊ฐ๋ณ์๋ฅผ ์ง์ ํด์ผ ํ๋๋ฐ, ์ ์ ํ ๊ฐ์ ์ฐพ๊ธฐ ์ํด ์คํ์ด ํ์ํ๋ค๋ ์ ์ ๋๋ค. ์ด ๋ค์ ์ธ์ ๋ค์์ ์๊ฐํ ๊ทธ๋ฆฌ๋ ์์น์ ๊ฐ์ ํ๋ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ต์ ์ ๋๋ค.
์ด์ ์์ ๋ ๊ฐ์ง๋ฅผ ์ฌ์ฉํด ์คํํ๋๋ก ํ๊ฒ ์ต๋๋ค. ์ฒซ ๋ฒ์งธ, ๋ฐ๋ฌ๋ชจ์ ๊ตฌ๋ถํ๊ธฐ ์ ๋๋ค. ๋จผ์ ๋ฐ์ดํฐ ์ ์ ๋ง๋ค์ด์ค๋๋ค.
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
X, y = make_moons(n_samples=100, random_state=123)
plt.scatter(X[y == 0, 0], X[y == 0, 1], color='red', marker='^', alpha=0.5)
plt.scatter(X[y == 1, 0], X[y == 1, 1], color='blue', marker='o', alpha=0.5)
plt.tight_layout()
plt.show()
ํ์คํ ๋น์ ํ ๋ฐ์ดํฐ์ด์ฃ ? ์ด์ ์ปค๋ PCA๋ก ํผ์ณ์ ์ ํ ๋ถ๋ฅ๊ธฐ์ ์ ํฉํ๊ฒ ๋ง๋ค์ด ์ค๋๋ค. ๋จผ์ , ๊ธฐ๋ณธ PCA์ ํฌ์ํ๋ฉด ์ด๋ป๊ฒ ๋ณด์ด๋์ง๋ถํฐ ํ์ธํด๋ณด๊ฒ ์ต๋๋ค.
from sklearn.decomposition import PCA
scikit_pca = PCA(n_components=2)
X_spca = scikit_pca.fit_transform(X)
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(7, 3))
ax[0].scatter(X_spca[y == 0, 0], X_spca[y == 0, 1],
color='red', marker='^', alpha=0.5)
ax[0].scatter(X_spca[y == 1, 0], X_spca[y == 1, 1],
color='blue', marker='o', alpha=0.5)
ax[1].scatter(X_spca[y == 0, 0], np.zeros((50, 1)) + 0.02,
color='red', marker='^', alpha=0.5)
ax[1].scatter(X_spca[y == 1, 0], np.zeros((50, 1)) - 0.02,
color='blue', marker='o', alpha=0.5)
ax[0].set_xlabel('PC1')
ax[0].set_ylabel('PC2')
ax[1].set_ylim([-1, 1])
ax[1].set_yticks([])
ax[1].set_xlabel('PC1')
plt.tight_layout()
plt.show()
ํ์คํ ์ค๋ฅธ์ชฝ ๊ทธ๋ฆผ์ ์ ํด์ง๊ธฐ๋ ํ์ง๋ง ์ ํ์ ์ผ๋ก ๊ตฌ๋ถํ๊ธฐ๋ ํ๋ค์ด ๋ณด์ ๋๋ค. ์ฐ๋ฆฌ๋ ๊ฒน์น ๋ถ๋ถ์ ์ ๋ํ๋ด๊ธฐ ์ํด์ ์ปค๋ PCA ํจ์ rbf_kernel_pca๋ฅผ ์ ์ฉํด๋ด ์๋ค.
X_kpca = rbf_kernel_pca(X, gamma=15, n_components=2)
fig, ax = plt.subplots(nrows=1,ncols=2, figsize=(7,3))
ax[0].scatter(X_kpca[y==0, 0], X_kpca[y==0, 1],
color='red', marker='^', alpha=0.5)
ax[0].scatter(X_kpca[y==1, 0], X_kpca[y==1, 1],
color='blue', marker='o', alpha=0.5)
ax[1].scatter(X_kpca[y==0, 0], np.zeros((50,1))+0.02,
color='red', marker='^', alpha=0.5)
ax[1].scatter(X_kpca[y==1, 0], np.zeros((50,1))-0.02,
color='blue', marker='o', alpha=0.5)
ax[0].set_xlabel('PC1')
ax[0].set_ylabel('PC2')
ax[1].set_ylim([-1, 1])
ax[1].set_yticks([])
ax[1].set_xlabel('PC1')
plt.tight_layout()
plt.show()
์ด๋ ๊ฒ ์์ ๋ฐ์ดํฐ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
๋ ๋ฒ์งธ ์์ ๋ ์์ ๋ถ๋ฆฌํ๋ ๊ฒ์ ๋๋ค. ์ผ๋จ ๋ฐ์ดํฐ๋ฅผ ํ์ธํด๋ณด๊ฒ ์ต๋๋ค.
from sklearn.datasets import make_circles
X, y = make_circles(n_samples=1000, random_state=123, noise=0.1, factor=0.2)
plt.scatter(X[y == 0, 0], X[y == 0, 1], color='red', marker='^', alpha=0.5)
plt.scatter(X[y == 1, 0], X[y == 1, 1], color='blue', marker='o', alpha=0.5)
plt.tight_layout()
plt.show()
์ฌ๊ธฐ์๋ ๋จผ์ ๊ธฐ๋ณธ PCA๋ฅผ ์ ์ฉํด๋ด ์๋ค.
scikit_pca = PCA(n_components=2)
X_spca = scikit_pca.fit_transform(X)
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(7, 3))
ax[0].scatter(X_spca[y == 0, 0], X_spca[y == 0, 1],
color='red', marker='^', alpha=0.5)
ax[0].scatter(X_spca[y == 1, 0], X_spca[y == 1, 1],
color='blue', marker='o', alpha=0.5)
ax[1].scatter(X_spca[y == 0, 0], np.zeros((500, 1)) + 0.02,
color='red', marker='^', alpha=0.5)
ax[1].scatter(X_spca[y == 1, 0], np.zeros((500, 1)) - 0.02,
color='blue', marker='o', alpha=0.5)
ax[0].set_xlabel('PC1')
ax[0].set_ylabel('PC2')
ax[1].set_ylim([-1, 1])
ax[1].set_yticks([])
ax[1].set_xlabel('PC1')
plt.tight_layout()
plt.show()
์ฌ๊ธฐ์๋ ๊ธฐ๋ณธ PCA๋ ์ ํ ๋ถ๋ฅ๊ธฐ์ ์ ํฉํ ๊ฒฐ๊ณผ๋ฅผ ๋ผ ์ ์์ต๋๋ค. ์ด์ ์ ์ ํ ๋๋ค ๊ฐ์ ์ฃผ๊ณ RBF ์ปค๋ PCA ๊ตฌํ์ ์ฌ์ฉํด๋ณด๊ฒ ์ต๋๋ค.
X_kpca = rbf_kernel_pca(X, gamma=15, n_components=2)
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(7, 3))
ax[0].scatter(X_kpca[y == 0, 0], X_kpca[y == 0, 1],
color='red', marker='^', alpha=0.5)
ax[0].scatter(X_kpca[y == 1, 0], X_kpca[y == 1, 1],
color='blue', marker='o', alpha=0.5)
ax[1].scatter(X_kpca[y == 0, 0], np.zeros((500, 1)) + 0.02,
color='red', marker='^', alpha=0.5)
ax[1].scatter(X_kpca[y == 1, 0], np.zeros((500, 1)) - 0.02,
color='blue', marker='o', alpha=0.5)
ax[0].set_xlabel('PC1')
ax[0].set_ylabel('PC2')
ax[1].set_ylim([-1, 1])
ax[1].set_yticks([])
ax[1].set_xlabel('PC1')
plt.tight_layout()
plt.show()
3. ์๋ก์ด ๋ฐ์ดํฐ ํฌ์ธํธ ํฌ์
์ด์ ๊น์ง๋ ํ๋์ ๋ฐ์ดํฐ์ ์ ์๋ก์ด ํน์ฑ์ ํฌ์ํ์ง๋ง, ์ค์ ์์๋ ๋ณํํด์ผํ ๋ฐ์ดํฐ์ ์ด ํ๋ ์ด์์ ๋๋ค. ์๋ฅผ ๋ค๋ฉด ํ๋ จ๊ณผ ํ ์คํธ ๋ฐ์ดํฐ์ฒ๋ผ ๋ง์ด์ฃ .
PCA์์๋ ๋ณํํ๋ ฌ W์ ์ ๋ ฅ ์ํ์ ์ ๊ณฑ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ํฌ์ํ์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์ปค๋ PCA๋ ์ด๋จ๊น์? ์ปค๋ PCA๋ ์ค์ฌ์ ๋ง์ถ ์ปค๋ ํ๋ ฌ์ ๊ณ ์ ๋ฒกํฐ๋ฅผ ๊ตฌํ์ต๋๋ค. ๋ฐ๋ผ์ ์ํ์ ์ด๋ฏธ ์ฃผ์ฑ๋ถ ์ถ์ธ v์ ๋ค์ด์์ต๋๋ค. ์๋ก์ด ์ํ x'๋ฅผ ํฌ์ํ๊ธฐ ์ํด์๋ ์๋๋ฅผ ๊ณ์ฐํด์ผํฉ๋๋ค.
๋คํํ ์ฐ๋ฆฌ๋ ์ปค๋ ํธ๋ฆญ์ ์ฌ์ฉํ๋ฏ๋ก ์ด๊ฒ์ ๊ณ์ฐํ ํ์๋ ์์ต๋๋ค. ์ผ๋ฐ PCA์ ์ปค๋ PCA์ ๋ค๋ฅธ ์ ์ ๋ฉ๋ชจ๋ฆฌ ๊ธฐ๋ฐ์ด๋ผ๋ ๊ฒ์ ๋๋ค. ์ฆ ์๋ก์ด ์ํ์ ํฌ์ํ๊ธฐ ์ํด์๋ ๋งค๋ฒ ์๋ณธ ํ๋ จ ์ธํธ๋ฅผ ์ฌ์ฌ์ฉํด์ผํฉ๋๋ค.
ํ๋ จ ์ธํธ์ i๋ฒ์งธ ์ํ๊ณผ ์๋ก์ด ์ํ x'์ฌ์ด์ RBF ์ ์ฌ๋๋ฅผ ๊ณ์ฐํด์ผํฉ๋๋ค.
์ปค๋ ํ๋ ฌ K์ ๊ณ ์ ๋ฒกํฐ a์ ๊ณ ์ณ๊ฐ ๋๋ค๋ ์๋ ๊ด๊ณ๋ฅผ ๋ง์กฑํฉ๋๋ค.
from scipy import exp
from scipy.linalg import eigh
import numpy as np
def rbf_kernel_pca(X, gamma, n_components):
# MxN ์ฐจ์์ ๋ฐ์ดํฐ์
์์ ์ํ ๊ฐ์ ์ ํด๋ฆฌ๋์ ๊ฑฐ๋ฆฌ์ ์ ๊ณฑ์ ๊ณ์ฐํฉ๋๋ค.
sq_dists = pdist(X, 'sqeuclidean')
# ์ํ ๊ฐ์ ๊ฑฐ๋ฆฌ๋ฅผ ์ ๋ฐฉ ๋์นญ ํ๋ ฌ๋ก ๋ณํํฉ๋๋ค.
mat_sq_dists = squareform(sq_dists)
# ์ปค๋ ํ๋ ฌ์ ๊ณ์ฐํฉ๋๋ค.
K = exp(-gamma * mat_sq_dists)
# ์ปค๋ ํ๋ ฌ์ ์ค์์ ๋ง์ถฅ๋๋ค.
N = K.shape[0]
one_n = np.ones((N, N)) / N
K = K - one_n.dot(K) - K.dot(one_n) + one_n.dot(K).dot(one_n)
# ์ค์์ ๋ง์ถฐ์ง ์ปค๋ ํ๋ ฌ์ ๊ณ ์ณ๊ฐ๊ณผ ๊ณ ์ ๋ฒกํฐ๋ฅผ ๊ตฌํฉ๋๋ค.
# scipy.linalg.eigh ํจ์๋ ์ค๋ฆ์ฐจ์์ผ๋ก ๋ฐํํฉ๋๋ค.
eigvals, eigvecs = eigh(K)
eigvals, eigvecs = eigvals[::-1], eigvecs[:, ::-1]
# ์ต์์ k ๊ฐ์ ๊ณ ์ ๋ฒกํฐ๋ฅผ ์ ํํฉ๋๋ค(ํฌ์ ๊ฒฐ๊ณผ).
alphas = np.column_stack([eigvecs[:, i]
for i in range(n_components)])
# ๊ณ ์ ๋ฒกํฐ์ ์์ํ๋ ๊ณ ์ณ๊ฐ์ ์ ํํฉ๋๋ค.
lambdas = [eigvals[i] for i in range(n_components)]
return alphas, lambdas
์๋ก์ด ๋ฐ๋ฌ ๋ฐ์ดํฐ์ ์ ๋ง๋ค๊ณ ์์ ๋ ์ปค๋ PCA ๊ตฌํ์ผ๋ก 1์ฐจ์ ๋ถ๋ถ๊ณต๊ฐ์ ํฌ์ํ๊ฒ ์ต๋๋ค.
X, y = make_moons(n_samples=100, random_state=123)
alphas, lambdas = rbf_kernel_pca(X, gamma=15, n_components=1)
์๋ก์ด ์ํ์ ํฌ์ํ๊ธฐ ์ ์ 26๋ฒ์งธ ํฌ์ธํธ๊ฐ ์๋ก์ด ๋ฐ์ดํฐ ํฌ์ธํธ x'๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค.
x_new = X[25]
x_new
#array([1.8713, 0.0093])
x_proj = alphas[25] # ์๋ณธ ํฌ์
x_proj
#array([0.0788])
def project_x(x_new, X, gamma, alphas, lambdas):
pair_dist = np.array([np.sum((x_new - row)**2) for row in X])
k = np.exp(-gamma * pair_dist)
return k.dot(alphas / lambdas)
# ์๋ก์ด ๋ฐ์ดํฐํฌ์ธํธ๋ฅผ ํฌ์ํฉ๋๋ค.
x_reproj = project_x(x_new, X, gamma=15, alphas=alphas, lambdas=lambdas)
x_reproj
#array([0.0788])
๋ง์ง๋ง์ผ๋ก ํฌ์ํ ๊ฒ์ ๊ทธ๋ํ๋ก ๊ทธ๋ ค๋ณด๊ฒ ์ต๋๋ค.
plt.scatter(alphas[y == 0, 0], np.zeros((50)),
color='red', marker='^', alpha=0.5)
plt.scatter(alphas[y == 1, 0], np.zeros((50)),
color='blue', marker='o', alpha=0.5)
plt.scatter(x_proj, 0, color='black',
label='original projection of point X[25]', marker='^', s=100)
plt.scatter(x_reproj, 0, color='green',
label='remapped point X[25]', marker='x', s=500)
plt.legend(scatterpoints=1)
plt.tight_layout()
plt.show()
์ด๋ ๊ฒ ์๋ก์ด ๋ฐ์ดํฐ ํฌ์ธํธ x'๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ํฌ์๋์์ต๋๋ค.
4. ์ฌ์ดํท๋ฐ์ ์ปค๋ PCA
์ฌ์ดํท๋ฐ์ sklearn.decomposition ๋ชจ๋ ์๋์ ์ปค๋ PCA๋ฅผ ๊ตฌํํด๋์์ต๋๋ค. kernel ๋งค๊ฐ๋ณ์๋ก ์ปค๋ ์ข ๋ฅ๋ฅผ ์ง์ ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๊ฐ ๊ตฌํํ ์ปค๋ PCA์ ๋น๊ต๋ฅผ ์ํด ๋ณํ๋ ๋ฐ๋ฌ ๋ฐ์ดํฐ๋ฅผ ๋ ๊ฐ ์ฃผ์ฑ๋ถ์ ๊ทธ๋ ค๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
from sklearn.decomposition import KernelPCA
X, y = make_moons(n_samples=100, random_state=123)
scikit_kpca = KernelPCA(n_components=2, kernel='rbf', gamma=15)
X_skernpca = scikit_kpca.fit_transform(X)
plt.scatter(X_skernpca[y == 0, 0], X_skernpca[y == 0, 1],
color='red', marker='^', alpha=0.5)
plt.scatter(X_skernpca[y == 1, 0], X_skernpca[y == 1, 1],
color='blue', marker='o', alpha=0.5)
plt.xlabel('PC1')
plt.ylabel('PC2')
plt.tight_layout()
plt.show()
์ ๊ทธ๋ํ๋ฅผ ํตํด ์ฌ์ดํท๋ฐ์ kernelPCA ๊ฒฐ๊ณผ๋ ์ง์ ๊ตฌํํ ๊ฒ๊ณผ ๊ฐ์์ ์ ์ ์์ต๋๋ค.
์ฌ๊ธฐ๊น์ง ์ปค๋ PCA๋ฅผ ์์๋ณด์์ต๋๋ค. ์ฌ์ค ์ ๋ ์์ง๋ ๊ณ์ฐ ๋น์ฉ์ ์ค์ด๋ ์ปค๋ ํธ๋ฆญ์ ๋ํด์ ์ ๋๋ก ์ดํด๊ฐ ๋์ง ์์๋๋ฐ์ใ ใ ์ด ๋ถ๋ถ์ ๋ํด์๋ ์ดํ์ ๊ณต๋ถํด์ ์ด๋ป๊ฒ ์๋ํ๋์ง ์ถ๊ฐ๋ก ์ ๋ก๋(์์ ) ํ๋๋ก ํ๊ฒ ์ต๋๋ค.(2020.02.20) ๋ค์ ์ธ์ ์์๋ ๋ชจ๋ธ์ ํ๊ฐํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ๋ค๋ฃจ๋๋ก ํ๊ฒ ์ต๋๋ค. ๋ค์ ์ธ์ ์์ ๋ดฌ์!