안녕하세요~ 오늘은 다차원척도법을 알아 보겠습니다.
다차원척도법은 여러 대상 간의 관계에 관한 수치적 자료를 이용해 유사성에 대한 측정치를 상대적 거리로 구조화하는 방법입니다.
따라서 다차원척도법은 2차원 혹은 3차원에서의 특정 위치에 관측치를 배치게 눈에 보기 쉽게 척도화 하는 거죠~
한번 알아볼까요???
1. 전통적 다차원척도법(Classical MDS)은 Numeric data로만 이루어진다.
cmdscale 함수를 사용한다 (stats 패키지)
2. 비계량적 다차원척도법(nonmetric MDS)은 투입변수로 numeric이 아닌 data를 포함한다.
isoMDS함수를 사용한다 (MASS 패키지)
##----R분석 사례----##
(1) 전통적 다차원 척도법 (Classical MDS)
#전통적 다차원 척도법을 실습하기 위해서 watervoles(영국 14개 지역의 물쥐의 13개 특성 발현 비율 data)를 사용하겠습니다.
install.packages("HSAUR")
data(watervoles, package="HSAUR")
#데이터를 한번 확인해보죠.
head(watervoles,5)
Surrey Shropshire Yorkshire Perthshire Aberdeen Elean Gamhna Alps
Surrey 0.000 0.099 0.033 0.183 0.148 0.198 0.462
Shropshire 0.099 0.000 0.022 0.114 0.224 0.039 0.266
Yorkshire 0.033 0.022 0.000 0.042 0.059 0.053 0.322
Perthshire 0.183 0.114 0.042 0.000 0.068 0.085 0.435
Aberdeen 0.148 0.224 0.059 0.068 0.000 0.051 0.268
Yugoslavia Germany Norway Pyrenees I Pyrenees II North Spain
Surrey 0.628 0.113 0.173 0.434 0.762 0.530
Shropshire 0.442 0.070 0.119 0.419 0.633 0.389
Yorkshire 0.444 0.046 0.162 0.339 0.781 0.482
Perthshire 0.406 0.047 0.331 0.505 0.700 0.579
Aberdeen 0.240 0.034 0.177 0.469 0.758 0.597
South Spain
Surrey 0.586
Shropshire 0.435
Yorkshire 0.550
Perthshire 0.530
Aberdeen 0.552
# cmdscale 함수 적용. cmdscale 함수는 Matrix데이터 상의 데이터들의 값을 거리로 생각하고, 2차원상으로 나타내주는 역할을 합니다.
voles_mds<-cmdscale(watervoles)
voles_mds
[,1] [,2]
Surrey -0.240788133 0.233677162
Shropshire -0.113656033 0.116786026
Yorkshire -0.239359809 0.076003132
Perthshire -0.212934123 0.060479017
Aberdeen -0.249489548 -0.069331766
Elean Gamhna -0.148728549 -0.077835691
Alps 0.051393974 -0.162305986
Yugoslavia -0.011536211 -0.344631490
Germany 0.003932616 0.005908733
Norway -0.038569294 -0.008874157
Pyrenees I 0.042115821 -0.056555465
Pyrenees II 0.515830349 0.029097752
North Spain 0.318027269 0.150096450
South Spain 0.323761671 0.047486283
#이제 cmdscale 함수의 eigenvalue를 생성해주는 옵션을 적용합니다. 따라서.. eigenvalue가 참 뭐랄까..
저한테는 이해하기 어려운 의미랄까?.
#그런 건데요~ 일종의 고유값을 생성해주는 겁니다. 얼만큼 거리를 이동할지 이런 것들이겠죠.
vole_mds<-cmdscale(watervoles, eig=TRUE)
> vole_mds
$points
[,1] [,2]
Surrey -0.240788133 0.233677162
Shropshire -0.113656033 0.116786026
Yorkshire -0.239359809 0.076003132
Perthshire -0.212934123 0.060479017
Aberdeen -0.249489548 -0.069331766
Elean Gamhna -0.148728549 -0.077835691
Alps 0.051393974 -0.162305986
Yugoslavia -0.011536211 -0.344631490
Germany 0.003932616 0.005908733
Norway -0.038569294 -0.008874157
Pyrenees I 0.042115821 -0.056555465
Pyrenees II 0.515830349 0.029097752
North Spain 0.318027269 0.150096450
South Spain 0.323761671 0.047486283
$eig
[1] 7.359910e-01 2.626003e-01 1.492622e-01 6.990457e-02 2.956972e-02
[6] 1.931184e-02 1.249001e-16 -1.139451e-02 -1.279569e-02 -2.849924e-02
[11] -4.251502e-02 -5.255450e-02 -7.406143e-02 -1.097833e-01
$x
NULL
$ac
[1] 0
$GOF
[1] 0.6248056 0.7883784
# Eigenvalue가 생성되었죠? 이제 시각화를 해보겠습니다.
# 책에 있는 내용으로치면 오류가 나서, 제가 계속 뒤적이면서 만들어본 결과 성공했습니다.
plot(voles_mds, type="n", xlab="Dim1", ylab="Dim2", main = "cmdscale(watervoles)")
segments(-1, -0, 1, 0, lty="dotted")
segments(0, -1, 0, 1, lty="dotted")
text(voles_mds, rownames(voles_mds), cex=0.8, col="red")
#voles_mds를 플랏을 찍는데 , "n"은 찍지 않는다입니다 아무것도 표시가 남지 않죠. 그리고, x축이름을 Dim1, y축이름을 Dim2라고 짓구요,
#main이름을 cmdscale(watervoles)라고 지은겁니다.
#segments는 나눠주는 역할을 하는데요~ 좌표점선을 이어주고, dotted는 점선으로 표시한다는 의미입니다.
#text는 이제 저렇게 이름을 띄워주는 역할을 하는데요~ voles_mds의 데이터로 행의 이름들을 빨간색으로 나타내준 겁니다!
#자 그럼 이제 두 번째 사례로 넘어가볼까요!?
#친족 : 15가지 친족(colnames)에 대해 6개의 그룹(sourceid)이 각각이 정한 기준에 의해 분류한 결과데이터를 사용할 것입니다.
#책에는 이렇게 써있지만 이해가 안되는군요 그럼 데이터를 직접 살펴보져~ 데이터도 보면 실행이 안되는게 많아서, 또 고쳤네요 ㅠㅠ.;
library(foreign)
kinship.1 <- read.spss("http://www.unt.edu/rss/class/Jon/R_SC/Module9/MDS/kinship_dat.sav", to.data.frame=T)
kinship.1
#데이터를 보니까 aunt.brother.cousin등 15가지의 친족이 variable로 나타나있군요.
#sourceid (source identification?) 이게 6개의 그룹으로 나누어져 있군요.
#그 중에서 저희는 sourceid가 1인 행만 사용하겠습니다.
kinship.2<-kinship.1[1:15, 1:15]
kinship.2
aunt brother cousin daughter father gdaugh gfather gmother gson mother
1 0 0 0 0 0 0 0 0 0 0
2 83 0 0 0 0 0 0 0 0 0
3 38 77 0 0 0 0 0 0 0 0
4 79 61 83 0 0 0 0 0 0 0
5 79 55 84 43 0 0 0 0 0 0
6 79 82 82 69 83 0 0 0 0 0
7 84 76 84 83 73 48 0 0 0 0
8 78 83 84 74 82 38 11 0 0 0
9 85 73 81 80 74 13 38 48 0 0
10 72 63 84 34 13 84 82 73 83 0
11 49 74 53 81 77 80 78 84 73 83
12 42 83 53 74 85 72 85 79 79 79
13 77 10 78 52 63 73 83 76 82 55
14 85 52 82 14 34 80 74 83 69 43
15 10 77 39 85 72 85 78 84 79 79
nephew niece sister son uncle
1 0 0 0 0 0
2 0 0 0 0 0
3 0 0 0 0 0
4 0 0 0 0 0
5 0 0 0 0 0
6 0 0 0 0 0
7 0 0 0 0 0
8 0 0 0 0 0
9 0 0 0 0 0
10 0 0 0 0 0
11 0 0 0 0 0
12 12 0 0 0 0
13 81 76 0 0 0
14 74 81 61 0 0
15 42 49 83 79 0
#요렇게 되었죠. 이제 다차원척도화하기위해서 거리형태로 나타내야하기때문에 distance matrix형태로 변환해야합니다.
kin.dist<-dist(kinship.2)
1 2 3 4 5 6 7
2 83.00000
3 85.86617 89.18520
4 129.81140 103.08249 93.94679
5 134.79985 109.29776 105.21407 43.42810
6 177.02825 158.47397 141.70392 109.96363 91.09336
7 185.49933 165.39347 153.93180 121.54423 98.48350 51.62364
8 183.83144 166.53828 149.85660 119.37755 100.17485 39.96248 21.63331
9 186.83683 166.39411 156.77691 126.40016 105.50355 65.09224 70.72482
10 208.64324 196.13516 189.02645 165.45996 162.36071 180.38015 162.94784
11 234.38003 231.70887 217.22569 214.98139 203.35437 183.69268 169.09169
12 235.45488 235.27856 216.42089 216.17123 206.33953 183.07376 172.24111
13 242.62316 230.15864 242.58401 222.22286 214.93022 214.41315 202.18309
14 243.18306 227.85302 228.12935 206.40494 207.79557 217.93348 206.44612
15 264.76593 274.46311 254.66841 263.63611 253.69273 239.06903 227.58075
8 9 10 11 12 13 14
2
3
4
5
6
7
8
9 62.57795
10 161.77763 143.54790
11 165.78299 147.28883 122.71104
12 166.62833 148.88586 125.03999 24.02082
13 201.20139 182.87154 145.56098 141.00355 138.86324
14 204.71444 189.14545 138.26786 162.32683 159.92186 91.73876
15 224.58183 212.81682 189.30663 138.34377 134.98148 166.93412 157.46428
#이렇게 거리형태로 변환되었습니다.
#이제 cmdscale을 적용합니다.
mds2<-cmdscale(kin.dist)
mds2
[,1] [,2]
1 -97.80831 -85.075706
2 -101.87481 -66.945503
3 -94.36266 -45.877589
4 -89.20892 -10.308259
5 -81.10522 9.223326
6 -55.28806 72.413885
7 -36.65867 74.393169
8 -34.91551 74.768978
9 -15.32028 63.421025
10 52.05353 -13.482851
11 99.52892 23.504895
12 102.23585 22.731125
13 109.91109 -38.743797
14 100.49770 -56.351359
15 142.31537 -23.671339
#요렇게 디스턴스 매트릭스가 되었죠.
#3차원 결과 도출 option을 적용해봅니다.
mds3<-cmdscale(kin.dist, k=3)
mds3
[,1] [,2] [,3]
1 -97.80831 -85.075706 47.1807477
2 -101.87481 -66.945503 0.4102747
3 -94.36266 -45.877589 38.2830477
4 -89.20892 -10.308259 -31.9847857
5 -81.10522 9.223326 -25.1540513
6 -55.28806 72.413885 -1.5747893
7 -36.65867 74.393169 -7.3687134
8 -34.91551 74.768978 -3.1528163
9 -15.32028 63.421025 -8.0731192
10 52.05353 -13.482851 -29.5897200
11 99.52892 23.504895 42.4181065
12 102.23585 22.731125 43.1990617
13 109.91109 -38.743797 -59.4977184
14 100.49770 -56.351359 -70.5707395
15 142.31537 -23.671339 65.4752149
#이렇게 3차원도 되지요.
#이제 2차원 결과를 먼저 시각화해봅니다.
#요번 부분에서 제가 아까 고쳤다는 부분이 이해가 되네요. 생략해버렸군요 책이..ㅠㅠ
Dim1<-mds2[,1]
Dim2<-mds2[,2]
plot(Dim1, Dim2, type="n", xlab="", ylab="", main="cmdscale(kin.dist)")
segments(-1500, -0, 1500, 0, lty="dotted")
segments(0, -1500, 0, 1500, lty="dotted")
text(Dim1, Dim2, colnames(kinship.2), cex=0.8, col="blue")
#요렇게 보니까 2차원상에서 15개의 친족들이 다 거리상으로 표시되었죠. 엄마는 가까운데 아빠는 머네요 생각보다 ㅋㅋ(아빠들 슬픔)
#3차원결과 시각화를 해보겠습니다.
install.packages("scatterplot3d")
library(scatterplot3d)
scatterplot3d(mds3, color="dark blue", pch=1, main="Mulitmensional Scaling 3-D Plot", sub="Three Dimensional Solution", grid=TRUE, box=TRUE)
#요렇게 3차원으로 나타낼 수도 있습니다. 이름을 뜨게 하고 싶은데 이 방법은 잘 모르겠네요 Discription을 찾아보았는데도;;ㅠㅠ
#3차원으로 늘여서 이름을 어떻게 지정해줘야할지..ㅠ0ㅠ
##----------##
(2) 비계량적 다차원척도법(nonmetric MDS)
# 이번에는 비계량적 다차원척도법을 해볼건데요~
# swiss ( 1888년 스위스 47개 불어권 도시에서의 demographic 정보. 출산율 저하에 따라 Data를 수집하였다고 합니다.) data를 이용합니다.
library(MASS)
data(swiss)
summary(swiss)
Fertility Agriculture Examination Education
Min. :35.00 Min. : 1.20 Min. : 3.00 Min. : 1.00
1st Qu.:64.70 1st Qu.:35.90 1st Qu.:12.00 1st Qu.: 6.00
Median :70.40 Median :54.10 Median :16.00 Median : 8.00
Mean :70.14 Mean :50.66 Mean :16.49 Mean :10.98
3rd Qu.:78.45 3rd Qu.:67.65 3rd Qu.:22.00 3rd Qu.:12.00
Max. :92.50 Max. :89.70 Max. :37.00 Max. :53.00
Catholic Infant.Mortality
Min. : 2.150 Min. :10.80
1st Qu.: 5.195 1st Qu.:18.15
Median : 15.140 Median :20.00
Mean : 41.144 Mean :19.94
3rd Qu.: 93.125 3rd Qu.:21.70
Max. :100.000 Max. :26.60
# 생식력, 유아 사망률, 교육수준, 농업, 카톨릭, 조사? 등등이 variable로 나타나있네요.
# 도시별로 조사한 결과인것 같습니다. 음..그럼 examination이 조사한 수? 이런 것을 나타내려나요~
# distance matrix형태로 나타내야겠죠~
swiss.dist<-dist(swiss)
swiss.mds<-isoMDS(swiss.dist)
initial value 5.463800
iter 5 value 4.499103
iter 5 value 4.495335
iter 5 value 4.492669
final value 4.492669
converged
#그 결과, 시작 값은 5.46부터 시작해서 iteration하여 4.492669로 수렴하였군요
swiss.mds
$points
[,1] [,2]
Courtelary 38.850496 -16.1546743
Delemont -42.676573 -13.7209890
Franches-Mnt -53.587659 -21.3357627
Moutier 6.735536 -4.6041161
Neuveville 35.622307 4.6339724
Porrentruy -44.739479 -25.4957015
Broye -55.301247 2.9985892
Glane -61.510950 -0.5029742
Gruyere -56.196434 -11.5873817
Sarine -47.880261 -18.4937959
Veveyse -60.573600 -3.3177231
Aigle 28.500730 18.4040743
Aubonne 31.622253 26.0543764
Avenches 31.955939 19.3455733
Cossonay 32.951993 27.2866822
Echallens 11.653211 24.5294932
Grandson 39.623322 -0.1906417
Lausanne 40.455512 -24.2790922
La Vallee 51.099610 -23.2691859
Lavaux 30.753053 29.7236322
Morges 32.051544 18.1638440
Moudon 33.349605 17.2202105
Nyone 26.363999 7.9625625
Orbe 35.822440 15.4595563
Oron 29.301157 31.3756933
Payerne 30.448866 19.5104430
Paysd'enhaut 30.389346 26.4350474
Rolle 29.595391 18.6942289
Vevey 30.316991 -16.0544171
Yverdon 33.168755 11.4999792
Conthey -67.045836 16.9000059
Entremont -66.130908 14.2235838
Herens -67.831773 19.3460319
Martigwy -63.493801 8.8769860
Monthey -59.675844 -1.3044352
St Maurice -63.678801 7.2356724
Sierre -69.462428 17.6354948
Sion -57.385309 -4.8572223
Boudry 37.667244 0.0118818
La Chauxdfnd 40.842274 -29.0069374
Le Locle 38.285582 -17.6212453
Neuchatel 35.745340 -30.5746402
Val de Ruz 37.226824 2.1006842
ValdeTravers 41.086622 -15.3626392
V. De Geneve 24.329270 -73.1278621
Rive Droite -4.756696 -17.5026420
Rive Gauche -3.887613 -37.2642199
$stress
[1] 4.492669
# 이렇게 변환되었습니다. 참 이걸 거리형태로 만드는 것 자체가. 참 대단하죠? 엄청난 수식이 들어가있을 것만 같은 느낌입니다.
# 이제 시각화해보겠습니다.
# 시각화1
plot(swiss.mds$points, type="n")
text(swiss.mds$points, labels = as.character(1:nrow(swiss)))
#시각화2(segment와 text포함)
plot(swiss.mds$points, type="n")
segments(-75, -0, 55, 0 lty="dotted")
segments(0, -75, 0, 35, lty="dotted")
text(swiss.mds$points, labels = row.names(swiss), col="red")
# 요렇게 전통적 다차원척도법과 비계량적 다차원척도법을 시각화해보는 것까지 한 번 해봤는데요~ 조~금 까다롭죠 ㅠㅠ
# 신기하지 않나요? 그래도..ㅎㅎ; 무튼 다음 시간에는 주성분분석(Principal Component Analysis, PCA)을 알아보도록 하겠습니다.
'## 오래된 게시글 (미관리) ## > R' 카테고리의 다른 글
20. 데이터 마트 - 1 (2) | 2018.11.21 |
---|---|
19. 주성분 분석(Principal Component Analysis, PCA) (5) | 2018.11.21 |
17. 시계열 분석-2 (0) | 2018.11.21 |
16. 시계열분석의 개념과 간단한 분석 (1) | 2018.11.21 |
15. R을 통한 회귀분석 실습 (0) | 2018.11.20 |