r入門とgoogle map +α

26

Upload: kobexr

Post on 07-Jul-2015

1.448 views

Category:

Technology


5 download

DESCRIPTION

Kobe.R #1 R入門 GoogleMap 巡回セールスマン問題

TRANSCRIPT

Page 1: R入門とgoogle map +α
Page 2: R入門とgoogle map +α

R とGoogleMap

• 鯖江市のデータを取得して Webブラウザ上にマッピングする

Page 3: R入門とgoogle map +α

R は 便利な解析ツール

統計分析

• オープン & フリー

• グラフィックス

• 充実した解析環境

Page 4: R入門とgoogle map +α

RStudio で 更に便利に

R用のIDE

統計分析

Page 5: R入門とgoogle map +α

R の 基本操作 (変数の代入)

• a <- 1 #aに1を代入

•b <- c(1:3) #bにベクトル(1,2,3)を代入

•c <- c(‘x’, ‘y’, ‘z’)

• d <- data.frame(d1=b, d2=c)

Page 6: R入門とgoogle map +α

R の 基本操作 (データフレーム)

• d <- data.frame(d1=b, d2=c) 要素ラベルで操作できる

•要素ラベルは「$」で表す d$d1[2] = d[2, 1] = 2

Page 7: R入門とgoogle map +α

R の 基本操作 (データの確認・準備)

• str(), head(), summary()でデータ確認

str(d$d1)

• as.XXXで型を変更 as.integer, as.character…

d$d1 <- as.character(d$d1)

• names()で要素の名前取得/命名 names(d) names(d) <- c(“名前1”, “名前2”)

Page 8: R入門とgoogle map +α

R の 基本操作 (パッケージの利用)

•Rの機能を拡張するためのパッケージ

• install.packages() … インストール • library() or require() … 呼び出し

• XML … XMLファイル操作 • googleVis … Google Visualization API

Page 9: R入門とgoogle map +α

R の 基本操作 (その他便利な機能紹介)

• データの取得

txtデータ: read.table csvデータ: read.csv(csvファイル) Excelデータ: xlsxパッケージ、xlsx(xlsファイル) Webデータ: readLines(URL) RCurlパッケージのgetURL

•可視化ツール

ggplot2: いろいろなプロット ggmap: マッピング

Page 10: R入門とgoogle map +α

R とGoogleMap

• 鯖江市のAED設置場所をマッピング

Page 11: R入門とgoogle map +α

install.packages('XML'); library(XML) #XML package

install.packages('googleVis'); library(googleVis) #googleVis package

int <- "integer"; num <- "numeric"; chr <- "character" #データ型の略記

url <- "http://www3.city.sabae.fukui.jp/xml/aed/aed.xml" #鯖江市URL

data <- xmlToDataFrame(url, stringsAsFactors=F,

colClasses=c(int, chr, chr, int, num, num, chr)) #型指定でデータ取得

data$latlong <- paste(data$latitude, data$longitude, sep=":") #データ加工

plot(gvisMap(data, locationvar="latlong", tipvar="name")) #表示

R とGoogleMap (コード)

• データ取得から可視化まで、これだけ

Page 12: R入門とgoogle map +α

R とGoogleMap (内容)

• 鯖江市HPからデータを取得 •データを確認、加工 • マッピングしてWebブラウザで表示

Page 13: R入門とgoogle map +α

R とGoogleMap (データを取得)

• XMLデータを取得する

#XMLパッケージの導入 #この中の関数xmlToDataFrameを利用する install.packages(‘XML’) library(XML)

#関数xmlToDataFrameを使ってXMLデータを取得 #この関数についてのヘルプを見るには、?xmlToDataFrame int <- "integer“; num <- "numeric“; chr <- "character“ url <- "http://www3.city.sabae.fukui.jp/xml/aed/aed.xml" data <- xmlToDataFrame(url, stringsAsFactors=F, colClasses=c(int, chr, chr, int, num, num, chr))

Page 14: R入門とgoogle map +α

R とGoogleMap (データの確認)

•データの中身を(簡単に)確認する

#str関数でデータフレームの構造を確認 str(data)

