昨日、こんなツイートを見た。
以前、県庁所在地と県庁所在地の間の距離が一番近いのどこか気になって、大津と京都が一番近いという無駄知識を得たんだけど、国土地理院さんが「都道府県庁間の距離」というなんのために作成されたのかまったくわからない図表を作成・公開していた。 pic.twitter.com/omv699HW3E
— 森川 真 (@mmww) 2019年11月14日
このデータは以前にも見たことがあって、多次元尺度法のよいサンプルになるかと思っていたのでした。今日はJuliaで古典的多次元尺度法をやってみる。
データは国土地理院の都道府県庁間の距離からダウンロードが可能。Excelファイルを持ってくる。このデータは人間が読むにはいいんだけど、ソフトで解析しようとすると下三角行列だけだったり県名が変なところに付いていたりしてめんどくさい。以下のように変換してCSVファイルに保存した。手っ取り早かったのでRでやった。
library(readxl) # Excelファイルの読み込み rawdat <- read_excel("000195511.xlsx") # Excelファイルには下三角行列にしかデータが入っていないので、対称な距離行列を作る D <- matrix(0, nrow=47, ncol=47) for (r in 1:46) { for (c in 1:r) { D[r+1, c] = as.numeric(rawdat[r+3, c+1]) D[c, r+1] = as.numeric(rawdat[r+3, c+1]) } } # 県名もとってくる prefnames <- rbind(as.matrix(rawdat[3,2]), as.matrix(rawdat[4:49,1])) for (n in 1: 47) { prefnames[n] <- gsub(" ", "", prefnames[n]) } rownames(D) <- prefnames colnames(D) <- prefnames # CSVファイルに保存 write.csv(D, file="prefecture_distance.csv")
Rでやるなら、この続きで
X <- cmdscale(D) plot(X, type="n", xlab="Dim. 1", ylab="Dim. 2", asp=1) text(X, label=rownames(X))
とすると下のような図ができる。簡単だなー。
ここからはJuliaで同じことをやってみる。まずは必要なパッケージの読み込み。多次元尺度法の関数はMultivariateStatsに入っている。
using CSV using MultivariateStats using Plots
先ほど作ったCSVファイルを読み込む。DataFrameの状態だと多次元尺度法の計算ができないので配列に変換している。
df = CSV.read("prefecture_distance.csv") pref_names = df[!, :Column1] pref_dist = df[:, 2:end] pref_dist = convert(Matrix, pref_dist)
ここから古典的多次元尺度法の計算。
res = transform(fit(MDS, pref_dist, maxoutdim=2, distances=true))
プロットしてみる。
scatter(res[1,:], res[2,:], legend=false, aspect_ratio=1)
日本語テキストがうまく入れられなかったので、ここまで。Rでやったのと(回転しているけど)同じ結果になっているので良しとする。