머신러닝&딥러닝

머신러닝 & 딥러닝 기초 28편 | PCA(Principal Component Analysis, 주성분 분석)

SecLogs YJ 2026. 3. 19. 21:33

 

목차

1. PCA(Principal Component Analysis, 주성분 분석)란?
2. PCA의 장점과 한계
3. PCA의 핵심 아이디어
4. PCA 작동 원리
5. 중요 개념 정리
6. PCA 예제

 

1. PCA(Principal Component Analysis, 주성분 분석)란?

 

PCA는 고차원 데이터를 더 적은 차원으로 줄이면서도, 데이터가 가지고 있는 중요한 정보는 최대한 유지하려는 차원 축소 기법이다.

머신러닝에서 데이터의 특성(feature)이 많아질수록 계산량이 증가하고, 불필요한 정보나 중복 정보가 섞여 모델 성능이 오히려 나빠질 수 있다.

또한, 사람이 데이터를 직접 이해하거나 시각화하기도 어려워진다.

이런 경우 PCA를 사용하면 여려 특성을 더 적은 수의 새로운 축으로 바꾸어 데이터를 간단하게 표현할 수 있다.

 

PCA는 기존 feature를 일부 골라서 남기는 방식이 아닌, 여러 Feature를 조합해서 새로운 축을 만든다.

이때 새로운 축을 주성분(Principal Component)이라고 한다.

 

즉, PCA는 단순히 차원을 줄이는 기법이 아닌, 데이터의 분산이 가장 큰 방향을 찾아 중요한 패턴을 보존하는 방법이다.

 

 

2. PCA의 장점과 한계

장점

  • 고차원 데이터를 단순하게 만든다.
  • 계산량을 줄인다.
  • 시각화를 쉽게 해준다.
  • 상관관계가 높은 feature들을 압축해 중복 정보를 줄이는 데 효과적이다.

단점

  • 데이터의 구조를 선형적인 관계로 가정한다.
  • 변환 후 생성된 주성분은 원래 feature과는 다른 의미를 가질 수 있다.
  • 분산이 작더라도 중요한 정보가 들어있는 경우, PCA는 이를 반영하지 못한다.

 

3. PCA의 핵심 아이디어

PCA는 데이터가 가장 많이 퍼져 있는 방향을 찾는다.

 

일반적으로 데이터가 한 방향으로 크게 퍼져 있다는 것은, 그 방향이 데이터의 특징을 잘 설명하고 있다는 뜻이다. 반대로 거의 퍼져 있지 않은 방향은 데이터의 차이를 잘 설명하지 못하거나, 중요하지 않은 정보일 가능성이 크다.

 

예를 들어, 2차원 평면 위에 점들이 대각선 방향으로 길게 분포되어 있다고 생각해보자.

이 데이터를 x축과 y축으로 보는 것보다 점들이 길게 늘어선 방향을 새로운 축으로 잡는 게 데이터를 더 잘 설명할 수 있다.

PCA는 바로 이런 방식으로 새로운 축을 만든다.

 

이때 만들어지는 첫 번째 축이 제 1주성분(PC1)이다.

PC1은 데이터의 분산을 가장 많이 설명하는 방향이다.

 

두 번째 축은 제2주성분(PC2)이다.

PC2는 PC1과 직각이면서, 남아 있는 분산을 가장 많이 설명하는 방향이다.

 

그 다음도 같은 방식으로 제3주성분, 제4성분이 정해진다.

 

주성분의 개수는 원래 데이터 개수와 동일하다.

예를 들어, 데이터가 4차원이라면 최대 4개의 주성분이 존재한다.

하지만 실제로는 모든 주성분을 사용하는 것이 아니라, 중요한 일부 주성분만 선택하여 차원을 줄이는 것이 PCA의 목적이다.

 

4. PCA 작동 원리

PCA의 흐름은 다음과 같이 이해할 수 있다.

 

4-1 데이터 표준화(Standardization) 

PCA는 데이터의 크기에 민감하기 때문에 데이터 표준화는 거의 필수이다.

예를 들어, 어떤 feature는 값의 범위가 1~10이고, 다른 feature는 1000~10000이라면 큰 값을 가지는 feature가 분산도 크게 보일 가능성이 높다.

그러면 실제로 중요한 feature가 아니라 단순히 숫자 규모가 큰 feature가 PCA 결과에 더 큰 영향을 줄 수 있다.

 

