TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 머신러닝>

[머신러닝] 차원 축소: 랜덤 투영, 지역 선형 임베딩

by 기록자_Recordian 2024. 11. 15.
728x90
반응형
차원축소란?
 

[머신러닝] 차원 축소(Dimension Reduction)

차원 축소(Dimension Reduction)차원 축소의 중요한 의미는차원 축소를 통해 좀 더 데이터를 잘 설명할 수 있는잠재적인 요소를 추출하는 데 있다.차원 축소: 매우 많은 피처로 구성된 다차원 데이터

puppy-foot-it.tistory.com


랜덤 투영

 

랜덤 투영은 간단하고 빠르며 메모리 효율이 높고 강력한 차원 축소 알고리즘으로, 특히 고차원 데이터셋을 다룰 때 염두에 두어야 한다.

 

랜덤 투영 알고리즘은 랜덤한 선형 투영을 사용하여 데이터를 저차원 공간에 투영한다. 이러한 랜덤 투영은  실제로 거리를 상당히 잘 보존할 가능성이 매우 높다는 것이 존슨과 린덴스트라우스가 수학적으로 증명해 냄에 따라 투영 후에도 비슷한 두 개의 샘플은 비슷한 채로 남고 매우 다른 두 개의 샘플은 매우 다른 채로 남는다.

 

물론 더 많은 차원을 삭제할수록 더 많은 정보가 손실되고 더 많은 거리가 왜곡되는데, 최적의 차원 수는 존슨과 린덴스트라우스는 거리가 주어진 허용 오차 이상으로 변하지 않도록 보장하기 위해 보존할 최소 차원 수를 결정하는 방정식을 생각해냈고, 이 방정식은 johnson_lindenstrauss_min_dim() 함수에 구현되어 있다.

from sklearn.random_projection import johnson_lindenstrauss_min_dim
m, e = 5_000, 0.1
d = johnson_lindenstrauss_min_dim(m, eps=e)
d

 

이제 각 항목을 평균 0, 분산 1/d 의 가우스 분포에서 랜덤 샘플링한 [d,n] 크기의 랜덤 행렬 P를 생성하고 이를 사용하여 데이터셋을 n차원에서 d 차원으로 투영할 수 있다.

n = 20_000
np.random.seed(42)
P = np.random.randn(d, n) / np.sqrt(d) # 표준 편차 = 분산의 제곱근

X = np.random.randn(m, n) # 가짜 데이터셋 생성
X_reduced = X @ P.T

 

알고리즘이 랜덤한 행렬을 생성하는 데 필요한 것은 데이터셋의 크기뿐이므로 간단하고 효율적이며 훈련이 필요하지 않아 데이터 자체는 전혀 사용되지 않았다.

 

[사이킷런에서의 랜덤 투영]

1) GaussianRandomProjection 클래스

사이킷런은 위와 정확히 같은 작업을 수행할 수 있는 GaussianRandomProjection 클래스를 제공하며, 이 클래스의 fit() 메서드를 호출하면 johnson_lindenstrauss_min_dim()을 사용해 출력 차원을 결정한 다음 랜덤한 행렬을 생성하여 components_ 속성에 저장한다.

그런 다음 transform()을 호출하면 이 행렬을 사용하여 투영을 수행한다. 이 변환기를 만들 때 엡실론(e)을 조정하려면 eps 매개변수를 설정하고 (기본값: 0.1), 특정 차원 d를 강제로 적용하려면 n_components 매개변수를 설정할 수 있다.

from sklearn.random_projection import GaussianRandomProjection

gaussian_rnd_proj = GaussianRandomProjection(eps=e, random_state=42)
X_reduced = gaussian_rnd_proj.fit_transform(X)

 

2) SparseRandomProjection 클래스

사이킷런은 SparseRandomProjection 라는 두 번째 랜덤 투영 변환기도 제공하는데, 이 변환기는 동일한 방식으로 타깃 차원을 결정하고 동일한 크기의 랜덤 행렬을 생성한 후 투영을 동일하게 수행한다.

 