'data.frame': 134 obs. of 7 variables: $ no : int 1 115 116 117 118 119 120 121 122 123 ... $ name : chr "鯖江高等学校 " "鯖江市嚮陽会館" "鯖江市役所" "JAたんなん ふれあいセンター " ... $ address : chr "鯖江市舟津町2丁目5-42 " "鯖江市桜町2丁目7番1号" "鯖江市西山町13番1号"... $ count : int 1 1 1 1 1 1 1 1 1 1 ... $ latitude : num 35.9 35.9 36 36 36 ... $ longitude: num 136 136 136 136 136 ... $ url : chr "http://www3.city.sabae.fukui.jp/xml/aed/#1" "http://www3.city.sabae.fukui.jp/xml/aed/#115” ...

latitude … 緯度

longitude … 経度

Page 15: R入門とgoogle map +α

R とGoogleMap (データを加工)

• データをマッピング用に加工する

#googleVisパッケージの導入 #この中の関数gvisMapを利用する Install.packages(‘googleVis’) library(googleVis)

#gvisMap関数で座標を指定するには、「緯度:経度」の形式が必要 #dataに緯度:経度を要素とする項目latlongを追加する #「データフレーム$項目名」<- 要素 で割り当て #欲しい要素は「data$latitude:data$longitude」なので #「data$latitude」と「data$longitude」を「:」で結合(paste) data$latlong <- paste(data$latitude, data$longitude, sep=":")

Page 16: R入門とgoogle map +α

R とGoogleMap (データを表示)

•マッピングする

#gvisMapを利用してマッピング用データを準備 map <- gvisMap(data, locationvar=“latlong”, tipvar=“name”) #「option」で条件設定をすることもできる map <- gvisMap(data, locationvar = “latlong”, tipvar = “name”, options = list(showTip = F, enableScrollWheel = T, useMapTypeControl = T))

#作成したデータをブラウザで表示する plot(map)

Page 17: R入門とgoogle map +α

R とGoogleMap (完成?)

Page 18: R入門とgoogle map +α

+α: セールスマンの巡回

http://www.bunkyo.ac.jp/~nemoto/lecture/seminar2/2000/kimura/ronbun2.htm

巡回セールスマン問題(じゅんかいセールスマンもんだい、英: traveling salesman problem、TSP)は、都市の集合と各2都市

間の移動コスト(たとえば距離)が与えられたとき、全ての都市をちょうど一度ずつ巡り出発地に戻る巡回路の総移動コストが最小のものを求める(セールスマンが所定の複数の都市を1回だけ

巡回する場合の最短経路を求める)組合せ最適化問題である。(Wikipedia)

Page 19: R入門とgoogle map +α

街の公園を巡回し管理している人がいます。 彼らの移動時間を短くできないか考えてみます。

+α: セールスマンの巡回

イメージ図

Page 20: R入門とgoogle map +α

流山市のオープンデータトライアルHPから、「平和台」の公園データを使います。

http://www.city.nagareyama.chiba.jp/10763/index.html

#CSVファイルのURL url.parks <- "http://www.city.nagareyama.chiba.jp/dbps_data/_material_/localhost/shisetsu_kouen.csv" #公園データの取得 parks <- read.csv(url.parks) #平和台が付く公園の収集 parks.selected <- parks[grep("平和台", parks$名称), 1:7]

公園の位置を取得

Page 21: R入門とgoogle map +α

取得データの確認

• 公園は全部で10ヶ所 • 今回は名称、緯度、経度を使用

Page 22: R入門とgoogle map +α

地図上へのプロット

MP <- M + geom_point(data = parks.selected, aes(x=経度, y=緯度), size=7, colour="red")

公園の中には、実際にHPで紹介されている位

置とは違う位置にプロットされてしまうものもあります(下記、平和台1号公園)。左図のプロットはとりあえずの目安と考えて下さい。

HPの緯度経度からのプロット

HPで紹介されている位置

Page 23: R入門とgoogle map +α

「平和台」の公園データを同じ箇所を通らないように、最短で巡回する経路を考えてみます。まず、各公園間の移動時間を計算します。

1 2 3 4 5 6 7 8 9 10

1 0.0 5.3 5.8 0.0 5.4 3.0 4.9 5.1 2.2 11.2

2 5.3 0.0 6.1 5.7 11.1 4.5 8.9 9.3 4.8 6.5

3 5.8 6.1 0.0 5.2 8.0 5.5 9.2 9.5 3.2 10.4

