PCA example - R

500 days ago by jhlee2chn

Example From :   http://yatani.jp/teaching/doku.php?id=hcistats:PCA

사람들이 새 컴퓨터를 선택할 때 관심을 갖는 아래 사항에 관하여 척도가 7점인 4문항의 리커트(Likert) 설문 조사를 16명에게 실시하였다.

(1: 매우 그렇지 않다 – 7: 매우 그렇다)

    Price 가격이 저렴하다.

    Software 운영체제가 사용하려는 소프트웨어와 호환된다.

    Aesthetics 디자인이 매력적이다.

    Brand 유명 브랜드의 제품이다.

 

▪ 아래와 같이 설문조사를 통하여 얻은 데이터를 입력하여 데이터 행렬(data)을 생성한다. 

# 데이터 입력, R 코드 Price <- c(6, 7, 6, 5, 7, 6, 5, 6, 3, 1, 2, 5, 2, 3, 1, 2) Software <- c(5, 3, 4, 7, 7, 4, 7, 5, 5, 3, 6, 7, 4, 5, 6, 3) Aesthetics <- c(3, 2, 4, 1, 5, 2, 2, 4, 6, 7, 6, 7, 5, 6, 5, 7) Brand <- c(4, 2, 5, 3, 5, 3, 1, 4, 7, 5, 7, 6, 6, 5, 5, 7) data <- data.frame(Price, Software, Aesthetics, Brand) # 데이터가 잘 입력되었는지 확인한다. data 
       
   Price Software Aesthetics Brand
1      6        5          3     4
2      7        3          2     2
3      6        4          4     5
4      5        7          1     3
5      7        7          5     5
6      6        4          2     3
7      5        7          2     1
8      6        5          4     4
9      3        5          6     7
10     1        3          7     5
11     2        6          6     7
12     5        7          7     6
13     2        4          5     6
14     3        5          6     5
15     1        6          5     5
16     2        3          7     7
   Price Software Aesthetics Brand
1      6        5          3     4
2      7        3          2     2
3      6        4          4     5
4      5        7          1     3
5      7        7          5     5
6      6        4          2     3
7      5        7          2     1
8      6        5          4     4
9      3        5          6     7
10     1        3          7     5
11     2        6          6     7
12     5        7          7     6
13     2        4          5     6
14     3        5          6     5
15     1        6          5     5
16     2        3          7     7

▪ 데이터 행렬을 센터링 하여 mydata 행렬을 얻는다.

(본 예제에서는 센터링 한 후에 다시 각 열을 해당 확률변수의 표준편차로 나누었다.

이를 scaling이라 하는데, 필요에 따라 scaling도 진행할 수 있다.) 

# 표준화(centering, scaling) 작업 mydata <- scale(data, center = T, scale = T) # 데이터 행렬을 센터링, scaling 한다. mydata 
       
           Price    Software Aesthetics      Brand
 [1,]  0.8485483 -0.04217745      -0.75 -0.3865961
 [2,]  1.3167129 -1.39185589      -1.25 -1.5112392
 [3,]  0.8485483 -0.71701667      -0.25  0.1757255
 [4,]  0.3803837  1.30750098      -1.75 -0.9489176
 [5,]  1.3167129  1.30750098       0.25  0.1757255
 [6,]  0.8485483 -0.71701667      -1.25 -0.9489176
 [7,]  0.3803837  1.30750098      -1.25 -2.0735607
 [8,]  0.8485483 -0.04217745      -0.25 -0.3865961
 [9,] -0.5559454 -0.04217745       0.75  1.3003686
[10,] -1.4922746 -1.39185589       1.25  0.1757255
[11,] -1.0241100  0.63266177       0.75  1.3003686
[12,]  0.3803837  1.30750098       1.25  0.7380470
[13,] -1.0241100 -0.71701667       0.25  0.7380470
[14,] -0.5559454 -0.04217745       0.75  0.1757255
[15,] -1.4922746  0.63266177       0.25  0.1757255
[16,] -1.0241100 -1.39185589       1.25  1.3003686
attr(,"scaled:center")
     Price   Software Aesthetics      Brand 
    4.1875     5.0625     4.5000     4.6875 
