交通センサスの解析と可視化

概要

今回は交通センサスの解析して市区町村間の交通流動を解析して日本の市区町村をグルーピングし、GISの仕組みを使って可視化するところまでやったので、その話をします。

モチベーション

そもそもなんでそんなことを始めたかというと、特に福島県なんですが「県境の設定が雑じゃね?」みたいな素朴な疑問があったからです。 これは歴史的事実として、実際に廃藩置県の政治的なゴタゴタの中で決まった県境が変更されずに今に至っているので当然そうなんですが、 となると「じゃあそこらへん合理的に県境を決めたらどうなるん?」という疑問がわいてくるわけです。

多くの地元民が納得する県境を考えると、 「大きな買い物をするときに行く街や、遠くに行くときにいくときに経由する街が同じ都道府県になると、まあまあうまくいくだろう」 という仮説をまず立てます。

その上で、その地域のグループを作るのであれば、最も交通流動の多い地域を繋いで、最終的に辿りつく大きな街が同じ地域をグルーピングすれば良いであろうと大雑把に考えたわけです。

さて、市区町村境界のそれぞれの交通量ってどう調べたもんかなあとなるわけですが、ここで交通センサスが出てきます。

道路交通センサスとは

5年に1度、主要道路の交通量を1台単位で計測する調査です。 この調査結果はWebで公開されており、簡単にダウンロードして個人レベルでも様々な解析にかけることが可能です。

http://www.mlit.go.jp/road/census/h27/

データとしては1日の交通量はもちろん、平日と休日の差や時間単位の交通量も取得できます。 区間は主要交差点や市区町村境界でで区切られた全ての区間の交通台数が取得できます。 おおまかな車種毎の交通量も測定できます。 平日・休日のデータと併せて、道路の主要用途なども類推できそうです。

データは非常に大きなCSVで、1レコードが1つの調査区間になっていて、その区間の全てのデータが詰め込まれています。

以下は参考のPDFデータです(CSVはあまりにも見辛いので)

GitHub

これから解説する処理をコードに落としたのがこちらになります。

https://github.com/ponkotuy/traffic

交通センサスのデータを自動でダウンロードするスクリプトがあったり、sbt runでGeoJSONのpropertiesに解析結果をぶちこむところまでやってくれるTrafficAnalyzerというmainメソッドがあったりします。

なおScalaです。平均レベルのエンジニアはきっとScala読めると思うので問題ないですね☆

区間の突合

交通センサスの1レコードは、道路が市区町村境界で区切られているために、同じ市区町村内で完結しており、 市区町村のID(標準地域コード)が振られています。 ある道路の市区町村境界の交通量を調べるには、市区町村境界で始まっている/終わっている道路を抽出し、 対になる区間を探す(突合する)必要があります。 これが実に厄介なのですが、市区町村境界と都道府県境界で全く異なった処理が必要になります。

市区町村境界

接続先道路のIDが振られていないですが、「○○市と○○町の境界」などという名前が付いており、 これと道路名/IDが同じものと突合できます。 またCSVファイルは都道府県毎になっていて、市区町村境界は同じ都道府県内にあることが保証されているので、ファイルをまたぐ必要はありません。

都道府県境界

こちらはCSVファイルを確実にまたぐことになるので厄介ですが、接続先のIDが振られているので、そのIDの道路を参照すれば突合できます。どうして市区町村境界にその仕様を入れなかった。

という境界チェックをするソースコードが以下のようになってます。

traffic/src/main/scala/csv/BoundaryTrafficAnalyzer.scala at a668c68f6999777f1fba17e6cebef21ebfd3c991 · ponkotuy/traffic · GitHub

可視化

これを全国規模で解析にかければ簡単に市区町村の交通流量のtableを作り、地域のグルーピングができます。 しかし折角なので分かりやすく可視化したいです。 こういう地図っぽいものを可視化するならGISの出番です。