둘의 큰 차이점은

  • 랜덤 행렬이 희소하다는 것인데, 메모리가 훨씬 적게 사용된다 (이전 예제 기준 - GaussianRandomProjection: 약 1.2GB, SparseRandomProjection: 약 25MB)
  • 랜덤 행렬을 생성하고 차원을 줄이는 데 있어서도 훨씬 빠르다. (SparseRandomProjection이 약 50% 더 빠름)
  • 입력이 희소할 경우 SparseRandomProjection 변환은 희소성을 유지한다 (dense_output=True 로 설정하지 않을 경우)
  • 이전 접근 방식과 동일한 거리 보존 속성을 가지며 차원 축소 품질도 비슷하다

▶ 일반적으로 특히 규모가 크거나 희박한 데이터셋의 경우 첫 번째 변환기 대신 SparseRandomProjection 변환기를 사용하는 것이 더 바람직하다.

 

다음은 GaussianRandomProjection 과 SparseRandomProjection의 성능을 비교해 보는 코드이다.

from sklearn.random_projection import SparseRandomProjection

print("GaussianRandomProjection fit")
%timeit GaussianRandomProjection(random_state=42).fit(X)
print("SparseRandomProjection fit")
%timeit SparseRandomProjection(random_state=42).fit(X)

gaussian_rnd_proj = GaussianRandomProjection(random_state=42).fit(X)
sparse_rnd_proj = SparseRandomProjection(random_state=42).fit(X)
print("GaussianRandomProjection transform")
%timeit gaussian_rnd_proj.transform(X)
print("SparseRandomProjection transform")
%timeit sparse_rnd_proj.transform(X)

 


지역 선형 임베딩 (LLE, locally linear embedding)

 

지역 선형 임베딩은 비선형 차원 축소(NLDR, nonlinear dimensionality reduction) 기술이며, PCA나 랜덤 투영과는 달리 투영에 의존하지 않는 매니폴드 학습이다. 즉, LLE는먼저 각 훈련 샘플이 최근접 이웃에 얼마나 선형적으로 연관되어 있는지 측정하고, 국부적인 관계가 가장 잘 보존되는 훈련 세트의 저차원 표현을 찾는다.

이 방법은 특히 잡음이 너무 많지 않은 경우 꼬인 매니폴드를 펼치는 데 좋다.

 

사이킷런은 LocallyLinearEmbedding 클래스를 제공한다.

스위스 롤을 만든 다음 사이킷런의 LocallyLinearEmbedding을 사용해 펼쳐보기.

from sklearn.datasets import make_swiss_roll
from sklearn.manifold import LocallyLinearEmbedding

X_swiss, t = make_swiss_roll(n_samples=1000, noise=0.2, random_state=42)
lle = LocallyLinearEmbedding(n_components=2, n_neighbors=10, random_state=42)
X_unrolled = lle.fit_transform(X_swiss)

변수 t는 스위스 롤의 회전 축을 따라 각 샘플의 위치를 포함하는 1차원 넘파이 배열이다. 

 

결과인 2D 데이터셋을 시각화해 본다.

plt.scatter(X_unrolled[:, 0], X_unrolled[:, 1],
            c=t, cmap=darker_hot)
plt.xlabel("$z_1$")
plt.ylabel("$z_2$", rotation=0)
plt.axis([-0.055, 0.060, -0.070, 0.090])
plt.grid(True)

plt.title("LLE를 사용하여 펼쳐진 스위스 롤")
plt.show()

▶ 스위스 롤이 완전히 펼쳐졌고 지역적으로는 샘플 간 거리가 잘 보존되어 있다. 그러나 펼쳐진 스위스 롤은 이렇게 늘어나거나 꼬인 밴드가 아닌 직사각형이어야 하는데, 그럼에도 불구하고 LLE는 매니폴드를 모델링하는 데 잘 작동한다.

 

LLE는 대규모 데이터셋에 적용하기는 어려우며, 투영 기법에 비해 훨씬 더 복잡하지만, 데이터가 비선형인 경우 훨씬 더 나은 저차원 표현을 구성할 수 있다.


다음 내용

 


[출처]

핸즈 온 머신러닝

728x90
반응형