attr(,"scaled:scale")
     Price   Software Aesthetics      Brand 
  2.136001   1.481834   2.000000   1.778342 
           Price    Software Aesthetics      Brand
 [1,]  0.8485483 -0.04217745      -0.75 -0.3865961
 [2,]  1.3167129 -1.39185589      -1.25 -1.5112392
 [3,]  0.8485483 -0.71701667      -0.25  0.1757255
 [4,]  0.3803837  1.30750098      -1.75 -0.9489176
 [5,]  1.3167129  1.30750098       0.25  0.1757255
 [6,]  0.8485483 -0.71701667      -1.25 -0.9489176
 [7,]  0.3803837  1.30750098      -1.25 -2.0735607
 [8,]  0.8485483 -0.04217745      -0.25 -0.3865961
 [9,] -0.5559454 -0.04217745       0.75  1.3003686
[10,] -1.4922746 -1.39185589       1.25  0.1757255
[11,] -1.0241100  0.63266177       0.75  1.3003686
[12,]  0.3803837  1.30750098       1.25  0.7380470
[13,] -1.0241100 -0.71701667       0.25  0.7380470
[14,] -0.5559454 -0.04217745       0.75  0.1757255
[15,] -1.4922746  0.63266177       0.25  0.1757255
[16,] -1.0241100 -1.39185589       1.25  1.3003686
attr(,"scaled:center")
     Price   Software Aesthetics      Brand 
    4.1875     5.0625     4.5000     4.6875 
attr(,"scaled:scale")
     Price   Software Aesthetics      Brand 
  2.136001   1.481834   2.000000   1.778342 

▪ mydata 행렬에 PCA를 진행한다. (R의 prcomp 명령어를 이용하였다.)

# PCA 진행. 앞에서 이미 센터링 scaling 하였음. retx는 PC score를 제공할지 여부 mypca <- prcomp(mydata, center = F, scale = F, retx = T) summary(mypca) 
       
Importance of components:
                          PC1    PC2    PC3     PC4
Standard deviation     1.5589 0.9804 0.6817 0.37926
Proportion of Variance 0.6076 0.2403 0.1162 0.03596
Cumulative Proportion  0.6076 0.8479 0.9640 1.00000
Importance of components:
                          PC1    PC2    PC3     PC4
Standard deviation     1.5589 0.9804 0.6817 0.37926
Proportion of Variance 0.6076 0.2403 0.1162 0.03596
Cumulative Proportion  0.6076 0.8479 0.9640 1.00000

▪ 주성분을 찾을 때 필요한 적재계수는 다음 명령어를 이용하여 확인할 수 있다. 이는 직교행렬 V에 해당한다.

# loadings (V를 의미한다.) mypca$rotation 
       
                  PC1        PC2        PC3         PC4
Price      -0.5229138 0.00807487 -0.8483525  0.08242604
Software   -0.1771390 0.97675554  0.1198660  0.01423081
Aesthetics  0.5965260 0.13369503 -0.2950727  0.73431229
Brand       0.5825287 0.16735905 -0.4229212 -0.67363855
                  PC1        PC2        PC3         PC4
Price      -0.5229138 0.00807487 -0.8483525  0.08242604
Software   -0.1771390 0.97675554  0.1198660  0.01423081
Aesthetics  0.5965260 0.13369503 -0.2950727  0.73431229
Brand       0.5825287 0.16735905 -0.4229212 -0.67363855

▪ 1~3번째 PC에서의 score는 다음 명령어를 이용하여 확인할 수 있다.

이는 행렬 Z=XV의 1~3번째 열벡터로 이루어진 행렬이다.

