RyanNerd
라덕'Story
RyanNerd
  • 분류 전체보기 (70) N
    • Study Note (35) N
      • Python (3)
      • R (1)
      • Airflow (7)
      • 통계 (22) N
      • 머신러닝 (2) N
    • 빅데이터분석기사 (1)
      • 필기 (1)
    • Programmers (28)
      • Python (13)
      • SQL (15)
    • Project (3)
      • Django (3)
    • Mac (2)

블로그 메뉴

  • NaverBlog
  • 홈

최근 글

전체 방문자
오늘
어제
hELLO · Designed By 정상우.
RyanNerd

라덕'Story

Study Note/통계

PCA 활용: 복잡한 데이터를 한눈에 보는 법 (차원 축소 & 시각화)

2025. 12. 18. 14:10

저번 포스팅에서 PCA의 원리를 배웠다면, 오늘은 "그래서 이걸 어디에 쓰는데?"에 대한 답입니다. 의료 데이터 분석에서 변수(Feature)가 수십, 수백 개일 때, PCA는 핵심 신호만 남기는 압축기이자, 고차원 데이터를 2D 화면에 뿌려주는 내비게이션 역할을 합니다.

오늘은 PCA를 활용한 차원 축소의 원리와, "실린더(Cylinder) 예시"를 통해 PCA가 어떻게 최적의 시각화 각도를 찾아내는지 코드로 직접 구현해 보겠습니다.

 

1. 차원 축소 (Dimensionality Reduction)

원리: "중요하지 않은 건 버린다"

주성분($PC$)들은 정보량(분산, $\sigma^2$)이 큰 순서대로 정렬되어 있습니다.

  • $\sigma_1^2 > \sigma_2^2 > \dots > \sigma_k^2$

우리는 이 중에서 정보량이 미미한 하위 주성분들을 과감히 버리고, 상위 $q$개의 주성분만 남겨 데이터를 표현합니다.

$$X \approx \beta_{1}PC_1 + \dots + \beta_{q}PC_q \quad (\text{where } q < k)$$

장점과 단점 (Trade-off)

  • 장점:
    • 가장 뚜렷한 특징(Signal)만 남습니다. (노이즈 제거 효과)
    • 데이터가 가벼워져 연산 속도가 빨라집니다.
    • 시각화가 가능해집니다.
  • 단점:
    • 작은 디테일(Detail)은 손상됩니다.
    • 원래 변수가 섞여 있어 직관적인 해석("이 축은 키(cm)다")이 어렵습니다.

2. 몇 개까지 줄여야 할까? (CVR)

무작정 줄이면 정보 손실이 큽니다. 이때 기준이 되는 것이 누적 분산 비율(Cumulative Variance Ratio, CVR)입니다.

$$CVR = \frac{\sum_{i=1}^{q} \sigma_i^2}{\text{Total Variance}}$$

보통 "전체 정보의 80~90%를 보존하는 선"에서 주성분 개수($q$)를 결정합니다.

 

3. [시각화 원리] 실린더(Cylinder)를 어디서 봐야 할까?

'실린더 예시'는 PCA가 시각화에 왜 강력한지를 보여주는 최고의 비유입니다.

3차원 공간에 원통(Cylinder) 모양으로 데이터가 퍼져 있다고 상상해 봅시다. 우리는 이걸 2차원 모니터(단면)로 봐야 합니다.

  1. 옆에서 본다면? (Bad Slice): 그냥 직사각형으로 보입니다. 데이터가 원형으로 분포한다는 중요한 구조를 놓치게 됩니다.
  2. 위에서 본다면? (Good Slice = PCA): 완벽한 원(Circle) 모양이 보입니다. 데이터가 가장 넓게 퍼져 있는(분산이 큰) 단면을 찾았기 때문입니다.

    PCA의 역할: 컴퓨터가 알아서 "데이터가 가장 넓게 퍼져 있는(가장 잘 보이는) 각도"를 찾아내어 우리에게 보여줍니다.

4. [실습] 파이썬 & R 코드로 그래프 그리기