4 0.0 5.7 5.2 0.0 5.4 3.0 4.9 5.1 2.2 11.2

5 5.4 11.1 8.0 5.4 0.0 7.1 5.2 4.1 6.0 16.0

6 3.0 4.5 5.5 3.0 7.1 0.0 5.1 5.5 2.8 9.5

7 4.9 8.9 9.2 4.9 5.2 5.1 0.0 2.9 6.3 11.5

8 5.1 9.3 9.5 5.1 4.1 5.5 2.9 0.0 6.2 13.4

9 2.2 4.8 3.2 2.2 6.0 2.8 6.3 6.2 0.0 10.6

10 11.2 6.5 10.4 11.2 16.0 9.5 11.5 13.4 10.6 0.0

#徒歩で移動する場合 travelmode = "walking" #nr x nrの時間行列と距離行列の作成 nr <- nrow(parks.selected) time <- matrix(0, nr, nr) distance <- matrix(0, nr, nr) for (i in 1:nr){ parks.selected.i <- parks.selected[i,] loc.i <- c(parks.selected.i$経度, parks.selected.i$緯度) for (j in (i+1):nr){ parks.selected.j <- parks.selected[j,] loc.j <- c(parks.selected.j$経度, parks.selected.j$緯度) route.ij <- route(loc.i, loc.j, mode=travelmode, structure="route") #時間行列と距離行列に代入 time[i, j] = time[j, i] <- sum(route.ij$minutes, na.rm=T) distance[i, j] = distance[j, i] <- sum(route.ij$km, na.rm=T) } }

各公園(1~10)間の移動時間を、route関数で計算した結果。単位はmin。徒歩移動とした。車移動の場合は、travelmode=“driving”

公園間の距離の計算

Page 24: R入門とgoogle map +α

最短距離の計算

10ヶ所の公園を1回ずつ経由するルートを、TSPパッケージを使って計算します。

install.packages("TSP"); library(TSP) ans <- solve_TSP(TSP(time))

• TSP関数で、距離の行列をTSP形式に変換 TSP: symmetric traveling salesperson problem(セールスマン巡回問題) • solve_TSP関数で、最短経路を求める

この順で公園をまわっていけばいいということらしい。

Page 25: R入門とgoogle map +α

公園の巡回順路、所用時間、距離をプロットしていきます。

#経路のプロット。ans[k]番目からans[k+1]番目の公園への移動経路のプロット for (k in 1:(nr-1)){ h1 <- ans[k]; h2 <- ans[k+1] route <- na.omit(route(c(lon[h1], lat[h1]), c(lon[h2], lat[h2]), mode=travelmode, structure="route")) #与えられた座標をそのまま使用すると正しく表示されないことがあるので、 #移動経路の始点(最後にまわる公園については終点)を公園の位置とした。 M <- M + geom_point(data=route[1,], aes(x=lon, y=lat), size=10, colour="red", alpha=0.75) M <- M + geom_text(data=route[1,], aes(x=lon, y=lat), label=k, colour="white") M <- M + geom_text(data=route[1,], aes(x=lon, y=lat+0.0005), label=parks.selected$名称[h1], colour=“red”, size=4) M <- M + geom_path(data=route, aes(x=lon, y=lat), size=1.5, colour="red", alpha=0.75) M <- M + geom_text(data=route, aes(x=mean(lon), y=mean(lat)), label=paste(sprintf("%3.1f", sum(route$min)), "min, ", sprintf("%3.1f", sum(route$km)), "km", sep=""), colour="white", size=4) if (nrow(route)<2){ lonlat <- data.frame(lon=lon[c(h1, h2)], lat=lat[c(h1, h2)]) M <- M + geom_path(data=lonlat, aes(x=lon, y=lat), size=0.75, colour="red", alpha=0.75, type="dotted") } } M <- M + geom_point(data=route[nrow(route),], aes(x=lon, y=lat), size=10, colour="red", alpha=0.75) M <- M + geom_text(data=route[nrow(route),], aes(x=lon, y=lat), label=k+1, colour="white") M <- M + geom_text(data=route[nrow(route),], aes(x=lon, y=lat+0.0015), label=parks.selected$名称[h1], colour="red", size=4)

プロット

Page 26: R入門とgoogle map +α

完成 (ごちゃごちゃ