Principal Component Analysis

Multivariate Data Analysis

Description for Principal Component Analysis

Yeongeun Jeon
10-23-2022

1. 서론


2. 선형변환과 주성분



3. 개념과 정의

3-1. 개념


3-2. 정의


4. 상관행렬을 이용한 주성분 분석


4-1. 정의


5. 주성분 그래프


6. 주성분 개수 선택


6-1. 전체 변동에서의 공헌도


6-2. 평균 고유값


6-3. 스크리 그래프

출처 : https://www.janda.org/workshop/factor%20analysis/SPSS%20run/SPSS08.htm

7. 예제


7-1. 고객만족 데이터

# 데이터 불러오기
satis <- read.csv("C:/Users/User/Desktop/satis.csv")
satis
   ID gender age x1 x2 x3 x4 x5
1   1      F  10  1  2  4  1  1
2   2      F  10  1  2  3  2  1
3   3      F  20  2  5  5  2  2
4   4      F  20  2  5  4  2  2
5   5      F  30  1  2  3  4  3
6   6      M  30  1  3  4  1  1
7   7      M  40  4  5  5  3  3
8   8      M  40  1  3  4  4  4
9   9      M  50  3  3  5  5  4
10 10      M  50  5  5  5  4  4

# 기술통계량 출력pacman::p_load("psych")
describe(satis[,c("x1", "x2", "x3", "x4", "x5")])
   vars  n mean   sd median trimmed  mad min max range  skew kurtosis
x1    1 10  2.1 1.45    1.5    1.88 0.74   1   5     4  0.83    -0.92
x2    2 10  3.5 1.35    3.0    3.50 1.48   2   5     3  0.12    -1.94
x3    3 10  4.2 0.79    4.0    4.25 1.48   3   5     2 -0.29    -1.50
x4    4 10  2.8 1.40    2.5    2.75 2.22   1   5     4  0.10    -1.64
x5    5 10  2.5 1.27    2.5    2.50 2.22   1   4     3  0.00    -1.82
     se
x1 0.46
x2 0.43
x3 0.25
x4 0.44
x5 0.40

Caution! Package psych에 내장되어 있는 함수 describe()를 이용하여 기술통계량을 출력할 수 있다.
Result! 변수 \(x_1\)의 표준편차는 다른 변수들에 비해 상대적으로 크지만, 변수 \(x_3\)는 다른 변수들에 비해 상대적으로 표준편차가 작다.


# 상관행렬 출력NAcor(satis[,c("x1", "x2", "x3", "x4", "x5")])
          x1         x2        x3         x4        x5
x1 1.0000000 0.70784332 0.7581754 0.44960032 0.5738636
x2 0.7078433 1.00000000 0.7282191 0.05868157 0.2909287
x3 0.7581754 0.72821908 1.0000000 0.24174689 0.4438968
x4 0.4496003 0.05868157 0.2417469 1.00000000 0.9389683
x5 0.5738636 0.29092868 0.4438968 0.93896829 1.0000000

Result! 상대적으로 표준편차가 큰 변수 \(x_1\)은 다른 변수들과 상관계수도 높으며, 특히, 변수 \(x_3\)와 큰 양의 상관성을 가지고 있다. 반면, 상대적으로 표준편차가 작은 변수 \(x_3\)는 변수 \(x_4\), \(x_5\)와의 상관계수가 낮다. 그리고, 변수 \(x_4\)\(x_5\) 사이에는 매우 큰 양의 상관성을 가지고 있다(\(r=0.94\)).


# 공분산행렬을 이용한 주성분 분석NAsatis.prcomp <- prcomp(satis[,c("x1", "x2", "x3", "x4", "x5")])
satis.prcomp
Standard deviations (1, .., p=5):
[1] 2.2542944 1.5386966 0.6528647 0.4472292 0.2157445

Rotation (n x k) = (5 x 5):
         PC1        PC2         PC3        PC4        PC5
x1 0.5723794  0.2916057 -0.72250071  0.2316137  0.1081469
x2 0.3966884  0.6003640  0.62118712  0.2716472 -0.1501190
x3 0.2564469  0.2233868 -0.03232539 -0.9143660 -0.2173088
x4 0.4617789 -0.5982335  0.07138977  0.1323191 -0.6373947
x5 0.4858141 -0.3830720  0.29321981 -0.1378017  0.7157328

Caution! 주성분 분석은 R에 내장되어 있는 함수 prcomp()를 통해 수행할 수 있다. 자세한 옵션은 ?prcomp를 통해 확인한다.
Result! 함수 prcomp()로부터 얻어진 리스트 객체에는 각 결과들이 별도로 저장되어 있다. 첫 번째 결과 “Standard deviations”에는 주성분의 표준편차(즉, 공분산행렬의 고유값의 제곱근)이 저장되어 있다. 두 번째 결과 “Rotation”에는 주성분 계수(즉, 공분산행렬의 단위 고유벡터)가 저장되어 있다.


satis.prcomp$sdev        # 주성분의 표준편차NA
[1] 2.2542944 1.5386966 0.6528647 0.4472292 0.2157445
satis.prcomp$sdev^2      # 주성분의 분산 = 주성분에 의해 설명되는 분산의 양 = 공분산행렬의 고유값NA
[1] 5.08184308 2.36758724 0.42623226 0.20001396 0.04654569

Caution! 함수 eigen(cov(satis[,c("x1", "x2", "x3", "x4", "x5")]))를 통해 주성분의 분산이 공분산행렬의 고유값임을 확인할 수 있으며, 공분산행렬의 대각성분 합이 주성분 분산의 합(공분산행렬의 고유값의 합)과 같음을 알 수 있다.


# 주성분 계수
satis.prcomp$rotation    
         PC1        PC2         PC3        PC4        PC5
x1 0.5723794  0.2916057 -0.72250071  0.2316137  0.1081469
x2 0.3966884  0.6003640  0.62118712  0.2716472 -0.1501190
x3 0.2564469  0.2233868 -0.03232539 -0.9143660 -0.2173088
x4 0.4617789 -0.5982335  0.07138977  0.1323191 -0.6373947
x5 0.4858141 -0.3830720  0.29321981 -0.1378017  0.7157328

Caution! 함수 eigen(cov(satis[,c("x1", "x2", "x3", "x4", "x5")]))를 통해 주성분 계수가 공분산행렬의 단위 고유벡터임을 확인할 수 있다.
Result! 주성분 계수에 의하면, 첫 번째 주성분 \(Y_1=0.572C_{1}+0.397C_{2}+0.256C_{3}+0.462C_{4}+0.486C_5\)이며, 두 번째 주성분 \(Y_2=0.292C_1+0.600C_2+0.223C_3-0.598C_4-0.383C_5\)이 된다. 여기서 확률변수 \(C_{i}\)\(X_i-\mu_i\)이며, \(\mu_i\)\(X_i\)의 평균을 의미한다. 즉, 함수 prcomp()는 기본적으로 중심화(평균이 0)된 데이터행렬을 대상으로 한다. 즉, 위의 분석 결과는 prcomp(satis[,c("x1", "x2", "x3", "x4", "x5")], center = TRUE, scale = FALSE)와 동일하다.
주성분의 의미를 해석해보면, 첫 번째 주성분은 주성분 계수가 서로 비슷하여 전반적인 만족도를 나타낸다고 할 수 있으며, 두 번째 주성분은 변수 \(x_1\), \(x_2\), \(x_3\)와 변수 \(x_4\), \(x_5\)의 부호가 반대이므로 가격, 성능, 편리성 제품의 “내형적 요인”과 디자인, 색상 등 제품의 “외형적 요인”의 만족도 차이를 나타낸다고 할 수 있다.