import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from mpl_toolkits.mplot3d import Axes3D

# --- 1. 차원 축소 예시 (2D -> 1D -> 2D 복원) ---
np.random.seed(42)
mean = [0, 0]
cov = [[5, 4], [4, 5]] # 상관관계가 강한 데이터
X = np.random.multivariate_normal(mean, cov, 100)

# PCA 수행 (1개 성분만 남김)
pca = PCA(n_components=1)
X_reduced = pca.fit_transform(X) # 차원 축소 (2D -> 1D)
X_restored = pca.inverse_transform(X_reduced) # 다시 2D 좌표로 복원 (정보 손실 발생)

# --- 2. 실린더(Cylinder) 시각화 원리 (3D) ---
# 실린더형 데이터 생성
angles = np.linspace(0, 2*np.pi, 100)
z_vals = np.linspace(-5, 5, 20)
X_cyl = []
for z in z_vals:
    for a in angles:
        # x^2 + y^2 = 1 (원통), z는 높이
        r = 1 + np.random.normal(0, 0.05) # 약간의 노이즈
        X_cyl.append([r*np.cos(a), r*np.sin(a), z])
X_cyl = np.array(X_cyl)

# PCA 수행 (3D -> 2D)
pca_cyl = PCA(n_components=2)
X_cyl_pca = pca_cyl.fit_transform(X_cyl)

# --- 그래프 그리기 ---
fig = plt.figure(figsize=(12, 10))

# [그래프 1] 차원 축소: 디테일 손상 확인
ax1 = fig.add_subplot(2, 2, 1)
ax1.scatter(X[:, 0], X[:, 1], alpha=0.5, label='Original (Detail)', color='blue')
ax1.scatter(X_restored[:, 0], X_restored[:, 1], alpha=0.8, label='Restored (PC1 only)', color='red')
# 원래 점과 투영된 점 연결 (손실된 정보 표현)
for i in range(len(X)):
    ax1.plot([X[i,0], X_restored[i,0]], [X[i,1], X_restored[i,1]], 'k-', alpha=0.1)
ax1.set_title("1. Dimensionality Reduction (2D -> 1D)")
ax1.legend()
ax1.grid(True)

# [그래프 2] 실린더: 옆에서 본 모습 (Bad View - 분산 작음)
ax2 = fig.add_subplot(2, 2, 3)
ax2.scatter(X_cyl[:, 0], X_cyl[:, 2], alpha=0.1, color='green') # X와 Z축만 봄
ax2.set_title("2. Bad Slice (Side View)\nStructure Lost (Looks like Rectangle)")
ax2.set_xlabel("X"); ax2.set_ylabel("Z (Height)")
ax2.grid(True)
ax2.set_aspect('equal')

# [그래프 3] 실린더: PCA가 찾은 모습 (Good View - 분산 큼)
ax3 = fig.add_subplot(2, 2, 4)
ax3.scatter(X_cyl_pca[:, 0], X_cyl_pca[:, 1], alpha=0.1, color='purple') # PC1, PC2
ax3.set_title("3. Good Slice (PC1 vs PC2)\nStructure Revealed (Circle!)")
ax3.set_xlabel("PC1"); ax3.set_ylabel("PC2")
ax3.grid(True)
ax3.set_aspect('equal')

plt.tight_layout()
plt.show()

 

# 라이브러리 로드 (없으면 설치 필요)
# install.packages("MASS")
library(MASS)

par(mfrow=c(2, 2)) # 2x2 화면 분할

# --- 1. 차원 축소 예시 (2D -> 1D) ---
set.seed(42)
Sigma <- matrix(c(5,4,4,5), 2, 2)
X <- mvrnorm(100, c(0,0), Sigma)

# PCA 수행
pca_res <- prcomp(X, center=TRUE, scale=FALSE)
# PC1만 사용하여 복원 (X_hat = PC_score * Rotation_matrix + Mean)
X_restored <- pca_res$x[,1] %*% t(pca_res$rotation[,1]) 
X_restored <- scale(X_restored, center = -pca_res$center, scale = FALSE) # 평균 더해줌

