⊢MachineLearning

비지도학습 : 차원축소 - PCA(Principal Component Analysis, 주성분 분석)

최 수빈 2025. 3. 17. 11:18

 

PCA(Principal Component Analysis, 주성분 분석)

 

고차원 데이터를 저차원으로 변환하는 차원 축소 기법

 

데이터의 분산을 최대한 보존하면서 주요 특징을 추출해 저차원 공간으로 변환

  • 이미지 압축 : 고차원 픽셀 데이터를 저차원으로 축소하여 공간 절약
  • 노이즈 제거 : PCA를 통해 데이터의 주요 특징만 남겨 노이즈 제거
  • 데이터 시각화 : 다차원 데이터를 2D 또는 3D로 변환하여 분석

 

작동 원리

  1. 데이터 표준화(Standardization)
    각 특성의 평균을 0, 분산을 1로 맞춤
  2. 공분산 행렬(Covariance Matrix) 계산
    데이터의 특성 간 관계 파악
  3. 고유값(Eigenvalue) 및 고유벡터(Eigenvector) 계산
    공분산 행렬을 분해하여 주성분(Principal Component) 추출
  4. 주성분 선택
    고유값이 큰 순서대로 주성분을 정렬하여 선택
    전체 분산의 95% 이상을 설명하는 주성분을 선택하는 것이 일반적
  5. 데이터 변환
    선택된 주성분을 사용하여 데이터를 저차원 공간으로 변환

 

PCA 실습

 

MNIST(Mixed National Institute of Standards and Technology) 데이터셋 활용

 

 

*MNIST(Mixed National Institute of Standards and Technology) 데이터셋

 

손으로 쓴 숫자(0~9)의 이미지로 구성된 머신러닝 및 딥러닝의 대표적인 벤치마크 데이터셋

  • 구성
    0부터 9까지의 손글씨 숫자 이미지 총 70,000개
    학습 데이터(Train) : 60,000개
    테스트 데이터(Test) : 10,000개
  • 이미지 크기
    각 숫자 이미지는 28x28픽셀의 흑백 이미지
    한 개의 이미지는 총 784개의 픽셀(28x28 =784)로 표현됨
    각 픽셀 값은 0(검은색) ~ 255(흰색) 범위

 

MNIST 데이터 로드

from sklearn.datasets import fetch_openml

# MNIST 데이터셋 불러오기
mnist = fetch_openml('mnist_784', version=1)

# 데이터와 레이블 분리
X = mnist.data
y = mnist.target

# 데이터 확인
print(X.shape, y.shape)

"""
(70000, 784) (70000,)
"""

 

 

데이터 표준화 (Standardization)

PCA 수행 전 데이터 스케일 조정

from sklearn.preprocessing import StandardScaler

# 데이터 표준화
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

 

 

PCA 수행

Scikit-learn의 PCA를 사용하여 차원 축소 수행

from sklearn.decomposition import PCA

# PCA 모델 생성 (전체 분산의 95%를 설명하는 주성분 선택)
pca = PCA(n_components=0.95)

# PCA 학습 및 변환
X_pca = pca.fit_transform(X_scaled)

# 변환된 데이터 크기 확인
print("원본 데이터 크기:", X_scaled.shape)
print("PCA 변환 후 데이터 크기:", X_pca.shape)

"""
원본 데이터 크기: (70000, 784)
PCA 변환 후 데이터 크기: (70000, 332)
"""

 

 

주성분 확인

# 선택된 주성분의 개수 확인
print(f'선택된 주성분 개수: {pca.n_components_}')

# 각 주성분이 설명하는 분산 비율 출력
print(f'각 주성분이 설명하는 분산 비율:\n{pca.explained_variance_ratio_}')

# 누적 분산 비율 확인
print(f'누적 분산 비율:\n{pca.explained_variance_ratio_.cumsum()}')