# 요약
summary(satis.prcomp)    
Importance of components:
                          PC1    PC2     PC3     PC4     PC5
Standard deviation     2.2543 1.5387 0.65286 0.44723 0.21574
Proportion of Variance 0.6257 0.2915 0.05248 0.02463 0.00573
Cumulative Proportion  0.6257 0.9172 0.96964 0.99427 1.00000

Result! 첫 2개의 고유값은 5.082, 2.368로서 각각 전체 변동의 62.6%(=5.082/8.122)와 29.2%(=2.368/8.122)를 차지한다. 따라서, 첫 2개의 주성분에 의해 데이터 변동의 약 91.7%가 설명될 수 있음을 알 수 있다. 이는 2개의 주성분으로 데이터 변동을 충분히 설명할 수 있음을 가리키며, 만약 첫 2개의 주성분을 취할 경우 이는 원래 다섯 개의 관찰변수들이 가지고 있는 정보를 2차원으로 축약한다는 의미를 가진다.


# 스크리 그래프래프
par(mfrow = c(1, 2))
screeplot(satis.prcomp, type = "b", main = "")  # 막대그래프screeplot(satis.prcomp, type = "l", main = "")  # 선 그래프

Caution! 함수 screeplot()을 이용하여 스크리 그래프를 작성할 수 있다.
Result! 스트리 그래프를 보면 첫 번째 주성분과 두 번째 주성분의 분산(고유값)이 크며 가파른 경사를 형성한다. 그러므로, 주성분 개수는 2개로 선정할 수 있다.


# 주성분점수
satis.score <- satis.prcomp$x           
satis.score
             PC1        PC2         PC3         PC4         PC5
 [1,] -2.8358625  0.3854386 -0.69889614 -0.51084444  0.22339007
 [2,] -2.6305305 -0.4361818 -0.59518098  0.53584068 -0.19669584
 [3,]  0.1306219  1.7202178  0.77444872 -0.38413777 -0.25779081
 [4,] -0.1258250  1.4968309  0.80677411  0.53022827 -0.04048198
 [5,] -0.7353444 -2.3987927  0.13403819  0.52487542 -0.04001978
 [6,] -2.4391741  0.9858026 -0.07770902 -0.23919722  0.07327109
 [7,]  2.2229738  1.3221236 -0.30594311  0.07360693  0.03684093
 [8,]  0.4036049 -1.9581138  1.01611974 -0.25564510  0.30828518
 [9,]  2.2665896 -1.7497491 -0.38981729 -0.57446472 -0.33012467
[10,]  3.7429463  0.6324238 -0.66383422  0.29973796  0.22332582

Caution! 주성분점수는 객체의 관찰값에 의해서 얻어지는 주성분 값으로, 다음 단계의 통계분석(예컨대, 회귀분석 또는 군집분석)에서 원래의 관찰변수 대신에 유용하게 사용될 수 있다. 함수 prcomp()로부터 얻어진 리스트 객체에는 주성분점수도 포함되어 있으며, 이는 객체 “x”에 저장되어 있다.
Result! 첫 번째 주성분과 두 번째 주성분에 의해 얻어지는 \(i\)번째 개체의 주성분점수는 다음과 같다. \[ \begin{align} \begin{cases} y_{i1}=0.572c_{i1}+0.397c_{i2}+0.256c_{i3}+0.462c_{i4}+0.486c_{i5},\\ y_{i2}=0.292c_{i1}+0.600c_{i2}+0.223c_{i3}-0.598c_{i4}-0.383c_{i5}, \end{cases} \end{align} \] 여기서 \(c_{ij}=x_{ij}-\bar{x}_{j}\)\(i\)번째 개체의 \(j\)번째 변수 관찰값 \(x_{ij}\)에서 \(j\)번째 변수의 평균값 \(\bar{x}_j\)을 뺀 것을 의미한다.


# 주성분점수 그래프
par(mfrow = c(3, 1))
# 1. 개체 번호별 그래프 plot(satis.score[,1:2], xlim = c(-4, 4), ylim = c(-2, 2), main = "개체 번호별 그래프")")
abline(v = 0, h = 0, lty = 2)
text(satis.score[,1:2],  labels = satis$ID, pos = 4, col = "red")

# 2. 성별 그래프 plot(satis.score[,1:2], xlim = c(-4, 4), ylim = c(-2, 2), main = "성별 그래프")")
abline(v = 0, h = 0, lty = 2)
text(satis.score[,1:2],  labels = satis$gender, pos = 4, col = "red")

# 3. 연령대별 그래프 plot(satis.score[,1:2], xlim = c(-4, 4), ylim = c(-2, 2), main = "연령대별 그래프")")
abline(v = 0, h = 0, lty = 2)
text(satis.score[,1:2],  labels = satis$age, pos = 4, col = "red")

Result! 첫 번째 그래프를 살펴보면, 그래프의 오른쪽에 위치하는 “10”, “9”, “7”번 개체들은 첫 번째 주성분 값이 높으므로 전반적인 만족도가 높은 편이며, 왼쪽에 위치하는 “1”, “2”, “6”번 개체들은 전반적인 만족도가 낮음을 알 수 있다. 또한, 그래프의 위쪽에 위치하는 “3”, “4”, “7”번 개체들은 두 번째 주성분 값이 높으므로 가격, 성능, 편리성 등 제품의 내형적 요인에는 만족도가 높으나 디자인, 색상 등 외형적 요인에는 만족도가 낮은 반면, 아래쪽에 위치하는 “5”, “8”, “9”번 개체들은 외형적 요인에는 만족도가 높으나 내형적 요인에는 만족도가 낮은 편이라고 해석할 수 있다. 성별, 연령대별도 똑같이 해석할 수 있다.


# 주성분점수 예측
predict(satis.prcomp, newdata = tail(satis[,c("x1", "x2", "x3", "x4", "x5")], 2))
        PC1        PC2        PC3        PC4        PC5
9  2.266590 -1.7497491 -0.3898173 -0.5744647 -0.3301247
10 3.742946  0.6324238 -0.6638342  0.2997380  0.2233258

Caution! 함수 predict()를 이용해서 새로운 데이터에 대한 주성분점수를 예측할 수 있다. 여기서는 설명의 편의상 마지막 2개의 자료를 새로운 자료로 취급하여 예측을 수행하였다.


# 주성분 분석 행렬도biplot(satis.prcomp)