따라서, PCA를 적용하기 전에 각 feature를 평균 0, 표준편차 1이 되도록 표준화한다.

 

 

4-2 공분산 행렬 계산

표준화된 데이터를 바탕으로 각  feature가 서로 어떤 관계를 가지는지 확인한다.

이때 사용하는 것이 공분산 행렬(Convariance Matrix)이다.

 

공분산은 두 변수가 함께 증가하든지, 함께 감소하든지, 또는 서로 반대로 움직이는지를 보여준다.

공분산이 크면 두 변수는 비슷한 패턴으로 움직인다고 볼 수 있고, 이는 중복 정보가 있을 가능성을 의미한다.

 

 

4-3 고유값과 고유벡터 계산

공분산 행렬로부터 고유값과 고유벡터를 계산한다.

  • 고유벡터 : 데이터가 퍼져 있는 방향, 즉 새로운 축의 방향
  • 고유값 : 그 축이 얼마나 중요한지(=얼마나 많은 분산을 설명하는지)

즉, 고유벡터는 방향이고 고유값은 중요도이다.

 

 

4-4 주성분(Principal Components) 선택

고유값이 큰 순서대로 주성분을 정렬한다.

보통은 상위 몇 개의 주성분만 선택해서 사용한다.

 

예를 들어, 전체 분산의 95%를 설명하는 데 필요한 주성분이 2개라면 원래 10차원 데이터라도 2차원으로 줄일 수 있다.

 

 

4-5 데이터 투명(Projection)

마지막으로 원본 데이터를 선택한 주성분 축에 투영한다.

이 과정을 통해 원래의 고차원 데이터는 더 적은 차원의 데이터로 바뀐다.

 

 

5. 중요 개념 정리

5-1. 주성분(Principal Component)이란

주성분은 feature를 단순히 하나 고른 것이 아닌, 기존 feature들을 조합해서 만든 새로운 축이다.

 

예를 들어 원래 데이터가 x1, x2, x3 세 개의 feature로 이루어져 있다면, 첫 번째 주성분은 feature를 일정한 비율로 결합한 형태로 표현된다.

즉, 하나의 feature를 그대로 사용하는 것이 아니라 여러 feature의 정보를 압축하여 하나의 값으로 나타낸 것이다.

 

이처럼 주성분은 기존 변수들을 새로운 기준으로 다시 표현한 결과이며, 데이터의 분산이 큰 방향일수록 더 중요한 정보를 담고 있다고 볼 수 있다. 

 

따라서, 첫 번째 주성분이 가장 중요한 정보를 포함하고, 두 번째 주성분은 그 다음으로 중요한 정보를 담게 된다.

 

결과적으로 PCA는 데이터를 단순히 줄이는 것이 아니라, 데이터를 가장 잘 설명하는 방향으로 재구성하는 과정이라고 이해하는 것이 중요하다.

 

 

5-2 데이터 투영(Projection)이란

투영은 원래 데이터를 새로운 축 위에 옮겨 놓는 과정이다.

 

예를 들어, 2차원 데이터를 1차원으로 줄인다면, 각 점을 가장 중요한 축인 PC1 위에 내려찍는다고 생각하면 된다.

이렇게 하면 원래 2차원 좌표 대신, PC1 위에서의 위치 하나만으로 데이터를 표현할 수 있다.

 

물론 이 과정에서 일부 정보가 사라지기도 한다.

하지만 PCA는 가능한 한 중요한 정보가 최대한 덜 사라지도록(=분산 손실이 최소화되도록) 축을 선택한다.

 

 

5-3 설명분산비율(Explained Variance Ration)이란?

설명분산비율은 각 주성분이 전체 분산 중에서 얼마만큼을 설명하는지를 비율로 나타낸 것이다.

 

예를 들어, 설명분산비율이 다음과 같을 경우

  • PC1 : 0.62
  • PC2 : 0,23
  • PC3 : 0,10

이는 첫 번째 주성분이 전체 정보의 62%, 두 번째가 23%, 세 번째가 10%를 설명한다는 뜻이다.

 

그래서 PC1과 PC2만 합쳐도 85%를 설명한다면, 이 두 개만 사용해도 데이터의 중요한 구조를 어느 정도 유지할 수 있다고 판단할 수 있다.

 

 

6. PCA 예제

예제 1) 라이브러리 불러오기

import numpy as np
import matplotlib.pyplot as plt

