Open njs03332 opened 2 years ago
from sklearn.manifold import LocallyLinearEmbedding
lle = LocallyLinearEmbedding(n_components=2, n_neighbors=10) X_reduced = lle.fit_transform(X)
- 결과 2D 데이터셋
- 스위스 롤이 완전히 펼쳐졌고 지역적으로는 샘플 간 거리가 잘 보존되어 있음
- 그러나 크게 보면 샘플 간 거리가 잘 유지되어있지 않음 (오른쪽은 압축되어있고 왼쪽은 확장되어있음)
- 그럼에도 불구하고 LLE는 매니폴드를 모델링하는 데 잘 동작함
<img width="771" alt="스크린샷 2022-08-30 오후 11 44 29" src="https://user-images.githubusercontent.com/37107740/187467659-d9bb37c9-4730-427b-be88-48a2823b47aa.png">
- LLE의 작동 방식
- 1) 알고리즘이 각 훈련샘플 x<sup>(i)</sup>에 대해 가장 가까운 k개의 샘플을 찾고, 이 이웃에 대한 선형 함수로 x<sup>(i)</sup>를 재구성함
- x<sup>(i)</sup>와 Σ<sup>m</sup><sub>j=1</sub>w<sub>i,j</sub>x<sup>(j)</sup> 사이의 제곱 거리가 최소가 되는 w<sub>i,j</sub>를 찾음
- 여기서 x<sup>(j)</sup>가 x<sup>(i)</sup>의 가장 가까운 k개 이웃 중 하나가 아닐 경우에는 w<sub>i,j</sub>=0이 됨
- 이는 곧 아래 식과 같은 제한이 있는 최적화 문제가 됨 (W는 가중치 w<sub>i,j</sub>를 모두 담은 가중치 행렬, 두번째 제약은 각 훈련 샘플에 대한 가중치를 정규화하는 것)
- 이 단계를 거치면 가중치 행렬 W^은 훈련 샘플 사이에 있는 지역 선형 관계를 담고 있음
<img width="692" alt="스크린샷 2022-08-30 오후 11 45 12" src="https://user-images.githubusercontent.com/37107740/187467773-35575a98-50b7-499f-871a-56432eae14fe.png">
- 2) 가능한 한 이 지역 선형 관계가 보존되도록 훈련 샘플을 d차원 공간 (d<n)으로 매핑함
- 만약 z<sup>(i)</sup>가 d차원 공간에서 x<sup>(i)</sup>의 상이라면 가능한 한 x<sup>(i)</sup>와 Σ<sup>m</sup><sub>j=1</sub>w<sub>i,j</sub>z<sup>(j)</sup> 사이의 거리가 최소화되어야 함
- 이는 곧 아래 식과 같은 최적화 문제가 됨
- 첫번째 단계와 달리 샘플을 고정하고 최적의 가중치를 찾는 대신 가중치를 고정하고 저차원의 공간에서 샘플 이미지의 최적 위치를 찾음
<img width="406" alt="스크린샷 2022-08-30 오후 11 45 25" src="https://user-images.githubusercontent.com/37107740/187467829-dcda7c37-d607-47dd-9e0b-74fa3c83d856.png">
- 사이킷런이 제공하는 LLE 구현의 계산 복잡도는 k개의 가장 가까운 이웃을 찾는데 O(nlog(m)nlog(k)), 가중치 최적화에 O(mnk<sup>3</sup>), 저차원 표현을 만드는 데 O(dm<sup>2</sup>)
- 마지막 항의 m<sup>2</sup> 때문에 이 알고리즘을 대량의 데이터셋에 적용하기는 어려움
## MDS
from sklearn.manifold import MDS
mds = MDS(n_components=2, random_state=42)
X_reduced_mds = mds.fit_transform(X)
## Isomap
from sklearn.manifold import Isomap
isomap = Isomap(n_components=2)
X_reduced_isomap = isomap.fit_transform(X)
## TSNE
from sklearn.manifold import TSNE
tsne = TSNE(n_components=2, random_state=42)
X_reduced_tsne = tsne.fit_transform(X)
from sklearn.decomposition import KernelPCA
rbf_pca = KernelPCA(n_components = 2, kernel='rbf', gamma = 0.04) # rbf 외 다른 커널로도 설정 가능 X_reduced = rbf_pca.fit_transform(X)
- <img width="595" alt="image" src="https://user-images.githubusercontent.com/26505830/187891110-bfb4281d-5e5e-4d23-bcf4-33a329963d00.png">
- kPCA는 비지도 학습이기 때문에 좋은 커널과 하이퍼파라미터를 선택하기 위한 명확한 성능 측정 기준이 없음
- 하지만 차원 축소는 지도 학습(ex. 분류)의 전처리 단계로 활용되므로 그리드 탐색을 사용하여 주어진 문제에서 성능이 가장 좋은
커널과 하이퍼파라미터를 선택할 수 있음
```python
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
## 1. kPCA를 사용해 차원을 2차원으로 축소하고
## 분류를 위해 로지스틱 회귀 적용
clf = Pipeline([
("kpca", KernelPCA(n_components=2)),
("log_reg", LogisticRegression())
])
param_grid = [{
"kpca__gamma": np.linspace(0.03, 0.05, 10),
"kpca__kernel": ["rbf", "sigmoid"]
}]
## 2. 가장 높은 분류 정확도를 얻기 위해 GridSearchCV를 사용해
## kPCA의 가장 좋은 커널과 gamma 파라미터를 찾기
grid_search=GridSearchCV(clf, param_grid, cv=3)
grid_search.fit(X,y)
## 3. 가장 좋은 커널과 하이퍼파라미터는 best_params_ 변수에 저장
print(grid_search.best_params_)
## 재구성 방법 예시
## 투영된 샘플을 훈련세트로, 원본 샘플을 타깃으로 하는 지도 학습 회귀 모델을 훈련
## fit_inverse_transform=True 로 지정하면 자동으로 수행
## + fit_inverse_transform=False 가 기본값이므로, inverse_transform 메서드는 해당 파라미터가 rue 일 때만 생성됨
rbf_pca = KernelPCA(n_components=2, kernel="rbf", gamma=0.0433, fit_inverse_transform=True)
X_reduced = rbf_pca.fit_transform(X)
X_preimage = rbf_pca.inverse_transform(X_reduced)
from sklearn.metrics import mean_squared_error mean_squared_error(X, X_preimage)