Caution! 주성분 계수(단위 고유벡터)와 주성분점수를 하나의 그래프에 함께 표현한 것을 행렬도(Biplot)라고 한다. 일반적으로 행렬도에서는 개체를 점으로 표현하고, 변수를 벡터로 표현한다. 이러한 행렬도를 통해서 개체들의 군집성, 변수들의 연관구조, 변수별 개체의 상대적 위치 등을 시각적으로 파악할 수 있다.
Result! 화살표를 먼저 살펴보면, 첫 번째 주성분을 기준으로 화살표는 모두 0의 오른쪽에 위치하기에 주성분 계수가 양수임을 알 수 있다. 또한, 두 번째 주성분을 기준으로 변수 \(x_1\), \(x_2\), \(x_3\)는 0보다 위쪽에 위치하기 때문에 주성분 계수가 양수이며, 변수 \(x_4\), \(x_5\)는 0보다 아래 쪽에 위치하기에 주성분 계수가 음수이다. 또한, 화살표의 길이는 변수의 분산을 의미하는데 변수 \(x_3\)가 분산이 가장 작기 때문에 가장 짧다. 화살표끼리 거리가 가깝고 같은 방향일수록 변수들의 상관성이 높아지며, 이는 변수 \(x_1\)\(x_3\), 변수 \(x_4\)\(x_5\)의 상관성이 높다는 것을 의미한다. 각 주성분 축에 가깝게 평행을 이루는 변수가 해당 주성분에 영향을 가장 많이 주는 변수로 해석할 수 있다. 예를 들어, 두 번째 주성분 축과 변수 \(x_2\)\(x_4\)가 평행에 가까운데 두 변수의 두 번째 주성분 계수는 상대적으로 크다. 그리고, 개체를 살펴보면, 오른쪽 축은 두 번째 주성분 값을 의미하고 위쪽 축은 첫 번째 주성분 값을 의미한다. 즉, “7”, “10”, “9”번 개체는 첫 번째 주성분점수 값이 양수임을 나타낸다. 게다가, “7”, “10”번 개체는 변수 \(x_1\), \(x_2\), \(x_3\)에 가까우므로 변수 \(x_1\), \(x_2\), \(x_3\)의 값이 높다는 것을 나타내고, “9”번 개체는 변수 \(x_4\), \(x_5\)에 가까우므로 변수 \(x_4\), \(x_5\)의 값이 높다는 것을 나타낸다.


# ggbiplot을 이용한 주성분 분석 행렬도pacman::p_load("devtools")
install_github("vqv/ggbiplot")
colorspace   (1.4-1 -> 2.0-3) [CRAN]
rlang        (1.0.2 -> 1.0.6) [CRAN]
lifecycle    (1.0.1 -> 1.0.3) [CRAN]
cli          (3.3.0 -> 3.4.1) [CRAN]
utf8         (1.2.1 -> 1.2.2) [CRAN]
vctrs        (0.4.1 -> 0.5.1) [CRAN]
pillar       (1.7.0 -> 1.8.1) [CRAN]
magrittr     (2.0.1 -> 2.0.3) [CRAN]
fansi        (0.4.2 -> 1.0.3) [CRAN]
viridisLite  (0.4.0 -> 0.4.1) [CRAN]
RColorBrewer (1.1-2 -> 1.1-3) [CRAN]
R6           (2.5.0 -> 2.5.1) [CRAN]
farver       (2.1.0 -> 2.1.1) [CRAN]
Rcpp         (1.0.3 -> 1.0.9) [CRAN]
withr        (2.4.2 -> 2.5.0) [CRAN]
tibble       (3.1.7 -> 3.1.8) [CRAN]
scales       (1.1.1 -> 1.2.1) [CRAN]
isoband      (0.2.4 -> 0.2.6) [CRAN]
gtable       (0.3.0 -> 0.3.1) [CRAN]
plyr         (1.8.5 -> 1.8.8) [CRAN]
ggplot2      (3.3.6 -> 3.4.0) [CRAN]

  There are binary versions available but the source versions
  are later:
             binary source needs_compilation
colorspace    2.0-1  2.0-3              TRUE
rlang        0.4.11  1.0.6              TRUE
lifecycle     1.0.0  1.0.3             FALSE
cli           2.5.0  3.4.1              TRUE
utf8          1.2.1  1.2.2              TRUE
vctrs         0.3.8  0.5.1              TRUE
pillar        1.6.0  1.8.1             FALSE
magrittr      2.0.1  2.0.3              TRUE
fansi         0.4.2  1.0.3              TRUE
viridisLite   0.4.0  0.4.1             FALSE
RColorBrewer  1.1-2  1.1-3             FALSE
R6            2.5.0  2.5.1             FALSE
farver        2.1.0  2.1.1              TRUE
Rcpp          1.0.6  1.0.9              TRUE
withr         2.4.2  2.5.0             FALSE
tibble        3.1.1  3.1.8              TRUE
scales        1.1.1  1.2.1             FALSE
isoband       0.2.4  0.2.6              TRUE
gtable        0.3.0  0.3.1             FALSE
plyr          1.8.6  1.8.8              TRUE
ggplot2       3.3.3  3.4.0             FALSE

  
  
  
   checking for file 'C:\Users\User\AppData\Local\Temp\RtmpcvI2Cu\remotes4970d177fc9\vqv-ggbiplot-7325e88/DESCRIPTION' ...
  
v  checking for file 'C:\Users\User\AppData\Local\Temp\RtmpcvI2Cu\remotes4970d177fc9\vqv-ggbiplot-7325e88/DESCRIPTION'

  
  
  
-  preparing 'ggbiplot':
   checking DESCRIPTION meta-information ...
  
   checking DESCRIPTION meta-information ... 
  
v  checking DESCRIPTION meta-information

  
  
  
-  checking for LF line-endings in source and make files and shell scripts

  
-  checking for empty or unneeded directories

  
  
  
-  looking to see if a 'data/datalist' file should be added

  
  
  
-  building 'ggbiplot_0.55.tar.gz'

  
   
library(ggbiplot)

ggbiplot(satis.prcomp,                      # 함수 prcomp에 의한 객체         obs.scale = 1,                     # 관찰값에 적용할 스케일NA= 1,                     # 변수에 적용할 스케일         labels = satis$ID,                 # 점에 대한 라벨벨
         circle = TRUE) +
  theme_bw()

Caution! Package ggbiplot을 이용해서 주성분 분석 행렬도를 작성할 수 있다. 함수 ggbiplot()에 대한 자세한 옵션은 여기를 참고한다.


# 공분산행렬을 입력으로 하는 주성분 분석NAcov.mat <- cov(satis[,c("x1", "x2", "x3", "x4", "x5")])
cov.mat
          x1        x2        x3        x4        x5
x1 2.1000000 1.3888889 0.8666667 0.9111111 1.0555556
x2 1.3888889 1.8333333 0.7777778 0.1111111 0.5000000
x3 0.8666667 0.7777778 0.6222222 0.2666667 0.4444444
x4 0.9111111 0.1111111 0.2666667 1.9555556 1.6666667
x5 1.0555556 0.5000000 0.4444444 1.6666667 1.6111111
satis.princomp <- princomp(covmat = cov.mat)
satis.princomp
Call:
princomp(covmat = cov.mat)

Standard deviations:
   Comp.1    Comp.2    Comp.3    Comp.4    Comp.5 
2.2542944 1.5386966 0.6528647 0.4472292 0.2157445 

 5  variables and  NA observations.