from sklearn.datasets import load_wine
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

 

import numpy as np 수치 계산을 돕는 Numpy 라이브러리
import matplotlib.pyplot as plt 그래프를 그리기 위한 Matplotlib의 pyplot 모듈
from sklearn.datasets import load_wine Wine 데이터셋을 불러오기 위한 함수
from sklearn.preprocessing import StandardScaler 데이터 표준화를 위한 도구
PCA 는 feature의 스케일에 민감하기 때문에 표준화 수행 필요
from sklearn.decomposition import PCA PCA 모델을 사용하기 위해 불러오는 크래스

 

 

예제 2) 데이터 생성

wine = load_wine()

X = wine.data
y = wine.target
feature_names = wine.feature_names
target_names = wine.target_names

 

wine = load_wine() Wine 데이터셋 전체를 불러온다.
(입력 데이터, 정답 라벨, feature 이름, 클래스 이름 등)
X = wine.data 입력 feature 데이터만 따로 꺼낸다.
y = wine.target 정답 라벨이다. 
각 데이터가 어떤 클래스에 속하는지를 나타낸다.
feature_names = wine.feature_names 각 열(column)이 무엇을 의미하는지 이름을 저장한다.
target_names = wine.target_names 클래스 이름을 저장한다. 
시각화할 때 범례를 붙일 때 사용할 수 있다.

 

 

예제 3) 데이터 크기 확인

print("원본 데이터 크기:", X.shape)
print("클래스 개수:", len(target_names))
print("특성 이름:", feature_names)

 

 

예제 4) 데이터 표준화

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

 

scaler = StandardScaler() 표준화를 수행할 객체를 생성
X_scaled = scaler.fit_transform(X) 먼저 각 feature의 평균과 표준편차를 계산한 뒤(fit), 그 기준으로 실제 데이터를 변환한다(transform).
결과적으로 각 feature는 평균이 0, 표준편차가 1에 가까운 값으로 바뀐다.

 

 

예제 5) PCA 적용

pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

 

pca = PCA(n_components=2) PCA 객체 생성
n_components=2는 원래 13차원 데이터를 2차원으로 줄이겠다는 뜻
X_pca = pca.fit_transform(X_scaled) 표준화된 데이터에서 주성분을 찾고(fit), 그 주성분 축으로 데이터를 변환한다(transform).
결과적으로 X_pca는 2개의 열만 가지는 새로운 데이터가 된다.

 

 

예제 6) 설명분산비율 확인

print("각 주성분의 설명분산비율:", pca.explained_variance_ratio_)
print("누적 설명분산비율:", np.sum(pca.explained_variance_ratio_))

 

print("각 주성분의 설명분산비율:", pca.explained_variance_ratio_) 각 주성분이 전체 분산 중 얼마를 설명하는지 출력
print("누적 설명분산비율:", np.sum(pca.explained_variance_ratio_)) 선택한 주성분들이 전체 분산을 합쳐서 얼마나 설명하는지 출력
이 값이 너무 낮다면 2차원으로 줄이는 과정에서 정보 손실이 크다고 볼 수 있다.

 

 

예제 6) 출력 결과

각 주성분의 설명분산비율: [0.36198848 0.1920749 ]
누적 설명분산비율: 0.5540633835693526

 

원래 데이터가 가지고 있던 정보(분산)의 약 55%만 2차원으로 표현하고 있다는 의미이다.

설명분산비율을 높이고자 한다면, 주성분 개수를 늘려야 한다.

pca = PCA(n_components=3)

 

참고오 아래와 같이 "전체 정보의 95%를 유지할 때까지 주성분을 알아서 선택”하는 코드도 있다.

pca = PCA(n_components=0.95)

 

 

 

예제 7) PCA 결과 시각화

plt.figure(figsize=(8, 6))

for class_index, class_name in enumerate(target_names):
    plt.scatter(
        X_pca[y == class_index, 0],
        X_pca[y == class_index, 1],
        label=class_name,
        alpha=0.7
    )

plt.title("PCA on Wine Dataset")
plt.xlabel("Principal Component 1")
plt.ylabel("Principal Component 2")
plt.legend()
plt.grid()
plt.show()

 

예제 7) 출력 결과

PCA 시각화 결과

 

 


👉 머신러닝 & 딥러닝 기초 29편 | t-SNE(t-distributed Stochastic Neighbor Embedding)