차원 축소: 매우 많은 피처로 구성된 다차원 데이터 세트의 차원을 축소해 새로운 차원의 데이터 세트를 생성하는 것
: 여러 변수 간에 존재하는 상관관계를 이용해 이를 대표하는 주성분을 추출해 차원을 축소하는 기법
기존 데이터의 정보 유실 최소화를 위해 가장 높은 분산을 가지는 데이터의 축을 찾아 이 축으로 차원 축소(분산이 데이터의 특성을 가장 잘 나타내는 것으로 간주)
첫 번째는 데이터 변동성이 가장 큰 축, 두 번째는 첫 번째 축과의 직교 벡터를 축으로 함.
: 입력 데이터의 공분산 행렬을 고유값 분해하고, 고유 벡터에 입력 데이터를 선형 변환하는 것.
Step 1: 입력 데이터 세트의 공분산 행렬 생성
Step 2: 공분산 행렬의 고유벡터와 고유값 게산
Step 3: 고유값이 가장 큰 순으로 K개(PCA 변환 차수)만큼 고유 벡터 추출
Step 4: 고유값이 가장 큰 순으로 추출된 고유벡터를 이용해 새롭게 입력 데이터 변환
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
#fit( )과 transform( ) 을 호출하여 PCA 변환 데이터 반환
pca.fit(iris_scaled)
iris_pca = pca.transform(iris_scaled)
print(iris_pca.shape)
print(pca.explained_variance_ratio_)
** 원본 데이터 세트 대비 PCA 변환된 데이터 세트의 예측 정확도는 떨어질 수밖에 없음.
@
: 선형 판별 분석법. 지도학습의 분류에서 사용하기 쉽도록 개별 클래스를 분별할 수 잇는 기준을 최대한 유지하면서 차원을 축소하는 방법.
Step 1: 클래스 내부와 클래스 간 분산 행렬을 구함(입력 데이터의 결정값 클래스별로 개별 피처의 평균 벡터를 기반으로)
Step 2: Sw(클래스 내부 분산 행렬), Su(클래스 간 분산 행렬)을 고유 벡터로 분해
Step 3: 고유값이 가장 큰 순으로 K개(LDA 변환 차수)만큼 추출
Step 4: 고유값이 가장 큰 순으로 추출된 고유벡터를 이용해 입력 데이터 변환
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
lda = LinearDiscriminantAnalysis(n_components=2)
lda.fit(iris_scaled, iris.target)
iris_lda = lda.transform(iris_scaled)
: 특이값 분해. m x n 크기의 행렬 A를 다음과 같이 분해하는 것.
일반적으로 Σ의 비대각인 부분, 대각 원소 중에 특이값이 0인 부분을 모두 제거하고, 제거된 Σ에 해당하는 U, V의 원소도 제거해 차원을 줄인 형태로 적용 (m x p, p x p, p x n)
분해한 행렬을 다시 내적하여 곱하면 원본 행렬로 완벽 복원 가능
scipy.linalg.svd 이용
from numpy.linalg import sv
U, Sigma, Vt = svd(a)
ex. 개별 로우끼리 관계 없는 경우
ex. 개별 로우끼리 의존하는 경우
3번째 = 1번째 + 2번째
4번째 = 번째
선형 독립인 로우 벡터의 개수가 2개임 => Sigma Value 0이 2개(행렬의 rank = 2)
: Σ의 대각 원소 중에 상위 몇 개만 추출해서 이에 대응하는 U, V의 원소도 제거해 차원을 줄인 형태로 분해
from scipy.sparse.linalg import svds
from scipy.linalg import svd
# 행렬의 특이값 = 4
num_components = 4
U_tr, Sigma_tr, Vt_tr = svds(matrix, k=num_components)
: 분해 행렬을 반환하지는 않지만, fit(), transfomr()을 호출하여 원본 데이터의 차원을 축소해 변환함
from sklearn.decomposition import TruncatedSVD
# 2개의 주요 component로 TruncatedSVD 변환
tsvd = TruncatedSVD(n_components=2)
tsvd.fit(iris_ftrs)
iris_tsvd = tsvd.transform(iris_ftrs)
plt.scatter(x=iris_tsvd[:,0], y= iris_tsvd[:,1], c= iris.target)
** 데이터 세트가 스케일링으로 데이터 중심이 동일해지면 사이킷런의 SVD와 PCA는 동일한 변환을 수행함. (=PCA가 SVD 알고리즘으로 구현되었음)
But, PCA는 밀집 행렬에 대한 변환만 가능한 반면, SVD는 희소 행렬(행렬값 대부분이 0인 행렬)에 대한 변환도 가능
from sklearn.decomposition import NMF
nmf = NMF(n_components=2)
nmf.fit(iris_ftrs)
iris_nmf = nmf.transform(iris_ftrs)
plt.scatter(x=iris_nmf[:,0], y= iris_nmf[:,1], c= iris.target)
<PCA와 LDA의 비교>
PCA는 변동성을 기준으로 차원 축소
LDA는 클래스를 유지하는 방향으로 차원 축소