Notice
Recent Posts
Recent Comments
Link
«   2026/03   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

My blog

[ML_week2_chap6] 차원축소 본문

ML

[ML_week2_chap6] 차원축소

gayoung 2026. 1. 27. 14:32

 

일반적으로 차원이 증가할 수록 데이터 포인터 간의 거리가 멀어져 희소한 구조를 가지게 된다.

수백 개 이상의 피처로 구성된 데이터 세트는 상대적으로 예측 신뢰도가 떨어진다 

다차원의 피처를 차원 축소해 더 직관적으로 데이터를 해석할 수 있다 

 

차원축소 :

고차원 데이터의 차원을 줄여  작은 차원의 데이터로 변환하는 기법으로

단순히 피처의 개수를 줄이는 것이 아니라 데이터를 더 잘 설명할 수 있는 잠재 요소를 추출하는 데 목적이 있다.

- 피처선택 : 불필요한 피처 제거  

- 피처추출 : 기존 피처를 저차원의 중요 피처로 압축, 데이터 잘 설명하는 잠재요소 추출 ex) PCA , SVD ,NMF

 

1. PCA  (주성분 , 새로운 축 분석) 

  1) 개념 및 특징 

-  비지도 학습 기법

-  데이터의 분산이 가장 큰 방향을 새로운 축(주성분)으로 설정. 분산이 클수록 데이터의 원래 특성을 가장 잘 유지

- 입력데이터 공분산 행렬이 고유벡터와 고유값으로 분해되고 분해된 고유벡터를 이용해 선형 변환하는 방식이다 

- 상관관계가 높은(중복성 큰거 하나의 새로운 축)  애들 가져옴

- 가장 큰 분산 방향 (첫번째 주성분) , 직교하면서 다음으로 큰 분산 ( 두번째 주성분) 

 2) 선형대수의 관점 (내부 작동 원리) 

- 입력데이터의 공분산 행렬(데이터들 상관관계와 퍼짐 정도)을 분석하여 정보 추출 

- 공분산 C : 고유벡터의 직교행렬 * 고유값 정방 행렬 * 고유벡터 직교행렬의 전치행렬로 분해

- P : 직교행렬  nxn : 공분산 행렬의 고유벡터들로 이루어짐 , 새로운 축의 방향을 결정 하며 축은 서로 직교 ,길이1 (방향)

- ∑ : 대각행렬 nxn : 주대각 성분에 고유값들이 큰 순서대로 나열 , 제외한 모든 값이 0 , 각 축 방향으로 (분산의 크기)

- 정방행렬(행크기 == 열 크기 ) 만 고유벡터로 분해가능

 

3) PCA 수행 메커니즘

- 내부적으로 SVD(특이값 분해) 엔진 사용해 행렬 분해

- PCA전 반드시 스케일링 (왜곡방지)

- 선형 변환 : 원본 데이터를 고유벡터 행렬 P에 투영해 새로운 차원의 좌표값으로 변환

# 스케일링
iris_scaled = StandardScaler().fit_transform(irisDF.iloc[:,:-1])

# 차원변환
pca = PCA(n_components=2) 

# pca 학습 / 변환 
pca.fit(iris_scaled)
iris_pca = pca.transform(iris_scaled) # 넘파이로 나옴 
#(150,4) -> (150,2) 

# 변동성 비율 제공 - fit()후 사용가능
print(pca.explained_variance_ratio_) 

# 교차 검증 정확도 
pca_X = irisDF_pca[['pca_component_1','pca_component_2']]  # DF
scores_pca = cross_val_score(rcf,pca_X,iris.target,scoring='accuracy',cv=3)
print(np.mean(scores_pca))

 

 

2. LDA (선형 판별 분석 ) 

- 지도학습 기법 : 레이블 활용 

- 입력 데이터의 결정 값 클래스를 최대한 분리할 수있는 축 (클래스간 분산 , 클래스 내부 분산 행렬 -> 고유벡터구함)

- 데이터가 가우시안 정규 분포를 따른다고 가정할 때 성느이 좋음 

- 클래스 개수 -1 까지만 차원수 가능 

 

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

iris = load_iris()
# 스케일링
iris_scaled = StandardScaler().fit_transform(iris.data)
# LDA 객체 생성 
lda = LinearDiscriminantAnalysis(n_components=2)

# LDA 변환  ✔️ fit 할때 target도 같이 넣어야함  
lda.fit(iris_scaled,iris.target) 
iris_lda = lda.transform(iris_scaled)

 

 

3. SVD (특이값 분해) 

- 정방행렬뿐만 아니라 행과 열의 크기가 다른 모든 행렬을  특정 행렬 곱으로 분해가능

- 넘파이 , 사이파이 라이브러리이용 

- 희소 데이터 (0이 많은 행렬)에도 적용가능 

- U : 직교행렬(mxm) , 행사이의 관계 (방향)

- ∑ : 대각행렬(mxn) , 특이값이 큰 순서대로 나열 , 값이 클 수록 해당 축이 가진 정보량이 큼