summary(satis.princomp, 
        loadings = TRUE,      # 주성분 계수(단위 고유벡터) 출력 여부
        cutoff = 0)           # 고유벡터 값 등을 출력할 때 주어진 값보다 작은 값은 출력하지 않도록 지정NA
Importance of components:
                          Comp.1    Comp.2    Comp.3     Comp.4
Standard deviation     2.2542944 1.5386966 0.6528647 0.44722920
Proportion of Variance 0.6256715 0.2914950 0.0524773 0.02462552
Cumulative Proportion  0.6256715 0.9171665 0.9696438 0.99426934
                           Comp.5
Standard deviation     0.21574450
Proportion of Variance 0.00573066
Cumulative Proportion  1.00000000

Loadings:
   Comp.1 Comp.2 Comp.3 Comp.4 Comp.5
x1  0.572  0.292  0.723  0.232  0.108
x2  0.397  0.600 -0.621  0.272 -0.150
x3  0.256  0.223  0.032 -0.914 -0.217
x4  0.462 -0.598 -0.071  0.132 -0.637
x5  0.486 -0.383 -0.293 -0.138  0.716

Caution! 함수 princomp()는 공분산행렬을 입력 데이터로 하여 주성분 분석을 수행할 수 있다.
Result! 결과는 “satis.prcomp”와 동일하다.


# 상관행렬을 이용한 주성분 분석NAsatis.cor.prcomp <- prcomp(satis[,c("x1", "x2", "x3", "x4", "x5")], center = TRUE, scale = TRUE) 
satis.cor.prcomp
Standard deviations (1, .., p=5):
[1] 1.7628337 1.1829978 0.5033695 0.4610255 0.1643420

Rotation (n x k) = (5 x 5):
         PC1        PC2         PC3         PC4        PC5
x1 0.5106549  0.1714026 -0.05545212  0.83272782 -0.1155083
x2 0.4065628  0.5002084 -0.64671083 -0.37226185  0.1663863
x3 0.4650578  0.3439269  0.75415171 -0.29030512  0.1114166
x4 0.3795169 -0.6205430 -0.05742977 -0.01399615  0.6836660
x5 0.4621973 -0.4658899 -0.08153030 -0.28898535 -0.6922142

Caution! 상관행렬에 기초하여 주성분 분석을 수행한다는 것은 표준화 변수를 분석대상으로 주성분 분석을 수행한다는 것이다. 함수 prcomp()의 옵션 center = TRUEscale = TRUE를 지정하여 상관행렬에 기초한 주성분 분석을 수행할 수 있다.
Result! 상관행렬을 이용한 주성분 분석 결과를 살펴보면, 위에서 공분산행렬에 기초하여 수행한 주성분 분석 prcomp(satis[,c("x1", "x2", "x3", "x4", "x5")], center = TRUE, scale = FALSE) 결과와는 다른 것을 확인할 수 있다.


satis.cor.prcomp$sdev        # 주성분의 표준편차NA
[1] 1.7628337 1.1829978 0.5033695 0.4610255 0.1643420
satis.cor.prcomp$sdev^2      # 주성분의 분산 = 주성분에 의해 설명되는 분산의 양 = 상관행렬의 고유값NA
[1] 3.1075826 1.3994838 0.2533809 0.2125445 0.0270083

Caution! 함수 eigen(cor(satis[,c("x1", "x2", "x3", "x4", "x5")]))를 통해 주성분의 분산이 상관행렬의 고유값임을 확인할 수 있으며, 상관행렬의 대각성분 합이 주성분 분산의 합(상관행렬의 고유값의 합)인 변수 개수 “5”와 같음을 알 수 있다.


satis.cor.prcomp$rotation    # 주성분 계수
         PC1        PC2         PC3         PC4        PC5
x1 0.5106549  0.1714026 -0.05545212  0.83272782 -0.1155083
x2 0.4065628  0.5002084 -0.64671083 -0.37226185  0.1663863
x3 0.4650578  0.3439269  0.75415171 -0.29030512  0.1114166
x4 0.3795169 -0.6205430 -0.05742977 -0.01399615  0.6836660
x5 0.4621973 -0.4658899 -0.08153030 -0.28898535 -0.6922142

Caution! 함수 eigen(cor(satis[,c("x1", "x2", "x3", "x4", "x5")]))를 통해 주성분 계수가 상관행렬의 단위 고유벡터임을 확인할 수 있다.
Result! 주성분 계수에 의하면, 첫 번째 주성분 \(Y_1=0.511Z_{1}+0.407Z_{2}+0.465Z_{3}+0.380Z_{4}+0.462Z_{5}\)이며, 두 번째 주성분 \(Y_2=0.171Z_{1}+0.500Z_{2}+0.344Z_{3}-0.621Z_{4}-0.466Z_{5}\)이 된다. 여기서 확률변수 \(Z_{i}\)\((X_i-\mu_i)/\sigma_{i}\)이며, \(\mu_i\)\(\sigma_{i}\)는 각각 \(X_i\)의 평균과 표준편차를 의미한다.
주성분의 의미를 해석해보면, 첫 번째 주성분은 주성분 계수가 서로 비슷하여 전반적인 만족도를 나타낸다고 할 수 있으며, 두 번째 주성분은 변수 \(x_1\), \(x_2\), \(x_3\)와 변수 \(x_4\), \(x_5\)의 부호가 반대이므로 가격, 성능, 편리성 제품의 “내형적 요인”과 디자인, 색상 등 제품의 “외형적 요인”의 만족도 차이를 나타낸다고 할 수 있다.


# 요약
summary(satis.cor.prcomp)    
Importance of components:
                          PC1    PC2     PC3     PC4    PC5
Standard deviation     1.7628 1.1830 0.50337 0.46103 0.1643
Proportion of Variance 0.6215 0.2799 0.05068 0.04251 0.0054
Cumulative Proportion  0.6215 0.9014 0.95209 0.99460 1.0000

Result! 첫 2개의 고유값은 3.108, 1.399로서 각각 전체 변동의 62.2%(=3.108/5)와 28.0%(=1.399/5)를 차지한다. 따라서, 첫 2개의 주성분에 의해 데이터 변동의 약 90.1%가 설명될 수 있음을 알 수 있다. 이는 2개의 주성분으로 데이터 변동을 충분히 설명할 수 있음을 가리키며, 만약 첫 2개의 주성분을 취할 경우 이는 원래 다섯 개의 관찰변수들이 가지고 있는 정보를 2차원으로 축약한다는 의미를 가진다.


# 스크리 그래프래프
par(mfrow = c(1, 2))
screeplot(satis.cor.prcomp, type = "b", main = "")  # 막대그래프screeplot(satis.cor.prcomp, type = "l", main = "")  # 선 그래프

Result! 스트리 그래프를 보면 첫 번째 주성분과 두 번째 주성분의 분산(고유값)이 크며 가파른 경사를 형성한다. 그러므로, 주성분 개수는 2개로 선정할 수 있다.


