본문 바로가기
의공학자를 위한 데이터분석/다변량 통계 분석

MVS-03 주성분분석 실전

by 율생공 2025. 7. 13.

주성분분석

  지난 글의 내용을 정리하자면

1) 주성분 분석은 설명 분산을 최대화하는, 변수들의 선형결합이다.

 2) 주성분의 수는 Kaiser's rule, 병렬 분석, 설명분산 등을 이용해 정한다.

  라고 할 수 있습니다. 이번에는 오픈 데이터셋을 이용해서 주성분분석을 하는 방법을 적어보려합니다.

 

R 코드

  우선 필요한 라이브러리들을 불러옵니다.

# 필요한 패키지 설치
#install.packages(c("psych", "FactoMineR", "factoextra", "paran"))

library(psych)         
library(FactoMineR)    
library(factoextra)    
library(paran)

   US arrest 라는 오픈 데이터셋을 불러옵니다. 간단한 분석을 위해 결측치를 제거하고, 표준화를 하여 주성분분석을 진행합니다.

# 내장된 오픈 데이터 USArrests
data("USArrests")

# 결측치 제거 (있으면)
df <- na.omit(USArrests)

# 표준화 후 PCA 수행
res.pca <- prcomp(df, scale = TRUE)

  여기서부터 Kaisers rule과 병렬 분석을 각각 적용해보겠습니다.

Kaiser's rule

# 고유값 계산
eig.val <- get_eigenvalue(res.pca)
print(eig.val)

# 고유값이 1 초과인 주성분 개수
sum(eig.val$eigenvalue > 1)

고유값이 1보다 큰 경우는 첫번째 주성분(Dim. 1) 뿐입니다. 따라서 Kaiser's rule에 따르면 주성분은 1개만 사용합니다.

 

병렬분석

# 병렬 분석 수행
paran(df, graph = TRUE, iterations = 1000, centile = 0)

# 또는 psych 패키지의 fa.parallel도 가능
fa.parallel(df, fa = "pc", n.iter = 100, show.legend = FALSE)

  파란 선은 실제 데이터의 주성분이 갖는 고유값, 빨간 선은 무작위 데이터의 주성분이 갖는 고유값입니다. 첫번째 주성분의 경우 고유값이 빨간 선보다 압도적으로 위에 있어 매우 유의하다고 할 수 있지만, 두번째 주성분부터는 작아지는 것을 볼 수 있습니다. 이 경우에도 주성분의 수는 1이라고 볼 수 있습니다. (하지만 값이 비슷한 정도이기 때문에 경우에 따라 포함할 수도 있습니다.)

 

설명분산

# 설명 분산 비율과 누적 비율
summary(res.pca)

  데이터 분석 관련 자격증 시험을 보신 분들께는 익숙하실 이미지입니다. PC1만으로 전체 데이터의 분산 중 62% 정도를 설명할 수 있고, PC1, PC2 두가지를 사용하면 87% 정도를 설명할 수 있습니다. 차원축소를 통한 시각화나 분류 등이 목적이라면 2개의 주성분도 고려해볼 수 있습니다. (PC4가 1.00인 이유는 전체 데이터에서 변수가 4개이기 때문입니다)

  

주성분의 loading : 주성분의 해석과 작명

# 각 변수의 주성분별 기여도 (로딩)
loadings <- res.pca$rotation
print(loadings)

  주성분은 요인분석이나 오토인코더에서와는 달리 첫 번째 주성분 > 두번째 주성분 > 세번째 주성분 ... 순으로 중요도가 결정됩니다. 중요한 주성분들에서 주성분을 구성하는 선형 합들의 가중치(loading)을 확인함으로써 어떤 것과 관련이 있는 주성분인지를 추론해볼 수 있습니다.  

  PC1의 경우 모든 feature들에서 비슷한 크기를 갖습니다. 모든 범죄가 PC1에 비슷한 가중치를 갖고 방향(+/-) 도 같기 때문에 이는 '전체적인 범죄 강도' 정도라고 이름붙일 수 있을 것 같습니다.

 PC1과 PC2를 이용해 시각화해보면 다음과 같습니다.

fviz_pca_ind(res.pca,
             col.ind = "cos2",  # 점의 색은 기여도에 따라
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
             repel = TRUE       # label 안 겹치게
)

'의공학자를 위한 데이터분석 > 다변량 통계 분석' 카테고리의 다른 글

MVS-02 PCA (주성분분석)  (1) 2024.11.15
MVS-01 여는 글  (2) 2024.11.04