この記事は「SORACOM Advent Calendar 2015」の 13 日目の記事です。先日 Tokyo.R で発表したネタと重複するところがあるのですが,ご容赦ください。
SORACOM がリリースされたときに面白いなと思ったものの,個人ではあまりハードウェア系を作る趣味があまりないこともあって,格安 SIM として個人で使うのはちょっと割高かなぁと思っていました。とはいえ今後仕事上で IoT のデータ分析案件を獲得していきたいなぁと思ったので,概念実証的な意味も込めて SORACOM Air を使い始めました。
そんなわけで, SORACOM Air の通信履歴をとって遊ぼう,せっかくだから GPS データもとって併せて可視化してみようと考えて SORACOM Air を購入したのがちょうど先月です。
この記事で書くのは, SORACOM Air の通信履歴を地図上にお絵かきしてみようというお話です。
ライブラリーを作る
データが欲しいので API が叩ければ良いのですが,せっかくなので SORACOM API を網羅したライブラリーがあると良いなと思って soracomr という R のパッケージを作成しました。一部まだ未実装なところはありますが, 9 割以上 (2015 年 12 月時点) の API をカバーしています (下記参照)。
基本的な API で SIM の登録とグループの configuration の設定まわりがまだ実装できていません。
SIM の登録に関しては SORACOM API のタグの指定のドキュメントがおかしいので問い合わせて回答を得たのであとは実装するだけなのですが,テスト用の未登録 SIM を購入するのが面倒なので放置しています。登録した SIM を未登録状態にできればよいのですが…。
configuration の方は設計レベルでどうしようか考えている段階です。今後サービスが増えるので自由に与えられる形式にしつつ,既存のサービスについては簡単に設定できるようにしたいので,どう与えるのがよいのか検討しています。
閑話休題, soracomr を作ったので,これを使うことで SORACOM API が簡単に利用できるようになりました。まだ CRAN (R のパッケージリポジトリ) に登録していないので,インストールは devtools パッケージを使って GitHub 経由で行います。
install.packages("devtools") devtools::install_github("kos59125/soracomr")
データ
通信履歴の取得
soracomr を利用して通信履歴を取得します。
通信履歴は以下のように取得することができます。
library(soracomr) token <- get_token("MY MAIL ADDRESS", "MY PASSWORD") subscriber <- get_subscriber(token, "MY IMSI") stats <- get_stats(token, subscriber, period = "minutes")
period パラメーターを "minutes" に指定すると, 5 分間隔での通信履歴が取得できます。以下のような感じです。
date | unixtime | dataTrafficStatsMap.s1.minimum.uploadByteSizeTotal | dataTrafficStatsMap.s1.minimum.downloadByteSizeTotal | dataTrafficStatsMap.s1.minimum.uploadPacketSizeTotal | dataTrafficStatsMap.s1.minimum.downloadPacketSizeTotal | dataTrafficStatsMap.s1.slow.uploadByteSizeTotal | dataTrafficStatsMap.s1.slow.downloadByteSizeTotal | dataTrafficStatsMap.s1.slow.uploadPacketSizeTotal | dataTrafficStatsMap.s1.slow.downloadPacketSizeTotal |
---|---|---|---|---|---|---|---|---|---|
2015-12-10T08:34:14.777 | 1449736454 | 46359 | 57553 | 256 | 255 | NA | NA | NA | NA |
2015-12-10T08:34:44.215 | 1449736484 | 374549 | 342990 | 1283 | 1094 | NA | NA | NA | NA |
2015-12-10T08:39:14.766 | 1449736754 | 15368 | 19132 | 120 | 133 | NA | NA | NA | NA |
2015-12-12T08:26:02.387 | 1449908762 | 97346 | 116226 | 387 | 323 | NA | NA | NA | NA |
2015-12-12T08:31:02.401 | 1449909062 | 179664 | 111522 | 367 | 305 | NA | NA | NA | NA |
2015-12-12T08:36:02.422 | 1449909362 | NA | NA | NA | NA | 558291 | 873195 | 2152 | 1721 |
結果のタイムスタンプはデータを記録した時点でのタイムスタンプです。タイムスタンプが 2015-12-10T08:34:14.777 というレコードの場合は, 2015-12-10T08:34:14.777 まで (つまり 08:29 から) の 5 分間の通信データが,そのレコードに記録されていることになります[A]。この事実は後で利用します。
とりあえず欲しかったのは通信量だけなので,以下ではスピードクラスは無視して通信量だけで考えます。単純に各スピードクラスの値について合計すれば良いです。
GPS
Android の My Tracks というアプリを利用して GPS のロギングを行っています。このアプリケーションは KMZ 形式や CSV 形式でのエクスポートができます。 R から使うなら CSV が楽です,というか KMZ だとデータの読み込みがおかしかったので (多分使ったパッケージの問題でしょう), CSV しか使えませんでした。
通信履歴と GPS の結合
通信履歴も GPS もミリ秒単位でレコードを蓄積しています。そのまま結合すると以下のようなデータになってしまいます。
date | upload | download | longitude | latitude |
---|---|---|---|---|
t1 | up1 | down1 | NA | NA |
t2 | NA | NA | long2 | lat2 |
t3 | NA | NA | long3 | lat3 |
t4 | NA | NA | long4 | lat4 |
t5 | up5 | down5 | NA | NA |
t6 | NA | NA | long6 | lat6 |
NA はこの後の処理で利用できないので,できるだけ NA を埋める必要があります。通信量については 5 分前を上限として前のレコードに時間単位で分割してやります。 5 分以上前のデータも NA であれば 0 とします。 GPS については前後の位置から時間で線形補完します。
date | upload | download | longitude | latitude |
---|---|---|---|---|
t1 | up1 | down1 | NA | NA |
t2 | up2 | down2 | long2 | lat2 |
t3 | up3 | down3 | long3 | lat3 |
t4 | up4 | down4 | long4 | lat4 |
t5 | up5 | down5 | long5 | lat5 |
t6 | NA | NA | long6 | lat6 |
先頭と末尾については埋めようがないので捨てます。最終的に以下のような NA のないデータを作成します。
date | upload | download | longitude | latitude |
---|---|---|---|---|
t2 | up2 | down2 | long2 | lat2 |
t3 | up3 | down3 | long3 | lat3 |
t4 | up4 | down4 | long4 | lat4 |
t5 | up5 | down5 | long5 | lat5 |
地図データ
地図データはたくさん無料で転がっているのでどれを利用するのでもよいのですが,今回は国土数値情報の鉄道データおよび ESRI ジャパンの全国市区町村界データを利用しました。
ちなみに最近別の Advent Calendar で国土数値情報データを R から簡単に利用できるようなパッケージを作ったという話をみたので,それを使うと楽かもしれません。
可視化
以上のデータを利用して,通信量で重み付けをしてコンターを作成します。努力すれば GPS の精度も考慮した重み付けみたいなことも可能なのですが, GPS の位置を真として単純にカーネル密度推定を行った結果です。
通信強度は推定された確率密度なので,何バイトとかそういう単位ではありません。数値は大小を表すだけで,数値そのものの意味は特に気にしないでください。
地図の中央付近にある自宅からの通勤経路や仕事場でよく利用されているのがわかります。自宅は WiFi 環境なので通信強度は高くありません。アップロードの強度が図の中央付近で強く出ているのは,多摩動物公園で写真をたくさんアップロードした結果です。
平日・休日ごとや,時間帯ごとに区切った地図も作ったりすると,自分が普段どんな動きをしているのかがわかって楽しいです。
まとめ
SORACOM API のラッパーライブラリーを R で作り,それを利用して可視化まで行いました。
デバイス企業通信データや GPS データ以外の様々なデータが SORACOM プラットフォームを経由して容易に蓄積できるようになっています。今後 IoT 分野でデータが蓄積されるようになると,データ分析業界も盛り上がってくれるのではないかと期待しています。
脚注
- SORACOM に問い合わせて確認 [↩]