# 주성분점수
satis.cor.score <- satis.cor.prcomp$x           
satis.cor.score
             PC1        PC2         PC3          PC4         PC5
 [1,] -1.9906473  0.5778652  0.73759241  0.213431924 -0.18686461
 [2,] -2.3088242 -0.3018902 -0.25953723  0.571452234  0.16077659
 [3,]  0.4876344  1.4296420  0.11720524 -0.642443414  0.18686107
 [4,] -0.1019340  0.9936350 -0.83885655 -0.274414499  0.04561479
 [5,] -1.0377676 -1.9234789 -0.47013838  0.096087391  0.04784539
 [6,] -1.6903807  0.9472936  0.25996481 -0.061501673 -0.06398017
 [7,]  1.8279334  0.8554056 -0.06462653  0.269147743 -0.02902117
 [8,]  0.2162042 -1.4850896 -0.05593690 -0.774548937 -0.23337697
 [9,]  1.7819347 -1.2562730  0.78252584 -0.003312879  0.23734016
[10,]  2.8158471  0.1628903 -0.20819270  0.606102111 -0.16519509

Result! 첫 번째 주성분과 두 번째 주성분에 의해 얻어지는 \(i\)번째 개체의 주성분점수는 다음과 같다. \[ \begin{align} \begin{cases} y_{i1}=0.511z_{i1}+0.407z_{i2}+0.465z_{i3}+0.380z_{i4}+0.462z_{i5},\\ y_{i2}=0.171z_{i1}+0.500z_{i2}+0.344z_{i3}-0.621z_{i4}-0.466z_{i5}, \end{cases} \end{align} \] 여기서 \(z_{ij}=(x_{ij}-\bar{x}_{j})/s_{j}\)\(i\)번째 개체의 \(j\)번째 변수 관찰값 \(x_{ij}\)에서 \(j\)번째 변수의 평균값 \(\bar{x}_j\)을 뺀 후 \(j\)번째 변수의 표준편차 값 \(s_j\)로 나눈 것을 의미한다.


# 상관행렬을 입력으로 하는 주성분 분석NAcor.mat <- cor(satis[,c("x1", "x2", "x3", "x4", "x5")])
cor.mat
          x1         x2        x3         x4        x5
x1 1.0000000 0.70784332 0.7581754 0.44960032 0.5738636
x2 0.7078433 1.00000000 0.7282191 0.05868157 0.2909287
x3 0.7581754 0.72821908 1.0000000 0.24174689 0.4438968
x4 0.4496003 0.05868157 0.2417469 1.00000000 0.9389683
x5 0.5738636 0.29092868 0.4438968 0.93896829 1.0000000
satis.cor.princomp <- princomp(covmat = cor.mat)
satis.cor.princomp
Call:
princomp(covmat = cor.mat)

Standard deviations:
   Comp.1    Comp.2    Comp.3    Comp.4    Comp.5 
1.7628337 1.1829978 0.5033695 0.4610255 0.1643420 

 5  variables and  NA observations.
summary(satis.cor.princomp, 
        loadings = TRUE,      # 주성분 계수(단위 고유벡터) 출력 여부
        cutoff = 0)           # 고유벡터 값 등을 출력할 때 주어진 값보다 작은 값은 출력하지 않도록 지정NA
Importance of components:
                          Comp.1    Comp.2     Comp.3     Comp.4
Standard deviation     1.7628337 1.1829978 0.50336951 0.46102546
Proportion of Variance 0.6215165 0.2798968 0.05067617 0.04250889
Cumulative Proportion  0.6215165 0.9014133 0.95208945 0.99459834
                           Comp.5
Standard deviation     0.16434203
Proportion of Variance 0.00540166
Cumulative Proportion  1.00000000

Loadings:
   Comp.1 Comp.2 Comp.3 Comp.4 Comp.5
x1  0.511  0.171  0.055  0.833  0.116
x2  0.407  0.500  0.647 -0.372 -0.166
x3  0.465  0.344 -0.754 -0.290 -0.111
x4  0.380 -0.621  0.057 -0.014 -0.684
x5  0.462 -0.466  0.082 -0.289  0.692

Caution! 함수 princomp()는 상관행렬을 입력 데이터로 하여 주성분 분석을 수행할 수 있다.
Result! 결과는 “satis.cor.prcomp”와 동일하다.


7-2. 학생성적 데이터

# 데이터 불러오기
student <- read.csv("C:/Users/User/Desktop/student.csv")
student
   ID x1 x2 x3 x4 x5
1   1  3 33 73  8 12
2   2  3 30 59 28 20
3   3 35 83 91 32 34
4   4 35 83 85 33 32
5   5 15 40 55 68 52
6   6  3 53 76 10  8
7   7 68 83 85 48 50
8   8 15 47 77 76 76
9   9 46 60 83 83 68
10 10 98 83 91 80 72

# 기술통계량 출력pacman::p_load("psych")
describe(student[,c("x1", "x2", "x3", "x4", "x5")])
   vars  n mean    sd median trimmed   mad min max range  skew
x1    1 10 32.1 31.56   25.0   27.50 31.88   3  98    95  0.80
x2    2 10 59.5 22.01   56.5   60.25 37.06  30  83    53 -0.02
x3    3 10 77.5 12.38   80.0   78.62  8.90  55  91    36 -0.63
x4    4 10 46.6 28.55   40.5   46.88 43.00   8  83    75  0.01
x5    5 10 42.4 24.94   42.0   42.50 35.58   8  76    68  0.00
   kurtosis   se
x1    -0.69 9.98
x2    -1.87 6.96
x3    -1.09 3.91
x4    -1.77 9.03
x5    -1.71 7.89

Result! 변수 \(x_1\)의 표준편차는 다른 변수들에 비해 상대적으로 크지만, 변수 \(x_3\)는 다른 변수들에 비해 상대적으로 표준편차가 작다.


# 상관행렬 출력NAcor(student[,c("x1", "x2", "x3", "x4", "x5")])
          x1        x2        x3        x4        x5
x1 1.0000000 0.7838622 0.6833432 0.5592287 0.6102284
x2 0.7838622 1.0000000 0.8604151 0.2117815 0.3092596
x3 0.6833432 0.8604151 1.0000000 0.1380259 0.2793357
x4 0.5592287 0.2117815 0.1380259 1.0000000 0.9731614
x5 0.6102284 0.3092596 0.2793357 0.9731614 1.0000000

Result! 상대적으로 표준편차가 큰 변수 \(x_1\)은 상대적으로 다른 변수들과 0.5 이상의 높은 상관성을 보인다. 반면, 상대적으로 표준편차가 작은 변수 \(x_3\)는 변수 \(x_4\), \(x_5\)와 상관계수가 0.3 이하로 낮은 상관성을 보인다. 그리고, 변수 \(x_4\)\(x_5\) 사이에는 매우 큰 양의 상관성을 가지고 있다(\(r=0.97\)).


# 공분산행렬을 이용한 주성분 분석NAstudent.prcomp <- prcomp(student[,c("x1", "x2", "x3", "x4", "x5")]) 
student.prcomp
Standard deviations (1, .., p=5):
[1] 46.259833 27.802085 10.689902  5.935039  2.997379

Rotation (n x k) = (5 x 5):
         PC1        PC2         PC3         PC4         PC5
x1 0.6155240  0.4184625  0.66098180 -0.08517714  0.04321101
x2 0.3149575  0.5395460 -0.57224849  0.52551269  0.07784525
x3 0.1533269  0.2865461 -0.39464213 -0.75500570 -0.41061682
x4 0.5208733 -0.5438504 -0.06785537  0.26119676 -0.60007473
x5 0.4765646 -0.3948383 -0.27438652 -0.27986409  0.68071806