"""
선택된 주성분 개수: 332
각 주성분이 설명하는 분산 비율:
[0.05642719 0.04041226 0.03738273 0.02893    0.02520752 0.02192549
 0.01914282 0.01740684 0.01532232 0.01396087 0.01342175 0.01201421
 0.01113962 0.01090582 0.01027986 0.00994955 0.00931255 0.00919635
 0.008886   0.00863195 0.00821741 0.00798417 0.00762573 0.00742315
 0.0071657  0.00689314 0.00681399 0.00654588 0.00627293 0.00610345
 0.00597261 0.00589304 0.00567358 0.00559358 0.00552473 0.00534443
 0.00527593 0.00515841 0.00505498 0.00477438 0.00476312 0.00465155
 0.00453454 0.00445757 0.00442313 0.00437877 0.00437294 0.00427724
 0.00424808 0.00418524 0.00404059 0.00396258 0.00393176 0.00390562
 0.00386444 0.00377501 0.00373883 0.00368328 0.00360377 0.0035637
 0.00349289 0.00344527 0.00343239 0.00341    0.00334463 0.00332107
 0.00329803 0.00319433 0.0031711  0.00315431 0.00309941 0.00305782
 0.00305095 0.0030396  0.00296635 0.00292958 0.00291295 0.00290232
 0.00288608 0.00287022 0.00284514 0.00281524 0.00279245 0.00278629
 0.00278233 0.00276733 0.0027542  0.00272901 0.0026874  0.00268139
 0.00267354 0.00263003 0.00262155 0.00258872 0.00258429 0.002571
 0.002519   0.00250904 0.00248094 0.00244092 0.00243607 0.00241671
 0.00238999 0.00236394 0.00235632 0.00232326 0.00229151 0.00225292
 0.00223891 0.0022322  0.00219714 0.00219026 0.00215303 0.00213447
 0.00210763 0.00210123 0.00206525 0.00205073 0.00202906 0.00198907
 0.00197597 0.00196588 0.00195394 0.00194545 0.00192834 0.00191505
 0.0018926  0.001884   0.00186304 0.0018189  0.00180676 0.00179009
 0.00178407 0.00176999 0.00175852 0.0017478  0.00173304 0.001728
 0.00169433 0.00167648 0.00165855 0.00164975 0.00164603 0.00164149
 0.00161138 0.00160413 0.00158927 0.00156601 0.00156231 0.00154815
 0.00153566 0.00152617 0.00151562 0.00149189 0.0014888  0.00147098
 0.00146274 0.00144916 0.00144202 0.00142795 0.00142245 0.00142043
 0.00140016 0.00139306 0.00139149 0.00139049 0.00138895 0.00138616
 0.00138451 0.00136449 0.00135787 0.00135151 0.001349   0.00133797
 0.00132635 0.00131349 0.00129857 0.00129275 0.00128703 0.00127087
 0.00126384 0.00125841 0.00123504 0.00122147 0.00121683 0.00121135
 0.00119987 0.0011959  0.00117699 0.00117216 0.00116486 0.00115194
 0.00114869 0.00114259 0.00113339 0.00112363 0.0011098  0.0010857
 0.00108128 0.00106264 0.00105589 0.00104707 0.00104297 0.00102776
 0.00101473 0.00100924 0.00099916 0.00099336 0.00098883 0.00097517
 0.00096859 0.00096289 0.00095418 0.00094574 0.00094345 0.00093592
 0.00092743 0.00090978 0.00090247 0.00089122 0.0008811  0.00087677
 0.00087115 0.00086639 0.0008581  0.00085287 0.00084026 0.0008293
 0.00082325 0.00081886 0.00081504 0.00080889 0.00080534 0.00079901
 0.00078771 0.00078122 0.00077733 0.00077151 0.00075642 0.00075139
 0.00074756 0.00073904 0.00073446 0.00072745 0.00072132 0.00071168
 0.00070254 0.00070072 0.0006958  0.00068794 0.00068262 0.00067936
 0.00067621 0.00066319 0.00066042 0.00065928 0.00065277 0.00063943
 0.00063772 0.00063592 0.0006307  0.00062632 0.00061863 0.00061657
 0.00060856 0.00060434 0.00059843 0.00058724 0.00058085 0.000576
 0.00057315 0.00057071 0.00056459 0.00056026 0.00055714 0.00054952
 0.0005471  0.00054404 0.00054158 0.00053849 0.00053598 0.00052652
 0.00052487 0.00051799 0.00051499 0.00051252 0.00050578 0.00050238
 0.00049864 0.00049624 0.0004944  0.00049112 0.00048178 0.00047847
 0.00047651 0.00047552 0.00047147 0.00046091 0.00045825 0.00044977
 0.00044841 0.00044791 0.00044299 0.0004388  0.00043726 0.00043261
 0.00043036 0.0004228  0.00041957 0.00041683 0.00041542 0.00041235
 0.00041092 0.00040894 0.00040756 0.00040225 0.00039977 0.00039671
 0.00039165 0.00038918 0.00038757 0.0003866  0.00038275 0.00037874
 0.00037818 0.00037467 0.00037178 0.00036996 0.00036669 0.00036099
 0.00035912 0.00035849]
누적 분산 비율:
[0.05642719 0.09683945 0.13422218 0.16315218 0.1883597  0.21028519
 0.22942801 0.24683484 0.26215716 0.27611803 0.28953978 0.30155399
 0.31269361 0.32359943 0.33387928 0.34382883 0.35314139 0.36233773
 0.37122373 0.37985569 0.3880731  0.39605727 0.403683   0.41110615
 0.41827185 0.42516499 0.43197898 0.43852485 0.44479779 0.45090124
 0.45687385 0.46276689 0.46844047 0.47403405 0.47955878 0.48490321
 0.49017915 0.49533756 0.50039254 0.50516692 0.50993004 0.51458159
 0.51911613 0.5235737  0.52799683 0.5323756  0.53674853 0.54102577
 0.54527385 0.54945909 0.55349969 0.55746227 0.56139402 0.56529964
 0.56916408 0.57293908 0.57667791 0.5803612  0.58396497 0.58752866
 0.59102155 0.59446682 0.59789921 0.60130921 0.60465384 0.60797491
 0.61127295 0.61446728 0.61763838 0.62079269 0.62389209 0.62694992
 0.63000087 0.63304047 0.63600682 0.6389364  0.64184935 0.64475167
 0.64763776 0.65050798 0.65335312 0.65616836 0.65896081 0.6617471
 0.66452943 0.66729676 0.67005095 0.67277997 0.67546736 0.67814875
 0.68082229 0.68345233 0.68607387 0.68866259 0.69124688 0.69381788
 0.69633688 0.69884592 0.70132685 0.70376778 0.70620385 0.70862056
 0.71101055 0.7133745  0.71573082 0.71805408 0.72034559 0.72259851
 0.72483742 0.72706962 0.72926676 0.73145701 0.73361004 0.73574451
 0.73785214 0.73995337 0.74201863 0.74406936 0.74609841 0.74808748
 0.75006346 0.75202934 0.75398327 0.75592873 0.75785706 0.75977212
 0.76166471 0.76354872 0.76541176 0.76723066 0.76903742 0.7708275
 0.77261157 0.77438156 0.77614008 0.77788788 0.77962092 0.78134893
 0.78304325 0.78471973 0.78637828 0.78802803 0.78967406 0.79131555
 0.79292694 0.79453107 0.79612034 0.79768635 0.79924865 0.8007968
 0.80233246 0.80385863 0.80537425 0.80686615 0.80835495 0.80982593
 0.81128867 0.81273783 0.81417984 0.81560779 0.81703024 0.81845068
 0.81985084 0.8212439  0.82263539 0.82402588 0.82541484 0.826801
 0.82818551 0.82955    0.83090787 0.83225938 0.83360837 0.83494634
 0.83627269 0.83758618 0.83888475 0.8401775  0.84146453 0.8427354
 0.84399924 0.84525765 0.84649268 0.84771415 0.84893098 0.85014232
 0.85134219 0.8525381  0.85371509 0.85488725 0.85605211 0.85720405
 0.85835274 0.85949533 0.86062872 0.86175234 0.86286214 0.86394784
 0.86502912 0.86609176 0.86714765 0.86819473 0.8692377  0.87026546
 0.87128019 0.87228944 0.87328859 0.87428196 0.87527078 0.87624595
 0.87721454 0.87817743 0.87913161 0.88007736 0.88102081 0.88195673
 0.88288416 0.88379394 0.88469641 0.88558764 0.88646873 0.88734551
 0.88821666 0.88908305 0.88994115 0.89079402 0.89163428 0.89246359
 0.89328684 0.8941057  0.89492075 0.89572964 0.89653498 0.89733399
 0.8981217  0.89890293 0.89968026 0.90045176 0.90120818 0.90195958
 0.90270713 0.90344618 0.90418064 0.90490809 0.9056294  0.90634108
 0.90704362 0.90774434 0.90844014 0.90912808 0.9098107  0.91049006
 0.91116627 0.91182947 0.91248989 0.91314917 0.91380194 0.91444137
 0.91507909 0.91571501 0.91634572 0.91697204 0.91759067 0.91820724
 0.9188158  0.91942015 0.92001858 0.92060582 0.92118667 0.92176267
 0.92233582 0.92290653 0.92347112 0.92403138 0.92458852 0.92513804
 0.92568514 0.92622918 0.92677076 0.92730925 0.92784524 0.92837175
 0.92889663 0.92941462 0.92992961 0.93044213 0.93094791 0.93145029
 0.93194893 0.93244517 0.93293957 0.9334307  0.93391247 0.93439094
 0.93486745 0.93534296 0.93581443 0.93627534 0.93673359 0.93718337
 0.93763178 0.93807969 0.93852267 0.93896147 0.93939873 0.93983134
 0.94026169 0.94068449 0.94110406 0.94152088 0.94193631 0.94234866
 0.94275958 0.94316852 0.94357608 0.94397833 0.9443781  0.94477481
 0.94516646 0.94555564 0.94594321 0.94632981 0.94671256 0.9470913
 0.94746948 0.94784415 0.94821593 0.94858589 0.94895259 0.94931357
 0.94967269 0.95003118]
 """

 

 

PCA 결과 시각화

차원 축소 후 2D 공간에서 데이터 시각화

import matplotlib.pyplot as plt
import seaborn as sns

# 2D 시각화
plt.figure(figsize=(10, 7))
sns.scatterplot(x=X_pca[:, 0], y=X_pca[:, 1], hue=y.astype(int), palette="viridis", legend=False)
plt.title('PCA of MNIST Dataset (2D)')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.show()

PCA of MNIST Dataset (2D)