- V : 직교행렬 (nxn), 열 사이의 관계 , 원본 변수들이 새로운 축을 만드는데 기여하는 정보

 

- Full SVD: 원본 행렬을 손실 없이 전부 분해 (메모리 낭비가 심함).

- Truncated SVD (절단된 SVD): Sigma에서 값이 큰 상위 k개만 남기고 나머지는 버리는 방식

 -> 의 비대각 부분,대각원소 중 특이값이 0인 부분 다 제거하고 mxn = mxp pxp pxn으로 분해

 

import numpy as np
from numpy.linalg import svd

np.random.seed(121)
a = np.random.randn(4,4)

#svd 분해 
U,Sigma,Vt = svd(a)
# sigma를 다시 0을 포함한 대칭 행렬로 변환 
Sigma_mat = np.diag(Sigma) # 대각선에만 숫자 있고 나머지는 0 으로 만
a_=np.dot(np.dot(U,Sigma_mat),Vt)

# 로우간의 의존성
a[2]=a[0]+a[1]
a[3]=a[0]
# SVD 수행
U,Sigma,Vt = svd(a)
# U행렬은 시그마와 내적을 수행하니까 앞 2행에 해당하는 앞 2열만 추출
U_ = U[:,:2]
Sigma_ = np.diag(Sigma[:2])
#V 전치 행렬의 경우는 앞 2행만 추출
Vt_ = Vt[:2
a_=np.dot(np.dot(U_,Sigma_),Vt_)

 

Truncated svd(희소행렬로만 지원) 는 넘파이X 사이파이에서만 가능 svds

# Truncated SVD - 시그마 행렬에 있는 대각원소 , 즉 특이값 중 상위 일부 데이터만 추출해 분해 
from scipy.sparse.linalg import svds
from scipy.linalg import svd

np.random.seed(121)
matrix = np.random.random((6,6))

# Truncated SVD로 Sigma행렬의 특이값을 4개로 하여 t svd 수행 
num_components = 4
U_tr , Sigma_tr,Vt_tr = svds(matrix,k=num_components) # 상위 k개만 골라 분해함
matrix_tr = np.dot(np.dot(U_tr,np.diag(Sigma_tr)),Vt_tr)

 

Truncated svd - 사이킷런에서는 U,sigma,Vt행렬 반환 X fit ,transform

- 희소행렬에 바로 svd 수행하는 것이 pca와의 차이점 , 즉 스케일링해서 데이터 중심 동일하면 동일한 변환이됨 

-pca : 밀집행렬에만 변환 / svd는 희소행렬에서도 가능하다는 점이 다름 

# 사이킷런 TruncatedSVD 클래스를 이용한 변환 
from sklearn.decomposition import TruncatedSVD,PCA

iris = load_iris()
iris_ftrs = iris.data

#2개의 주요 컴포넌트로 TruncatedSVD 변환

tsvd = TruncatedSVD(n_components=2)
tsvd.fit(iris_ftrs)
iris_tsvd = tsvd.transform(iris_ftrs)

 

 

4. NMF

- truncated SVD와 같이 낮은 랭크를 통한 행렬 근사 방식 : 고차원 행렬 -> 두개의 저차원 행렬로 

- 원본 행렬 내의 모든 원소값이 모두 양수 -> 두개 기반 양수행렬로 분해

nmf = NMF(n_components=2)
nmf.fit(iris_ftrs)
iris_nmf = nmf.transform(iris_ftrs)

 

 

알고리즘 성격 원리 주요특징 
PCA 비지도 분산이 가장 큰 축 찾기 - 데이터 복잡성 줄임 , 보편적 
- 선형적인 구조만 파악가능
- 고차원 데이터 시각화 ,성능향상 전처리 
LDA 지도 클래스 간 분리 최대 - 데이터 분별력 최대한 유지 - 클래스간 경계 
- 정답개수보다 많은 차원으로 줄일 수없음 , 정규분포를 따라야 성능 좋음 
- 얼굴인식 , 마켓팅 분류 등 분류 문제 전처리
SVD 수학적 행렬을 U,Sigma,V^T로 분해 - 행과 열이 달라도 쓸 수있고,  0이 많은 상황에서도 안정적
- 데이터 양이 많으면 계산량이 많아짐 
- 추천시스템 , 텍스트 마이닝 , 이미지 압축
NMF 비지도 음수 미포함 행렬분해 - 모든 결과값 양수라 작은게 모여 전체 
- 데이터 음수면 사용 불가
- 토픽 모델량 

 

'ML' 카테고리의 다른 글

[ML_week4_chap3] 평가  (0) 2026.02.10
[ML_week3_chap5] 회귀  (0) 2026.02.03
[ML_week2_chap2] 사이킷런  (0) 2026.01.24
[ML_week1_chap10] 시각화  (0) 2026.01.19
[ML_week1_chap1] Numpy , Pandas  (0) 2026.01.19