今回のテーマは 多次元尺度構成法 (MultiDimensional Scaling),略してMDSです。
前回まではクラスタリングで「まとめていく」話をしていました。変数間の距離の近いものをひとまとめにする,というものでした。 数字が似ていると近い,という話でしたが,距離があるということは,空間的に離れているということ。この空間を再現するのがMDSです。
MDSは 距離から地図を作る技術 ,ととらえてください。 少し抽象的な言い方をすると,「相対的な関係から,背景にある空間関係を見出す」とも言えます。
サンプルデータで確かめてみましょう。まずはRの持っている距離データから。
data(eurodist)
eurodist
## Athens Barcelona Brussels Calais Cherbourg Cologne
## Barcelona 3313
## Brussels 2963 1318
## Calais 3175 1326 204
## Cherbourg 3339 1294 583 460
## Cologne 2762 1498 206 409 785
## Copenhagen 3276 2218 966 1136 1545 760
## Geneva 2610 803 677 747 853 1662
## Gibraltar 4485 1172 2256 2224 2047 2436
## Hamburg 2977 2018 597 714 1115 460
## Hook of Holland 3030 1490 172 330 731 269
## Lisbon 4532 1305 2084 2052 1827 2290
## Lyons 2753 645 690 739 789 714
## Madrid 3949 636 1558 1550 1347 1764
## Marseilles 2865 521 1011 1059 1101 1035
## Milan 2282 1014 925 1077 1209 911
## Munich 2179 1365 747 977 1160 583
## Paris 3000 1033 285 280 340 465
## Rome 817 1460 1511 1662 1794 1497
## Stockholm 3927 2868 1616 1786 2196 1403
## Vienna 1991 1802 1175 1381 1588 937
## Copenhagen Geneva Gibraltar Hamburg Hook of Holland Lisbon
## Barcelona
## Brussels
## Calais
## Cherbourg
## Cologne
## Copenhagen
## Geneva 1418
## Gibraltar 3196 1975
## Hamburg 460 1118 2897
## Hook of Holland 269 895 2428 550
## Lisbon 2971 1936 676 2671 2280
## Lyons 1458 158 1817 1159 863 1178
## Madrid 2498 1439 698 2198 1730 668
## Marseilles 1778 425 1693 1479 1183 1762
## Milan 1537 328 2185 1238 1098 2250
## Munich 1104 591 2565 805 851 2507
## Paris 1176 513 1971 877 457 1799
## Rome 2050 995 2631 1751 1683 2700
## Stockholm 650 2068 3886 949 1500 3231
## Vienna 1455 1019 2974 1155 1205 2937
## Lyons Madrid Marseilles Milan Munich Paris Rome Stockholm
## Barcelona
## Brussels
## Calais
## Cherbourg
## Cologne
## Copenhagen
## Geneva
## Gibraltar
## Hamburg
## Hook of Holland
## Lisbon
## Lyons
## Madrid 1281
## Marseilles 320 1157
## Milan 328 1724 618
## Munich 724 2010 1109 331
## Paris 471 1273 792 856 821
## Rome 1048 2097 1011 586 946 1476
## Stockholm 2108 3188 2428 2187 1754 1827 2707
## Vienna 1157 2409 1363 898 428 1249 1209 2105
この距離行列からMDSによって地図を作ります。MDSは大きく分けて二種類あって,計量MDS(メトリックMDS)と非計量MDS(ノンメトリックMDS)とよばれます。
非計量MDSは距離の大小関係を条件にする分析方法で,データが順序尺度水準であれば良いとされています。計量MDSは間隔尺度水準以上でなければなりません。前者が物理的な距等,厳密な距離関係に向いている,後者が心理的な距離等,厳密さを少し緩めた仮定をもったデータに向いている,ととらえておけばいいでしょう。
今回のデータは実測値なので,前者のMDSを使います。関数はcmdscaleです。
result.cmd <- cmdscale(eurodist,2)
plot(result.cmd,type="n")
text(result.cmd,rownames(result.cmd))
距離データから地図がかけたでしょうか。ピンとこない人は,次のサイトを参考に実際の距離を計算し,MDSしてみましょう。 次に示すのは一例です。
http://www.alles.or.jp/~halcyon/
chu_goku <- matrix(c( 0, 93.2,292.1,203.7,230.8,
93.2, 0,204.5,132.6,137.6,
291.2,204.5, 0,107.4, 98.5,
203.7,132.6,107.4, 0,120.6,
230.8,137.6, 98.5,120.6, 0),ncol=5)
colnames(chu_goku)<-c("Yamaguchi","Hiroshima","Tottori","Ssimane","Okayama")
result.cmd <- cmdscale(chu_goku,2)
plot(result.cmd,type="n")
text(result.cmd,colnames(chu_goku))
非計量なMDSはMASSパッケージのisoMDS関数を使います。
library(MASS)
コントの大会,KOCでの評価をデータセットにして作りました(Moodleで配布したKOC2016.csv参照)。
dat <- read.csv("KOC2016.csv")
# 4-8列目のデータを横に倒して距離行列を作る
dist(t(dat[4:8]))
## 設楽 日村 三村 大竹
## 日村 12.206556
## 三村 12.083046 9.949874
## 大竹 13.038405 9.110434 9.165151
## 松本 17.916473 14.422205 12.529964 12.206556
これを元に,MDSをしてみます。
KOC.dist <- dist(t(dat[4:8]))
result.iso <- isoMDS(KOC.dist,k=2)
## initial value 3.354092
## iter 5 value 0.037157
## iter 5 value 0.000000
## iter 5 value 0.000000
## final value 0.000000
## converged
result.iso
## $points
## [,1] [,2]
## 設楽 8.158060 4.145646
## 日村 2.228005 -4.276799
## 三村 1.261745 -0.166295
## 大竹 -1.517073 -3.190291
## 松本 -10.130738 3.487739
##
## $stress
## [1] 1.573116e-14
ここで,$points
とあるのは地図の座標です。 $stress
とあるのは適合度で,今回はとても小さな数字です(e-14は10の-14乗)から,当てはまりが良いと言えます。 普通ここの数字が0.1ぐらいであればよい(参考;https://www1.doshisha.ac.jp/~mjin/R/27/27.html) といいます。何次元あるかわからないときは,stressの値で判断するといいでしょう。
プロットします。
plot(result.iso$points,type="n")
text(result.iso$points,row.names(result.iso$points))
松本さんと設楽さんは評価が似ていないので,距離が遠くなって地図上も遠くなりました。重心にいるのが三村さんで,平均的な判断をしたと言えます。
ちなみにこの評価は,それぞれのネタに対しても当然計算できます。
KOC.dist <- dist((dat[4:8]))
result.iso2 <- isoMDS(KOC.dist,k=2)
## initial value 5.681832
## iter 5 value 3.064185
## final value 2.955881
## converged
result.iso2
## $points
## [,1] [,2]
## [1,] -2.591474 -3.2151996
## [2,] -13.331355 -1.3219487
## [3,] -1.671479 -0.1121383
## [4,] 4.050928 -1.1772914
## [5,] -8.117286 -4.6602890
## [6,] 8.336328 -3.1168835
## [7,] -6.001741 5.5651082
## [8,] -1.047049 1.4840079
## [9,] -7.639617 1.2747067
## [10,] 8.726201 -1.6935552
## [11,] -3.352796 0.7642731
## [12,] 1.066265 4.4695982
## [13,] 3.390341 -0.6426404
## [14,] 9.642331 -0.9598076
## [15,] 8.540403 3.3420597
##
## $stress
## [1] 2.955881
result.iso2 <- isoMDS(KOC.dist,k=3)
## initial value 3.069107
## iter 5 value 1.604949
## iter 10 value 1.355053
## iter 15 value 1.230978
## iter 20 value 1.164499
## final value 1.154477
## converged
result.iso2
## $points
## [,1] [,2] [,3]
## [1,] -2.754420 -3.58794756 -1.6474076
## [2,] -11.965179 -2.45297354 4.9805260
## [3,] -1.646526 -0.03193805 -0.4013751
## [4,] 4.408976 -1.19503205 -1.8073314
## [5,] -9.315448 -4.13111604 -1.7868069
## [6,] 7.711424 -2.91837595 2.8115902
## [7,] -6.322182 5.72974386 0.6604279
## [8,] -1.057645 1.34095170 1.0732267
## [9,] -7.510444 1.79983452 -3.0809487
## [10,] 8.573470 -1.13682388 2.0689492
## [11,] -3.722965 1.05751439 -1.2242810
## [12,] 1.176690 4.97013334 1.0383819
## [13,] 3.572762 -0.89902517 -1.4671551
## [14,] 9.952440 -1.78718190 0.3979760
## [15,] 8.899049 3.24223634 -1.6157723
##
## $stress
## [1] 1.154477
ストレス値をみてください。2の時は当てはまりが悪かったので,3にすると改善されましたね。今回は説明に3次元いるようです。
プロットは二次元で,三枚描くことにしましょう。
# dim1 and dim2
plot(result.iso2$points[,1:2],type="n")
text(result.iso2$points[,1:2],as.character(dat$actor))
# dim1 and dim3
plot(result.iso2$points[,1],result.iso2$points[,3],type="n")
text(result.iso2$points[,1],result.iso2$points[,3],as.character(dat$actor))
# dim2 and dim3
plot(result.iso2$points[,2],result.iso2$points[,3],type="n")
text(result.iso2$points[,2],result.iso2$points[,3],as.character(dat$actor))
このように,印象評定のデータから類似度を計算し,分析に用いることもできます。実際マーケティングなんかでは使われてたりします。
今回は扱いません。smacofパッケージを使うと簡単にできます。興味がある方にはご案内します。