Result! 함수 prcomp()로부터 얻어진 리스트 객체에는 각 결과들이 별도로 저장되어 있다. 첫 번째 결과 “Standard deviations”에는 주성분의 표준편차(즉, 공분산행렬의 고유값의 제곱근)이 저장되어 있다. 두 번째 결과 “Rotation”에는 주성분 계수(즉, 공분산행렬의 단위 고유벡터)가 저장되어 있다.


student.prcomp$sdev        # 주성분의 표준편차NA
[1] 46.259833 27.802085 10.689902  5.935039  2.997379
student.prcomp$sdev^2      # 주성분의 분산 = 주성분에 의해 설명되는 분산의 양 = 공분산행렬의 고유값NA
[1] 2139.972189  772.955942  114.274008   35.224690    8.984282

Caution! 함수 eigen(cov(student[,c("x1", "x2", "x3", "x4", "x5")]))를 통해 주성분의 분산이 공분산행렬의 고유값임을 확인할 수 있으며, 공분산행렬의 대각성분 합이 주성분 분산의 합(공분산행렬의 고유값의 합)과 같음을 알 수 있다.


# 주성분 계수
student.prcomp$rotation   
         PC1        PC2         PC3         PC4         PC5
x1 0.6155240  0.4184625  0.66098180 -0.08517714  0.04321101
x2 0.3149575  0.5395460 -0.57224849  0.52551269  0.07784525
x3 0.1533269  0.2865461 -0.39464213 -0.75500570 -0.41061682
x4 0.5208733 -0.5438504 -0.06785537  0.26119676 -0.60007473
x5 0.4765646 -0.3948383 -0.27438652 -0.27986409  0.68071806

Caution! 함수 eigen(cov(student[,c("x1", "x2", "x3", "x4", "x5")]))를 통해 주성분 계수가 공분산행렬의 단위 고유벡터임을 확인할 수 있다.
Result! 주성분 계수에 의하면, 첫 번째 주성분 \(Y_1=0.616C_{1}+0.315C_{2}+0.153C_{3}+0.521C_{4}+0.477C_{5}\)이며, 두 번째 주성분 \(Y_2=0.418C_1+0.540C_2+0.287C_3-0.544C_4-0.395C_{5}\)이 된다. 여기서 확률변수 \(C_{i}\)\(X_i-\mu_i\)이며, \(\mu_i\)\(X_i\)의 평균을 의미한다. 즉, 함수 prcomp()는 기본적으로 중심화(평균이 0)된 데이터행렬을 대상으로 한다. 즉, 위의 분석 결과는 prcomp(dat.x, center = TRUE, scale = FALSE)와 동일하다.
주성분의 의미를 해석해보면, 첫 번째 주성분은 주성분 계수가 서로 비슷하여 전반적인 평점을 나타낸다고 할 수 있으며, 두 번째 주성분은 변수 \(x_1\), \(x_2\), \(x_3\)와 변수 \(x_4\), \(x_5\)의 부호가 반대이므로 국어, 영어, 제2외국어의 “인문계열”과 수학, 과학의 “이과계열”의 점수 차이를 나타낸다고 할 수 있다.


# 요약
summary(student.prcomp)    
Importance of components:
                           PC1     PC2      PC3     PC4     PC5
Standard deviation     46.2598 27.8021 10.68990 5.93504 2.99738
Proportion of Variance  0.6967  0.2517  0.03721 0.01147 0.00293
Cumulative Proportion   0.6967  0.9484  0.98561 0.99707 1.00000

Result! 첫 2개의 고유값은 2139.972, 772.956로서 각각 전체 변동의 69.7%(=2139.972/3071.411)와 25.2%(=772.956/3071.411)를 차지한다. 따라서, 첫 2개의 주성분에 의해 데이터 변동의 약 94.8%가 설명될 수 있음을 알 수 있다. 이는 2개의 주성분으로 데이터 변동을 충분히 설명할 수 있음을 가리키며, 만약 첫 2개의 주성분을 취할 경우 이는 원래 다섯 개의 관찰변수들이 가지고 있는 정보를 2차원으로 축약한다는 의미를 가진다.


# 스크리 그래프래프
par(mfrow = c(1, 2))
screeplot(student.prcomp, type = "b", main = "")  # 막대그래프screeplot(student.prcomp, type = "l", main = "")  # 선 그래프

Result! 스트리 그래프를 보면 첫 번째 주성분과 두 번째 주성분의 분산(고유값)이 크며 가파른 경사를 형성한다. 그러므로, 주성분 개수는 2개로 선정할 수 있다.


# 주성분점수
student.score <- student.prcomp$x           
student.score
              PC1        PC2        PC3        PC4         PC5
 [1,] -61.5413668   5.231022   8.666472 -9.6242324  0.99649177
 [2,] -50.4028345 -14.434976  12.356007  2.3543318 -0.04415861
 [3,]  -0.3514567  29.018103 -13.563126  0.4473432 -0.54559251
 [4,]  -1.7036742  27.544653 -10.714355  5.7983024 -0.04340246
 [5,]  -4.3952811 -39.552990   4.649289 11.0995753  0.67528203
 [6,] -55.6467471  17.373233  -3.000589  0.2628541 -2.60147547
 [7,]  34.9998806  26.089071   5.141256  1.8678545  4.63436503
 [8,]  16.7871502 -43.299075 -15.166696 -6.4591254  3.72326437
 [9,]  40.7164010 -22.241609  -2.763239 -2.7306959 -6.03517460
[10,]  81.5379285  14.272568  14.394982 -3.0162076 -0.75959955

Result! 첫 번째 주성분과 두 번째 주성분에 의해 얻어지는 \(i\)번째 개체의 주성분점수는 다음과 같다. \[ \begin{align} \begin{cases} y_{i1}=0.616c_{i1}+0.315c_{i2}+0.153c_{i3}+0.521c_{i3}+0.477c_{i5},\\ y_{i2}=0.418c_{i1}+0.540c_{i2}+0.287c_{i3}-0.544c_{i4}-0.395c_{i5}, \end{cases} \end{align} \] 여기서 \(c_{ij}=x_{ij}-\bar{x}_{j}\)\(i\)번째 개체의 \(j\)번째 변수 관찰값 \(x_{ij}\)에서 \(j\)번째 변수의 평균값 \(\bar{x}_j\)을 뺀 것을 의미한다.


# 주성분점수 그래프
plot(student.score[,1:2], xlim = c(-80, 80), ylim = c(-50, 50), main = "개체 번호별 그래프")")
abline(v = 0, h = 0, lty = 2)
text(student.score[,1:2],  labels = student$ID, pos = 4, col = "red")

