brunch

You can make anything
by writing

C.S.Lewis

by 첨물 May 09. 2021

빅분기 실기연습(4)

R프로그램_주성분 분석

먼저 주성분 분석이 뭘까?


어떤 반 아이들 16명이 국어, 영어, 수학, 과학 시험을 보았다.

그리고 나서 16명을 문과에 강한 학생들과 이과에 강한 학생들로 구별하고 싶다고 하자

그러면 네 개 과목을 문과, 이과 두 개의 축으로 된 좌표 평면에 16명의 학생들을 점으로 나타낼 수 있지 않을까? 2차원 평면에 4차원을 표시하기 어려우니 차원을 축소해서 2차원으로 표시... 

그러면 어떻게 차원을 축소할 수 있을까가 이번에 실습할 예제이다.


먼저 16명의 학생들의 네 개 과목 점수를 데이터로 넣기


x1 <- c(26, 46, 57, 36, 57, 26, 58, 37, 36, 56, 78, 95, 88, 90, 52, 56) #국어

x2 <- c(35, 74, 73, 73, 62, 22, 67, 34, 22, 42, 65, 88, 90, 85, 46, 66) #영어

x3 <- c(35, 76, 38, 69, 25, 25, 87, 79, 36, 26, 22, 36, 58, 36, 25, 44) #수학

x4 <- c(45, 89, 54, 55, 33, 45, 67, 89, 47, 36, 40, 56, 68, 45, 37, 56) #과학

score <- cbind(x1, x2, x3, x4) #데이터 합치기

colnames(score)=c("국어", "영어", "수학", "과학")

rownames(score)=1:16

head(score)


> head(score)

  국어 영어 수학 과학

1   26   35   35   45

2   46   74   76   89

3   57   73   38   54

4   36   73   69   55

5   57   62   25   33


6   26   22   25   45


그러면 위와 같이 1~16번 학생의 점수가 score 변수에 들어가게 된다.


그리고 나서 주성분 분석을 해 보자. (procomp 함수)


result = prcomp(score) #주성분 분석 실시

summary(result)


> summary(result)

Importance of components:

                           PC1     PC2     PC3     PC4

Standard deviation     30.1227 27.0528 9.07614 6.15239

Proportion of Variance  0.5157  0.4159 0.04682 0.02151


Cumulative Proportion   0.5157  0.9317 0.97849 1.00000


result 값은 아래와 같이 총 네 개의 값으로 이루져있다. 

sdev : 표준편차

rotation : 주성분 변환 계수

center : 국어, 영어, 수학, 과학 평균

scale : 표준화 여부

x : 1~16 번의 학생의 네 개 과목을 변환한 변수 PC1~PC4로 다시 표현함




head(result)


> head(result)

$sdev

[1] 30.122748 27.052808  9.076140  6.152386


$rotation

           PC1         PC2        PC3        PC4

국어 0.6093268 -0.39286407 -0.6126773 -0.3146508

영어 0.7185749 -0.09337973  0.6200124  0.3008572

수학 0.2624323  0.73573272  0.1052861 -0.6154198

과학 0.2085672  0.54372366 -0.4786711  0.6570680


$center

   국어    영어    수학    과학 

55.8750 59.0000 44.8125 53.8750 


$scale


[1] FALSE


$x

          PC1         PC2         PC3         PC4

1  -39.875586   1.9330027   6.6385247   2.3869499

2   20.272050  44.5227945   1.8206643  11.5061432

3    8.983792  -6.6935019   7.2138153   8.1326987

4    4.531898  24.9080814  22.8652385  -3.6805786

5   -6.712062 -26.6490472   9.0770519  -0.9747007

6  -51.841383  -4.2103881  -2.4744972   4.6300044

7   20.852225  36.5932231   1.8173605 -15.6007799

8  -13.167590  54.0009583 -17.1498753   0.4574549

9  -42.444225   1.0414784  -8.4004654  -3.9719854

10 -20.804753 -22.0216849  -4.0412448  -5.3214089

11   8.912199 -33.5804643  -5.5956910  -0.2340615

12  42.809104 -23.4070505  -7.9356529   3.2338001

13  48.257282   1.8670423  -5.8346446   0.3836511

14  35.312506 -27.1435512  -1.4669216  -3.3232651

15 -20.421626 -21.0157566   0.3055568  -1.5868892

16   5.336169  -0.1451361   3.1607808   3.9629668




왜 이런 작업을 하는지 다시 한번 생각해보면, 앞에서 얘기한 것처럼 1번 학생을 4개의 변수가 아닌 2개의 변수로 표현하고 싶은 것이다. 

PC1과 PC2 만으로 전체를 표현할 수 있을지 보는 것이 누적 비율

아래 값을 보면 PC1 이 51%, PC1과 PC2가 93%를 설명할 수 있다고 나와있다.


Cumulative Proportion   0.5157  0.9317 0.97849 1.00000


이걸 파레토 차트처럼 그래프로 표현한 것이 scree plot이다.


screeplot(result, type="lines", pch=1, main="scree plot")

물론 그냥 plot으로도 표현할 수 있다.



plot(result, xlab="Principal Component", main="Varriance by Prin.Comp.")


그럼 정말 PC1과 PC2 두 개의 축으로 1~16번의 학생을 표시해보자.

가로축을 PC1/PC2,  세로축을 PC2/PC1

가로축이 높으면 문과 쪽, 세로 쪽이 높으면 이과 쪽을 표현함.


biplot(result, main = "Prin. Compo. 1/ Prin. Compo.2")


그렇다면 국어와 영어, 수학과 과학이라는 변수는 서로서로 상관관계가 있지 않을까? 이것이 공분산 분석이다.


cc <- cor(score) #상관계수 구하기

cc


> cc

           국어      영어       수학       과학

국어  1.0000000 0.7830829 -0.1344493 -0.0657303

영어  0.7830829 1.0000000  0.2424654  0.2124899

수학 -0.1344493 0.2424654  1.0000000  0.8696483


과학 -0.0657303 0.2124899  0.8696483  1.0000000


역시 예상했던 대로 국어와 영어, 수학과 과학점수는 강한 상관관계를 보였다. 이를 통해 국어+영어, 수학+과학이라는 PC1, PC2의 주성분 2개로 차원 축소를 하여 분석하는 법을 공부해보았다.



코드 정리


x1 <- c(26, 46, 57, 36, 57, 26, 58, 37, 36, 56, 78, 95, 88, 90, 52, 56) #국어

x2 <- c(35, 74, 73, 73, 62, 22, 67, 34, 22, 42, 65, 88, 90, 85, 46, 66) #영어

x3 <- c(35, 76, 38, 69, 25, 25, 87, 79, 36, 26, 22, 36, 58, 36, 25, 44) #수학

x4 <- c(45, 89, 54, 55, 33, 45, 67, 89, 47, 36, 40, 56, 68, 45, 37, 56) #과학

score <- cbind(x1, x2, x3, x4) #데이터 합치기

colnames(score)=c("국어", "영어", "수학", "과학")

rownames(score)=1:16

head(score)

result = prcomp(score) #주성분 분석 실시

result

summary(result)

head(result)

plot(result, xlab="Principal Component", main="Varriance by Prin.Comp.")

screeplot(result, type="lines", pch=1, main="scree plot")

result$x[,1:2] 

biplot(result, main = "Prin. Compo. 1/ Prin. Compo.2")

cc <- cor(score) #상관계수 구하기

cc


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari