こんにちは、ナイトレイインターン生の田中です!
Wantedlyをご覧の方に、ナイトレイのエンジニアがどのようなことをしているか知っていただきたく、Qiitaに公開している記事をストーリーに載せています。
少しでも私たちに興味を持ってくれた方は下に表示される募集記事もご覧ください↓↓
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 (個別解析):データセット内のユーザーそれぞれの動きを解析できる関数
今回はこのうち
Individual measures (個別解析)
に分類される17個の関数のうち以下の6つの関数を、コードを交えて紹介していきます。
- radius_of_gyration:ユーザーの特徴的な移動距離を算出する関数
- k_radius_of_gyration:ユーザーの最も頻度の高いk個の場所からの特徴的な移動距離を算出する関数
- random_entropy:ユーザーのランダムエントロピーを算出する関数
- uncorrelated_entropy: 各場所の履歴確率からユーザーの訪問パターンの特徴を算出する関数
- real_entropy:「移動パターン」に存在する時空間的な特徴の予測可能確率を算出する関数
- jump_lengths:時系列順に並んだ2つの連続した各ポイント間の距離を算出する関数
※ 今回この記事で使用しているデータは社内検証用のデータになります。
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')
Individual measures (個別解析)
参考URL:https://scikit-mobility.github.io/scikit-mobility/reference/individual_measures.html
概要
入力したuidごとの移動履歴、行動パターンを解析する関数が所属しています。
radius_of_gyration
概要
各ユーザーの特徴的な移動距離を算出する関数
inputに必要なデータとパラメータ、outputされるデータについて
- inputデータ
- tdf(TrajDataFrame): 緯度経度データ
- tdf(TrajDataFrame): 緯度経度データ
- パラメータ
- show_progress: Trueの場合、プログレスバーを表示。
- show_progress: Trueの場合、プログレスバーを表示。
- inputデータ例
- データ型はTrajDataFrameのデータを使用します。
- outputデータ
- 各ユーザーの特徴的な移動距離(回転半径)を算出します。
- outputされるデータ例
- uidとradius_of_gyrationのカラムを含むデータが出力されます。
- ユーザーidとそれに対応するユーザーの特徴的な移動距離がわかります。
- 特徴的な移動距離の内容が理解できておらず勉強中です。。
- 習慣(よくあるパターン)的な特徴なのか、珍しい移動的な特徴なのかが未だわからずといった感じです。
- コード例
from skmob.measures.individual import radius_of_gyration
rg_df = radius_of_gyration(tdf)
rg_df.head(10)
k_radius_of_gyration
概要
ユーザーの最も頻度の高いk個の場所からの特徴的な移動距離(k回回転半径)を算出する関数
inputに必要なデータとパラメータ、outputされるデータ
- inputデータ
- tdf(TrajDataFrame): 緯度経度データ
- tdf(TrajDataFrame): 緯度経度データ
- パラメータ
- k: 最も頻繁に訪れる場所の数(デフォルトは2)
- show_progress: Trueの場合、プログレスバーを表示
- inputデータ例
- データ型はTrajDataFrame。
- outputデータ
- 各ユーザーの最も頻度の高いk個の場所からの特徴的な移動距離をuidごとに算出します。
- outputされるデータ例
- コード例
from skmob.measures.individual import k_radius_of_gyration
krg_df = k_radius_of_gyration(tdf)
krg_df.head(10)
random_entropy
概要
各ユーザーのランダムエントロピー(予測可能性)を算出する関数
inputに必要なデータとパラメータ、outputされるデータ
- inputデータ
- tdf(TrajDataFrame): 緯度経度データ
- tdf(TrajDataFrame): 緯度経度データ
- パラメータ
- show_progress: Trueの場合、プログレスバーを表示
- show_progress: Trueの場合、プログレスバーを表示
- inputデータ例
- データ型はTrajDataFrame。
- outputデータ
- 各ユーザーの居場所の予測可能性が算出されます。
- outputされるデータ例
- コード例
from skmob.measures.individual import random_entropy
re_df = random_entropy(tdf)
re_df.head(10)
uncorrelated_entropy
概要
各場所の履歴確率からユーザーの訪問パターンの特徴を算出する。
inputに必要なデータとパラメータ、outputされるデータ
- inputデータ
- tdf(TrajDataFrame): 緯度経度データ
- tdf(TrajDataFrame): 緯度経度データ
- パラメータ
- normalize: Trueの場合範囲内のエントロピーを正規化
- show_progress: Trueの場合プログレスバーを表示
- inputデータ例
- データ型はTrajDataFrame。
- outputデータ
- 各ユーザーの訪問パターンの特徴のエントロピーを算出
- outputされるデータ例
- コード例
from skmob.measures.individual import uncorrelated_entropy
ue_df = uncorrelated_entropy(tdf, normalize=True)
ue_df.head(10)
real_entropy
概要
訪問頻度、訪問した場所の順序や各場所に滞在した時間から、「移動パターン」に存在する時空間的な特徴の予測可能確率を算出する
inputに必要なデータとパラメータ、outputされるデータ
- inputデータ
- tdf(TrajDataFrame): 緯度経度データ
- tdf(TrajDataFrame): 緯度経度データ
- パラメータ
- show_progress: Trueの場合、プログレスバーを表示
- show_progress: Trueの場合、プログレスバーを表示
- inputデータ例
- データ型はTrajDataFrame。
- outputデータ
- 各ユーザーの移動パターンの特徴の予測可能確率をuidごとに算出します。
- outputされるデータ例
- コード例
from skmob.measures.individual import real_entropy
rtdf = tdf.sort_values(by="datetime")
re_df = real_entropy(rtdf)
re_df.head(10)
jump_lengths
概要
時系列順に並んだ2つの連続した各ポイント間の距離を算出する
inputに必要なデータとパラメータ、outputされるデータ
- inputデータ
- tdf(TrajDataFrame): 緯度経度データ
- tdf(TrajDataFrame): 緯度経度データ
- パラメータ
- show_progress: Trueの場合、プログレスバーを表示
- merge: Trueの場合、個人のリストを1つのリストにマージする
- inputデータ例
- データ型はTrajDataFrame。
- inputデータは、datetimeで昇順に並べ替える必要があります。
- outputデータ
- uidごとに各ポイント間の距離を算出し、表示します。
- merge=Falseの場合は、pandas.DataFrameで出力されます。
- outputされるデータ例
- merge=Trueの場合は、listで出力されます。
- uid関係なく全件のデータがlistにまとめられてしまうようなので、データを入れる前にuidごとに処理できるようにする一工程が必要そうです。
- コード例
- uid関係なく全件のデータがlistにまとめられてしまうようなので、データを入れる前にuidごとに処理できるようにする一工程が必要そうです。
from skmob.measures.individual import jump_lengths
jl_df = jump_lengths(tdf)
jl_df.head(10)
# mergeあり
jl_list = jump_lengths(tdf, merge=True)
4. シリーズ記事
scikit-mobilityについて、シリーズで記事を投稿しています。
シリーズの記事もぜひ読んでいただけると嬉しいです。
前回の記事はこちらです。
最後に
私たちの会社、ナイトレイでは一緒に事業を盛り上げてくれるGISチームメンバーを募集しています!
現在活躍中のメンバーは開発部に所属しながらセールス部門と密に動いており、
慣れてくれば顧客とのフロントに立ち進行を任されるなど、顧客に近い分やりがいを感じやすい
ポジションです。
このような方は是非Wantedlyからお気軽にご連絡ください(もしくは recruit@nightley.jp まで)
✔︎ GISの使用経験があり、観光・まちづくり・交通系などの分野でスキルを活かしてみたい
✔︎ ビッグデータの処理が好き!(達成感を感じられる)
✔︎ 社内メンバーだけではなく顧客とのやり取りも実はけっこう好き
✔︎ 地理や地図が好きで仕事中も眺めていたい
一つでも当てはまる方は是非こちらの記事をご覧ください 。
二つ当てはまった方は是非エントリーお待ちしております(^ ^)
「位置情報×モビリティ.まちづくりetc事業領域拡大の為GISエンジニア募集」
https://www.wantedly.com/projects/1031814
▼ナイトレイとは?