Result! 그래프를 살펴보면, 그래프의 오른쪽에 위치하는 “10”, “9”, “7”번 개체들은 첫 번째 주성분 값이 높으므로 전반적인 평점이 높은 편이며, 왼쪽에 위치하는 “1”, “2”, “6”번 개체들은 전반적인 평점이 낮은 편임을 알 수 있다. 또한, 그래프의 위쪽에 위치하는 “3”, “4”, “7”번 개체들은 두 번째 주성분 값이 높으므로 국어, 영어, 제2외국어 등 인문계열 과목에는 점수가 높으나 수학, 과학 등 이과계열 과목에는 점수가 낮은 반면, 아래쪽에 위치하는 “5”, “8”번 개체들은 이과계열 과목에는 점수가 높으나 인문계열 과목에는 만족도가 낮은 편이라고 해석할 수 있다.


# 주성분점수 예측
predict(student.prcomp, newdata = tail(student[,c("x1", "x2", "x3", "x4", "x5")], 2))
        PC1       PC2       PC3       PC4        PC5
9  40.71640 -22.24161 -2.763239 -2.730696 -6.0351746
10 81.53793  14.27257 14.394982 -3.016208 -0.7595996

Caution! 함수 predict()를 이용해서 새로운 데이터에 대한 주성분점수를 예측할 수 있다. 여기서는 설명의 편의상 마지막 2개의 자료를 새로운 자료로 취급하여 예측을 수행하였다.


# 주성분 분석 행렬도biplot(student.prcomp)

Result! 화살표를 먼저 살펴보면, 첫 번째 주성분을 기준으로 화살표는 모두 0의 오른쪽에 위치하기에 주성분 계수가 양수임을 알 수 있다. 또한, 두 번째 주성분을 기준으로 변수 \(x_1\), \(x_2\), \(x_3\)는 0보다 위쪽에 위치하기 때문에 주성분 계수가 양수이며, 변수 \(x_4\), \(x_5\)는 0보다 아래 쪽에 위치하기에 주성분 계수가 음수이다. 또한, 화살표의 길이는 변수의 분산을 의미하는데 변수 \(x_3\)가 분산이 가장 작기 때문에 가장 짧다. 화살표끼리 거리가 가깝고 같은 방향일수록 변수들의 상관성이 높아지며, 이는 변수 \(x_2\)\(x_3\), 변수 \(x_4\)\(x_5\)의 상관성이 높다는 것을 의미한다. 그리고, 개체를 살펴보면, 오른쪽 축은 두 번째 주성분 값을 의미하고 위쪽 축은 첫 번째 주성분 값을 의미한다. 즉, “7”, “10”, “9”번 개체는 첫 번째 주성분점수 값이 양수임을 나타낸다. 게다가, “7”, “3”, “4”번 개체는 변수 \(x_2\)\(x_3\)에 가까우므로 두 변수의 값이 높다는 것을 나타내고, 변수 \(x_1\)에 가까운 “10”번 개체는 국어 점수가 높다는 것을 나타낸다.


# ggbiplot을 이용한 주성분 분석 행렬도pacman::p_load("devtools")
install_github("vqv/ggbiplot")
library(ggbiplot)

ggbiplot(student.prcomp,                    # 함수 prcomp에 의한 객체         obs.scale = 1,                     # 관찰값에 적용할 스케일NA= 1,                     # 변수에 적용할 스케일         labels = student$ID,               # 점에 대한 라벨벨
         circle = TRUE) +
  theme_bw()


# 공분산행렬을 입력으로 하는 주성분 분석NAcov.mat <- cov(student[,c("x1", "x2", "x3", "x4", "x5")])
cov.mat
         x1       x2        x3        x4        x5
x1 996.3222 544.6111 266.94444 504.04444 480.40000
x2 544.6111 484.5000 234.38889 133.11111 169.77778
x3 266.9444 234.3889 153.16667  48.77778  86.22222
x4 504.0444 133.1111  48.77778 815.37778 693.06667
x5 480.4000 169.7778  86.22222 693.06667 622.04444
student.princomp <- princomp(covmat = cov.mat)
student.princomp
Call:
princomp(covmat = cov.mat)

Standard deviations:
   Comp.1    Comp.2    Comp.3    Comp.4    Comp.5 
46.259833 27.802085 10.689902  5.935039  2.997379 

 5  variables and  NA observations.
summary(student.princomp, 
        loadings = TRUE,      # 주성분 계수(단위 고유벡터) 출력 여부
        cutoff = 0)           # 고유벡터 값 등을 출력할 때 주어진 값보다 작은 값은 출력하지 않도록 지정NA
Importance of components:
                           Comp.1     Comp.2     Comp.3     Comp.4
Standard deviation     46.2598334 27.8020852 10.6899021 5.93503916
Proportion of Variance  0.6967391  0.2516615  0.0372057 0.01146857
Cumulative Proportion   0.6967391  0.9484006  0.9856063 0.99707487
                            Comp.5
Standard deviation     2.997379263
Proportion of Variance 0.002925132
Cumulative Proportion  1.000000000

Loadings:
   Comp.1 Comp.2 Comp.3 Comp.4 Comp.5
x1  0.616  0.418  0.661  0.085  0.043
x2  0.315  0.540 -0.572 -0.526  0.078
x3  0.153  0.287 -0.395  0.755 -0.411
x4  0.521 -0.544 -0.068 -0.261 -0.600
x5  0.477 -0.395 -0.274  0.280  0.681

Result! 결과는 “student.prcomp”와 동일하다.


# 상관행렬을 이용한 주성분 분석NAstudent.cor.prcomp <- prcomp(student[,c("x1", "x2", "x3", "x4", "x5")], center = TRUE, scale = TRUE) 
student.cor.prcomp
Standard deviations (1, .., p=5):
[1] 1.7852209 1.2132058 0.4662250 0.3308475 0.1195505

Rotation (n x k) = (5 x 5):
         PC1         PC2         PC3        PC4         PC5
x1 0.5175853  0.09386107 -0.71009530  0.4642922  0.05910103
x2 0.4516210  0.43816660 -0.11258435 -0.7683317  0.03224429
x3 0.4206036  0.47398415  0.62887267  0.4183725 -0.16707843
x4 0.3980188 -0.57412032  0.06907097 -0.1329413 -0.69965898
x5 0.4391100 -0.49489900  0.28781556 -0.0372845  0.69139676

Result! 상관행렬을 이용한 주성분 분석 결과를 살펴보면, 위에서 공분산행렬에 기초하여 수행한 주성분 분석 prcomp(satis[,c("x1", "x2", "x3", "x4", "x5")], center = TRUE, scale = FALSE) 결과와는 다른 것을 확인할 수 있다.


student.cor.prcomp$sdev        # 주성분의 표준편차NA
[1] 1.7852209 1.2132058 0.4662250 0.3308475 0.1195505
student.cor.prcomp$sdev^2      # 주성분의 분산 = 주성분에 의해 설명되는 분산의 양 = 상관행렬의 고유값NA
[1] 3.18701362 1.47186824 0.21736574 0.10946007 0.01429233

Caution! 함수 eigen(cor(student[,c("x1", "x2", "x3", "x4", "x5")]))를 통해 주성분의 분산이 상관행렬의 고유값임을 확인할 수 있으며, 상관행렬의 대각성분 합이 주성분 분산의 합(상관행렬의 고유값의 합)인 변수 개수 “5”와 같음을 알 수 있다.


student.cor.prcomp$rotation    # 주성분 계수
         PC1         PC2         PC3        PC4         PC5