# 그래프 1: 차원 축소 효과
plot(X, col=rgb(0,0,1,0.4), pch=19, main="1. Dimensionality Reduction", 
     xlab="X1", ylab="X2", asp=1)
points(X_restored, col="red", pch=19, cex=0.8)
segments(X[,1], X[,2], X_restored[,1], X_restored[,2], col="gray") # 연결선
legend("topleft", legend=c("Original", "Reduced(PC1)"), col=c("blue", "red"), pch=19)


# --- 2. 실린더 시각화 예시 ---
# 실린더 데이터 생성
theta <- runif(1000, 0, 2*pi)
z <- runif(1000, -5, 5)
r <- 1 + rnorm(1000, 0, 0.05)
x_cyl <- r * cos(theta)
y_cyl <- r * sin(theta)
z_cyl <- z
cyl_data <- data.frame(x=x_cyl, y=y_cyl, z=z_cyl)

# PCA 수행
pca_cyl <- prcomp(cyl_data)

# 그래프 2: 옆에서 본 모습 (Bad View)
plot(cyl_data$x, cyl_data$z, col=rgb(0,1,0,0.1), pch=19,
     main="2. Bad Slice (Side View)", xlab="X", ylab="Z (Height)", asp=1)
text(0, 0, "Rectangle?", col="black", cex=1.5)

# 그래프 3: PCA로 본 모습 (Good View)
plot(pca_cyl$x[,1], pca_cyl$x[,2], col=rgb(0.5,0,0.5,0.1), pch=19,
     main="3. Good Slice (PC1 vs PC2)", xlab="PC1", ylab="PC2", asp=1)
text(0, 0, "Circle!", col="black", cex=1.5)

par(mfrow=c(1, 1)) # 화면 초기화

그래프 해석

  1. 차원 축소 (1번 그래프):
    • 파란 점(원본)이 대각선 방향(PC1)인 빨간 점(축소본)으로 이동했습니다.
    • 회색 선의 길이만큼 정보(디테일)가 손실되었지만, 데이터의 가장 큰 경향성(Trend)은 그대로 유지하고 있습니다.
  2. 실린더 시각화 (2번 vs 3번 그래프):
    • 2번 (Bad Slice): 3차원 원통을 옆면($X, Z$축)에서 잘라보면 단순히 직사각형처럼 보입니다. 데이터의 진짜 모양(원형)을 알 수 없습니다.
    • 3번 (Good Slice - PCA): 주성분($PC1, PC2$)으로 데이터를 투영하니, 위에서 내려다본 것처럼 완벽한 원형(Circle) 구조가 드러납니다.
    • 결론: PCA는 데이터가 가장 넓게 퍼진 면을 찾아, 숨겨진 구조(Structure/Cluster)를 시각화하는 데 탁월합니다.

 

'Study Note > 통계' 카테고리의 다른 글

어제는 잊어라, 오직 오늘만 본다: 마르코프 연쇄 (Markov Chain)  (0) 2025.12.19
PCA와 비슷하지만 다른, 요인분석(Factor Analysis)의 모든 것  (0) 2025.12.19
차원 축소의 핵심, 주성분분석(PCA) 완벽 가이드  (0) 2025.12.18
정확도(Accuracy)의 함정: 민감도, 특이도, 그리고 베이즈 정리  (0) 2025.12.17
분류 문제의 시작, 로지스틱 회귀(Logistic Regression) 완벽 해부  (0) 2025.12.16
    'Study Note/통계' 카테고리의 다른 글
    • 어제는 잊어라, 오직 오늘만 본다: 마르코프 연쇄 (Markov Chain)
    • PCA와 비슷하지만 다른, 요인분석(Factor Analysis)의 모든 것
    • 차원 축소의 핵심, 주성분분석(PCA) 완벽 가이드
    • 정확도(Accuracy)의 함정: 민감도, 특이도, 그리고 베이즈 정리
    RyanNerd
    RyanNerd
    라이언 덕후의 일상 스토리~

    티스토리툴바