最初GIS、有料のお高いのしかないと思っていたんですが、 QGISというオープンソースのツールが出ていて、一通り必要な機能が揃っているのでオススメです。

https://www.qgis.org/ja/site/index.html

QGISは一通りの形式を扱うことができますが、プログラマー的に馴染みの深いJSONをベースにしたGeoJSONを使って可視化します。 なお、GeoJSONはMB級の大きなファイルになることが多いので、処理する場合は高速な処理系・高速なライブラリを使うと幸せになれます。

やりたいことはGeoJSONを呼んでfeaturesの中で各要素のpropertiesに欲しい要素を追加したいだけなので、パース・追記・saveの3機能をもったclassをjacksonで作ったりしました。

traffic/src/main/scala/geojson/GeoJson.scala at be7b06894741364ffa3d9953984c5cf930a09f92 · ponkotuy/traffic · GitHub

市区町村地図

さて、可視化するには市区町村境界の書き込まれたGeoJSONが必要なわけですが、国土交通省のサイトに落ちてます。

http://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N03.html

この地図をGISに読み込ませると、GeoJSONのpropertiesに書いた値からラベルをレンダリングしたり、 値に応じて色分けしたり、濃淡をつけて塗ったりできます。

このデータに先程交通センサスを解析して作った地域グループを登録すれば可視化できます。

結果

今回は県境との違いが見たかったので本州のみの図になりますが以下のようになりました。

といっても小さくて分からないとおもうのでいくらか気になったところをピックアップしてみます。

青森県は弘前と八戸が比較的大きい都市ですが、八戸市の影響が岩手県まで食い込んでるのが見てとれます。 ただ階上町がちょっとあやしいですね…ほんとうかな…?

宮城が気仙沼市まで伸びているのは個人的に大分ちゃうやろという感じでしたが、案の定一関の方に属してますね。

福島県は新潟県にもっと食い込むのを想像してたんですが特にそうはならなかったのと、 会津盆地でまとまるかとおもったら一部が郡山に食い込んだのが完全に誤算でおどろいてるところです。 浜通りが分離したりいわき市が影響力大きくて茨城県に食い込んでるのは想定内です。 浜通りが茨城に編入されると割と自然な県分けになるんでしょうか?

関東はわりと想像通り都心に伸びる高速道路に沿ったような区分けになってます。 特に中央自動車道が強い。 あとやはり古河市が茨城県なのは無理があるみたいで栃木県の小山市とグループ作ってます。

南あわじ市が徳島側に属しているのが意外過ぎてびっくりです。 鳴門大橋の交通量が、洲本市との境界にある神戸淡路鳴門自動車道を含めた道路の交通量より多いということに他ならないので。

島根と鳥取の県境はなぜか人口集中してる地域を真っ二つにしてる違和感があったので、これも想定通り1グループになっていますね。 参議院選挙も合区になったし1つになればいい気がします。 中国山地が越えられないのも想定通りです。

個人的に一番想定通りになってるのが山口県で、広島寄りの岩国、中央の山口市、小倉に編入された下関という完璧な分類です。

鳥栖とか絶対福岡でしょと思った人は多いと思いますが実際そうなってますね。

まとめ

地域的なまとまりを道路交通の利用状況から推測してみるようなことをやってみました。 8割方良い結果が出ているものの、同一グループに属するルールに関しては若干見直しが必要かもしれません。 とりあえず市区町間の交通量は出ているので、もう少しルールを見直せばもう少しそれっぽいグループ分けができるかもしれません。

あと都道府県の分類のような行政区画の設定は、人口規模ができるだけ均一になる必要があるので、 そのような観点でまとまりを広げるような要素の導入が必要になりそうです。

余談ですが、山中の村落が大きな都市と接続せずこじんまりとまとまってしまう現象が多く観測され、 「実は交通困難で都市部に出られない田舎の人ってめっちゃ多いのでは?」みたいな別の問題がありそうな気がしている昨今です。 なにかの考慮漏れならいいんですが。