x1 0.5175853  0.09386107 -0.71009530  0.4642922  0.05910103
x2 0.4516210  0.43816660 -0.11258435 -0.7683317  0.03224429
x3 0.4206036  0.47398415  0.62887267  0.4183725 -0.16707843
x4 0.3980188 -0.57412032  0.06907097 -0.1329413 -0.69965898
x5 0.4391100 -0.49489900  0.28781556 -0.0372845  0.69139676

Result! 주성분 계수에 의하면, 첫 번째 주성분 \(Y_1=0.518Z_{1}+0.452Z_{2}+0.421Z_{3}+0.398Z_{4}+0.439Z_{5}\)이며, 두 번째 주성분 \(Y_2=0.094Z_{1}+0.438Z_{2}+0.474Z_{3}-0.574Z_{4}-0.495Z_{5}\)이 된다. 여기서 확률변수 \(Z_{i}\)\((X_i-\mu_i)/\sigma_{i}\)이며, \(\mu_i\)\(\sigma_{i}\)는 각각 \(X_i\)의 평균과 표준편차를 의미한다.
주성분의 의미를 해석해보면, 첫 번째 주성분은 주성분 계수가 서로 비슷하여 전반적인 평점을 나타낸다고 할 수 있으며, 두 번째 주성분은 변수 \(x_1\), \(x_2\), \(x_3\)와 변수 \(x_4\), \(x_5\)의 부호가 반대이므로 국어, 영어, 제2외국어의 “인문계열”과 수학, 과학의 “이과계열”의 점수 차이를 나타낸다고 할 수 있다.


# 요약
summary(student.cor.prcomp)    
Importance of components:
                          PC1    PC2     PC3     PC4     PC5
Standard deviation     1.7852 1.2132 0.46622 0.33085 0.11955
Proportion of Variance 0.6374 0.2944 0.04347 0.02189 0.00286
Cumulative Proportion  0.6374 0.9318 0.97525 0.99714 1.00000

Result! 첫 2개의 고유값은 3.187, 1.472로서 각각 전체 변동의 63.7%(=3.187/5)와 29.4%(=1.472/5)를 차지한다. 따라서, 첫 2개의 주성분에 의해 데이터 변동의 약 93.2%가 설명될 수 있음을 알 수 있다. 이는 2개의 주성분으로 데이터 변동을 충분히 설명할 수 있음을 가리키며, 만약 첫 2개의 주성분을 취할 경우 이는 원래 다섯 개의 관찰변수들이 가지고 있는 정보를 2차원으로 축약한다는 의미를 가진다.


# 스크리 그래프래프
par(mfrow = c(1, 2))
screeplot(student.cor.prcomp, type = "b", main = "")  # 막대그래프screeplot(student.cor.prcomp, type = "l", main = "")  # 선 그래프

Result! 스트리 그래프를 보면 첫 번째 주성분과 두 번째 주성분의 분산(고유값)이 크며 가파른 경사를 형성한다. 그러므로, 주성분 개수는 2개로 선정할 수 있다.


# 주성분점수
student.cor.score <- student.cor.prcomp$x           
student.cor.score
             PC1         PC2         PC3         PC4         PC5
 [1,] -2.2470840  0.59291807  0.11734892  0.57000378  0.07050020
 [2,] -2.3648070 -0.56384142 -0.43800069  0.09637971 -0.01316672
 [3,]  0.6371219  1.45367994  0.36829470 -0.24073999 -0.01752385
 [4,]  0.4119368  1.24346894  0.04275167 -0.44523585 -0.01646831
 [5,] -0.9778549 -1.92149789 -0.49632909 -0.44545382 -0.01505308
 [6,] -1.7773223  1.14510117  0.12617138 -0.03003567 -0.10059295
 [7,]  1.4790506  0.68283716 -0.45563359 -0.05657281  0.17677268
 [8,]  0.4475007 -1.57666392  0.88207761 -0.01920990  0.16749550
 [9,]  1.3831919 -0.97790554  0.34768523  0.16519787 -0.22970590
[10,]  3.0082663 -0.07809652 -0.49436614  0.40566668 -0.02225757

Result! 첫 번째 주성분과 두 번째 주성분에 의해 얻어지는 \(i\)번째 개체의 주성분점수는 다음과 같다. \[ \begin{align} \begin{cases} y_{i1}=0.518z_{i1}+0.452z_{i2}+0.421z_{i3}+0.398z_{i4}+0.439z_{i5},\\ y_{i2}=0.094z_{i1}+0.438z_{i2}+0.474z_{i3}-0.574z_{i4}-0.495z_{i5}, \end{cases} \end{align} \] 여기서 \(z_{ij}=(x_{ij}-\bar{x}_{j})/s_{j}\)\(i\)번째 개체의 \(j\)번째 변수 관찰값 \(x_{ij}\)에서 \(j\)번째 변수의 평균값 \(\bar{x}_j\)을 뺀 후 \(j\)번째 변수의 표준편차 값 \(s_j\)로 나눈 것을 의미한다.


# 상관행렬을 입력으로 하는 주성분 분석NAcor.mat <- cor(student[,c("x1", "x2", "x3", "x4", "x5")])
cor.mat
          x1        x2        x3        x4        x5
x1 1.0000000 0.7838622 0.6833432 0.5592287 0.6102284
x2 0.7838622 1.0000000 0.8604151 0.2117815 0.3092596
x3 0.6833432 0.8604151 1.0000000 0.1380259 0.2793357
x4 0.5592287 0.2117815 0.1380259 1.0000000 0.9731614
x5 0.6102284 0.3092596 0.2793357 0.9731614 1.0000000
student.cor.princomp <- princomp(covmat = cor.mat)
student.cor.princomp
Call:
princomp(covmat = cor.mat)

Standard deviations:
   Comp.1    Comp.2    Comp.3    Comp.4    Comp.5 
1.7852209 1.2132058 0.4662250 0.3308475 0.1195505 

 5  variables and  NA observations.
summary(student.cor.princomp, 
        loadings = TRUE,      # 주성분 계수(단위 고유벡터) 출력 여부
        cutoff = 0)           # 고유벡터 값 등을 출력할 때 주어진 값보다 작은 값은 출력하지 않도록 지정NA
Importance of components:
                          Comp.1    Comp.2     Comp.3     Comp.4
Standard deviation     1.7852209 1.2132058 0.46622498 0.33084750
Proportion of Variance 0.6374027 0.2943736 0.04347315 0.02189201
Cumulative Proportion  0.6374027 0.9317764 0.97524952 0.99714153
                            Comp.5
Standard deviation     0.119550543
Proportion of Variance 0.002858466
Cumulative Proportion  1.000000000

Loadings:
   Comp.1 Comp.2 Comp.3 Comp.4 Comp.5
x1  0.518  0.094  0.710  0.464  0.059
x2  0.452  0.438  0.113 -0.768  0.032
x3  0.421  0.474 -0.629  0.418 -0.167
x4  0.398 -0.574 -0.069 -0.133 -0.700
x5  0.439 -0.495 -0.288 -0.037  0.691

Result! 결과는 “student.cor.prcomp”와 동일하다.

Reuse

Text and figures are licensed under Creative Commons Attribution CC BY 4.0. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".