brunch

빅분기 실기연습(4)

R프로그램_주성분 분석

by 첨물

먼저 주성분 분석이 뭘까?


어떤 반 아이들 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")

fee4d301-95d0-4c6a-92cb-e17f1febbdd5.png

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



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

17dcfd7a-5c4d-4d08-8670-75f0dd3c02a9.png


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

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

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


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


125c4ed8-082f-49c0-9333-272d15396da1.png

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


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


keyword
매거진의 이전글빅분기 실기연습(3)