# PC1~PC3 score. 1열부터 3열까지 mypca$x[, 1:3] 
       
             PC1         PC2         PC3
 [1,] -1.1088441 -0.19931676 -0.34011951
 [2,] -2.0679730 -1.76890900 -0.27589687
 [3,] -0.3634723 -0.69751259 -0.80636384
 [4,] -2.0272096  0.88740412  0.75172002
 [5,] -0.6686402  1.35057412 -1.10839793
 [6,] -1.6151352 -1.01942683 -0.03565573
 [7,] -2.3840835  0.76603244  1.07981912
 [8,] -0.8105812 -0.13246925 -0.48765585
 [9,]  1.5030793  0.27221348 -0.30467593
[10,]  1.8749056 -1.17502483  0.65597978
[11,]  1.6283487  0.92758606  0.17338293
[12,]  0.7450737  1.57081802 -0.84695116
[13,]  1.2415980 -0.55167695  0.39695643
[14,]  0.8479424  0.08399428  0.17095950
[15,]  0.9197585  0.66873897  1.19372328
[16,]  2.2852328 -0.98302526 -0.21682424
             PC1         PC2         PC3
 [1,] -1.1088441 -0.19931676 -0.34011951
 [2,] -2.0679730 -1.76890900 -0.27589687
 [3,] -0.3634723 -0.69751259 -0.80636384
 [4,] -2.0272096  0.88740412  0.75172002
 [5,] -0.6686402  1.35057412 -1.10839793
 [6,] -1.6151352 -1.01942683 -0.03565573
 [7,] -2.3840835  0.76603244  1.07981912
 [8,] -0.8105812 -0.13246925 -0.48765585
 [9,]  1.5030793  0.27221348 -0.30467593
[10,]  1.8749056 -1.17502483  0.65597978
[11,]  1.6283487  0.92758606  0.17338293
[12,]  0.7450737  1.57081802 -0.84695116
[13,]  1.2415980 -0.55167695  0.39695643
[14,]  0.8479424  0.08399428  0.17095950
[15,]  0.9197585  0.66873897  1.19372328
[16,]  2.2852328 -0.98302526 -0.21682424

앞서 PC1, PC2가 원 데이터의 84.8% 정도를 보존한다고 이해할 수 있으므로, 15% 정도의 정보는 잃어버리더라도, PC1, PC2만 택하여 2차원 데이터로 차원을 줄 일 수 있다.

이를 활용하여 데이터를 시각화하거나 다른 데이터 분석기법을 적용할 수 있다. 예를 들어, 다음과 같이 주어진 데이터를 개의 클러스터로 묶는 알고리즘인 K-means clustering을 진행할 수 있다.

# 2차원으로 차원 축소 후(PC1과 PC2만 취하여) k-means clustering 진행 PC1 = mypca$x[, 1] # 1열을 PC1라 함 PC2 = mypca$x[, 2] # 2열을 PC2라 함 # PC1, PC2를 이용하여 클러스터의 개수(centers)를 4개로 하고 # 임의로 10번 시행(nstart)하여 가장 잘 clustering 하는 것을 찾음 myclust <- kmeans(mypca$x[, 1:2], centers = 4, nstart = 10) # clustering 후 시각화 결과 보여줌 plot(PC1, PC2, xlab = "PC 1", ylab = "PC 2", type="p", col = myclust$cluster) dev.off() 
       
null device 
          1 
null device 
          1 

그리고 주성분의 고윳값에 대한 선 그림(line plot)인 scree plot을 활용하여 데이터의 차원을 줄일 때, 주성분을 몇 개로 선택할지 결정할 수 있다(아래 오른쪽 그림 참조).

scree plot은 고윳값을 가장 큰 값에서부터 크기 순서대로 정렬하므로, 대개 기울기가 꺾이는 부분의 “elbow point” 왼쪽에 있는 성분까지 선택한다.

# scree 그래프 (분산을 나타낸다) screeplot(mypca, type = "lines", col = 2) dev.off() 
       
null device 
          1 
null device 
          1