1. scikit-mobilityとは?
scikit-mobilityは位置情報データを使用して人の動きを解析したり、可視化することができるpythonライブラリです。
公式ドキュメント:https://scikit-mobility.github.io/scikit-mobility/index.html
GitHub:https://github.com/scikit-mobility/scikit-mobility
公式ドキュメントは英語しかありませんが結構充実していて、
GitHubにはチュートリアル等も載っているので試してみるのがおすすめです。
scikit-mobilityの主な機能と、チュートリアルについて解説しているQiitaもありますのでこちらも是非参考にしてください。
2. 今回紹介する関数
- カテゴリ:measures(データ解析用関数)
- 参考URL:https://scikit-mobility.github.io/scikit-mobility/reference/measures.html
- 概要:緯度・経度・日時・ユーザーid等のデータから様々な移動パターンの解析を行うことができる関数が用意されています。
また、データ解析用の関数には二種類のカテゴリがあります。
- Collective measures(集団解析) : データセット全体の動きを解析できる関数
- Individual measures (個別解析):データセット内のユーザーそれぞれの動きを解析できる関数
今回はこのうち
1. Collective measures(集団解析)
に分類される関数たちを6つ、コードを交えて紹介していきます。
※ 今回この記事で使用しているデータは社内検証用のデータになります。
3. 前提処理
ライブラリのインストール
$ pip install scikit-mobility
詳しい環境構築はこちらを参考にしてください
TrajDataFrameデータの作成
- 以下の項目を含むデータを用意します。
latitude(type: float); 緯度(必須)
longitude (type: float); 経度(必須)
datetime (type: date-time); 日時(必須)
uid (type: string);(オプション)
tid (type: string); (オプション)
特に使いたいデータがない場合はscikit-mobilityのチュートリアルを参考にこちらのデータをダウンロードするといいと思います。
※自動でデータがダウンロードされるので気をつけてください
# ファイルのダウンロード(google colab等で実行する場合はこうすると楽です。)
import urllib.request
url='https://raw.githubusercontent.com/scikit-mobility/scikit-mobility/master/examples/geolife_sample.txt.gz'
save_name='geolife_sample.txt.gz'
urllib.request.urlretrieve(url, save_name)
- 用意したデータをTrajDataFrameに変換します。
import skmob
# リストをTrajDataFrameに変換する場合
tdf = skmob.TrajDataFrame(data_list, latitude=1, longitude=2, datetime=3)
# pandas.DataFrameをTrajDataFrameに変換する場合
tdf = skmob.TrajDataFrame(data_df, latitude='latitude', datetime='hour', user_id='user')
- TrajDataFrameはPandasDataFrameを拡張したものなので、Pandasでできるような基本的な処理を行うことができます。
4. Collective measures(集団解析)
参考URL:https://scikit-mobility.github.io/scikit-mobility/reference/collective_measures.html
概要
入力したuidにかかわらず、入力したデータ内のユーザー全体の位置データの傾向を解析する関数が用意されています。
random_location_entropy
概要
特定の場所を訪れたユーザーの推測可能性(ロケーションエントロピー)が算出されます。
(ロケーションエントロピーについては難しかったので、勉強中です。。)
inputに必要なデータとパラメータ、outputされるデータについて
- inputデータ
- tdf(TrajDataFrame): 緯度経度データ
- パラメータ
- show_progress: Trueの場合プログレスバーを表示
- inputするデータ例
- outputデータ
コード例
from skmob.measures.collective import random_location_entropy
# 'sort_values'でrandom_location_entropyの高い順にソート
rle_df = random_location_entropy(tdf,
show_progress=True).sort_values(by='random_location_entropy', ascending=False)
rle_df.head()
- データ内のユーザーがいる確率が最も高いとされるrandom_location_entropy=1.0の場所を可視化してみました。
→ 渋谷周辺が最もデータ内のユーザーが訪問する確率が高いとされているようです。
→ ナイトレイ社内のデータなので、ナイトレイがある渋谷の確率が高いのは矛盾がないですね。
uncorrelated_location_entropy
概要
時間的に相関なく特定の場所に訪問したことがあるユーザー数の推測可能性を算出する関数です。
inputに必要なデータとパラメータ、outputされるデータについて
-
inputデータ
- tdf(TrajDataFrame): 緯度経度データ
-
パラメータ
- normalize: Trueの場合位置エントロピーを正規化する
- show_progerss: Trueの場合プログレスバーを表示する。
-
inputするデータ例
-
outputデータ
コード例
from skmob.measures.collective import uncorrelated_location_entropy
# 'sort_values'でuncorrelated_location_entropyの高い順にソート
ule_df = uncorrelated_location_entropy(tdf, show_progress=True).sort_values(by='uncorrelated_location_entropy', ascending=False)
ule_df.head()
mean_square_displacement
概要
全体の平均二乗ゆらぎを計算します。
平均二乗ゆらぎ:時間の経過に伴う基準位置に対するオジェクトの位置の偏差の尺度
知識が足りず理解できていないです。勉強中です。。
inputに必要なデータとパラメータ、outputされるデータについて
-
inputデータ
- tdf(TrajDataFrame): 緯度経度データ
-
パラメータ
- days: 開始時刻からの日数
- hours: 開始時刻からの日数からの時間
- minutes: 開始時刻からの日数からの時間からの分数
- show_progress: Trueの場合プログレスバーを表示
-
inputするデータ例
-
outputデータ
コード例
from skmob.measures.collective import mean_square_displacement
msd_tdf = tdf.sort_values(by='datetime')
msd = mean_square_displacement(msd_tdf, days=0, hours=1, minutes=0)
visits_per_location
概要
各ロケーション(場所)への全ユーザーの総訪問数を算出します。
inputに必要なデータとパラメータ、outputされるデータについて
-
inputデータ、パラメータ
- tdf(TrajDataFrame): 緯度経度データ
-
inputするデータ例
-
outputデータ
コード例
from skmob.measures.collective import visits_per_location
vl_df = visits_per_location(tdf)
vl_df.head()
homes_per_location
概要
ある場所にある自宅の数が算出されます。
夜の時間帯に最も多くユーザーがいた緯度経度を"家"と定義しているようです。
inputに必要なデータとパラメータ、outputされるデータについて
- inputデータ、パラメータ
- tdf(TrajDataFrame): 緯度経度データ
- パラメータ
- start_night: 夜判定の開始時刻(形式:HH:MM)
- end_night: 夜判定の終了時刻(形式:HH:MM)
- inputするデータ例
- outputデータ
コード例
from skmob.measures.collective import homes_per_location
hl_df = homes_per_location(tdf).sort_values(by='n_homes', ascending=False)
hl_df.head()
visits_per_time_unit
概要
単位時間あたりの訪問数を算出します。
inputに必要なデータとパラメータ、outputされるデータについて
-
inputデータ
- tdf(TrajDataFrame): 緯度経度データ
-
パラメータ
- time_unit: 単位時間の指定
-
inputするデータ例
-
outputデータ
コード例
from skmob.measures.collective import visits_per_time_unit
vtu_df = visits_per_time_unit(tdf)
vtu_df.sort_values("n_visits", ascending=False).head()
5. シリーズ記事
今回はここまでになります。
ここまで読んでいただき、ありがとうございました。
scikit-mobilityについて、シリーズで記事を投稿しています。
シリーズの記事もぜひ読んでいただけると嬉しいです。
前回の記事はこちらです。
最後に
私たちの会社、ナイトレイでは一緒に事業を盛り上げてくれるGISチームメンバーを募集しています!
現在活躍中のメンバーは開発部に所属しながらセールス部門と密に動いており、
慣れてくれば顧客とのフロントに立ち進行を任されるなど、顧客に近い分やりがいを感じやすい
ポジションです。
このような方は是非Wantedlyからお気軽にご連絡ください(もしくは recruit@nightley.jp まで)
✔︎ GISの使用経験があり、観光・まちづくり・交通系などの分野でスキルを活かしてみたい
✔︎ ビッグデータの処理が好き!(達成感を感じられる)
✔︎ 社内メンバーだけではなく顧客とのやり取りも実はけっこう好き
✔︎ 地理や地図が好きで仕事中も眺めていたい
一つでも当てはまる方は是非こちらの記事をご覧ください 。
二つ当てはまった方は是非エントリーお待ちしております(^ ^)
「位置情報×モビリティ.まちづくりetc事業領域拡大の為GISエンジニア募集」
▼ナイトレイとは?