Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
100
Help us understand the problem. What is going on with this article?
@Kender_09

ElasticsearchとPython使えば生活圏推定を簡単にできる話

More than 5 years have passed since last update.

概要

なんか書いてみようということで、Elasticsearchに行動履歴の位置情報を登録すれば、いい感じに利用できる上に、いい感じに可視化もできるという話をします。

前提知識

logo-elastic.png

今回Elasticsearchを利用するので、簡単に紹介。
ElasticsearchはApache Solrとよく比較される全文検索エンジンの一つです。スキーマフリーですべての入出力がREST&JSONになっています。またJavaで実装されています。

インストールはyumでもbrewでも簡単に出来ます。利用したい環境に合わせて調べてみてください。
ちなみにElasticsearchのGUIプラグインのelasticsearch-headが便利なので合わせて入れておくと良いです。

Elasticsearchの設定

Elasticsearchを起動できたら、利用するindex(データベースで言うテーブルのようなもの)の設定をしていきます。
その為にまずindexのマッピング方法をjsonで作成します。
今回は以下の様なデータセットのログがあることを想定します。

sample_log
{
  "id":1,
  "uuid":"7ef82126c32c55f7272d5ca5dd5e40c6",
  "time":"2015-12-03T04:21:01.641Z",
  "lat":35.658546,
  "lng":139.729281,
  "accuracy":47.126048
}

この様なデータセットが上手くマッピングされるように、フィールド毎のタイプなどの設定をします。今回は以下の様なマッピングの設定にしました。geoというデータセットのタイプのマッピングの設定をしてあげているというイメージです。

geo_mapping.json
{
  "geo" : {
    "properties" : {
      "id" : {
        "type" : "integer"
      },
      "uuid" : {
        "type" : "string",
        "index" : "not_analyzed"
      },
      "time" : {
        "type" : "date",
        "format" : "date_time"
      },
      "location" : {
        "type" : "geo_point"
      },
      "accuracy" : {
        "type" : "double"
      }
    }
  }
}

少し解説すると、uuidフィールドがnot_analyzedと設定しているのは、ユニークな値で形態素解析されたくない値なのでこうしています。
また今回重要となるのがlocationフィールドのtypeです。geo_pointはElasticsearchが提供しているtypeで、経度緯度をセットで登録することで利用できます。このフィールドのtypeにしておくことで便利な検索ができるようになったりします。詳しくは後で。

マッピングの設定が作成できたら、それを利用してindexを作成します。index名は今回test_geoにしてます。Elasticsearchを起動している状態で以下の様なcurlを投げてあげれば作成完了です。

indexの作成
curl -XPOST 'localhost:9200/test_geo' -d @geo_mapping.json

データの登録

データはログファイルとして所持していることを想定し、ログファイルから作成したindexにデータを登録していきます。
今回公式のpythonのclientがあるのでそれを利用してみます。

これはpipで簡単にインストールできます。

インストール
pip install elasticsearch

これを利用して登録していくプログラムは以下の用な感じです。

regist_es.py
import json
import sys
from elasticsearch import Elasticsearch

es = Elasticsearch()
index = "test_geo"
doc_type = "geo"

f = open('var/logs.json', 'r')

_line = f.readline()
while _line:
    data = json.loads(_line)
    _line = f.readline()
f.close()

for value in data:
    lat = value['lat']
    lon = value['lng']
    del value['lat']
    del value['lng']
    value.update({
        "location" : {
            "lat" : lat,
            "lon" : lon
        }
    })
    es.index(index=index, doc_type=doc_type, body=value, id=value['id'])

注意する点はgeo_pointに適した形にするために、latlonをまとめてlocationにしている点です。
このプログラムを実行すればlogs.jsonにあった行動履歴の情報がElasticsearchに登録されます。とても簡単ですね。

Kibanaで可視化

データの登録が出来たので、あとは煮るなり焼くなりです。
KibanaはElasticsearchに登録されているデータを可視化してくれる、公式の出している可視化ツールです。
現在はKibana4が出ているので、せっかくなので最新版を取ってきてみると良いと思います。
取得したら./bin/kibanaを実行するだけで5601番ポートでHTTPサーバが起動します。詳しい設定の方法など
実際に起動したら、適当なブラウザでアクセスするとダッシュボードの設定ができます。
色々といじって遊んでみると、下みたいなヒートマップなどが簡単に作成できたりします。

heatmap.png

histgram.png

生活圏推定

せっかくデータを登録したので利用もしてみます。
今回はこの論文(モバイル端末向けの位置情報を利用した情報推薦システム)の生活圏推定なんかをやってみます。
位置情報をgeo_typeで登録したので以下の様な、特定の位置から何km以内のデータを取得するというようなクエリが投げれます。

query = {
    "from":0,
    "query": {
        "filtered" : {
            "query" : {
                "simple_query_string" : {
                    "query" : uuid,
                    "fields" : ["uuid"],
                }
            },
            "filter" : {
                "geo_distance" : {
                    "distance" : 10 + 'km',
                    "geo.location" : {
                        "lat" : lat,
                        "lon" : lon
                    }
                }
            }
        }
    }
}

実際にこれを利用した生活圏推定とかした結果は以下みたいになりました。

Sample結果
Stage1
35.653945 , 139.716692
半径(km): 5.90

Stage2
35.647367 , 139.709346
半径(km): 1.61

重心使う場合
35.691165 , 139.709840
半径(km): 8.22

昼: (104)
35.696822 , 139.708228
半径(km): 9.61
夜: (97)
35.685100 , 139.711568
半径(km): 6.77

最寄り駅(昼): 東新宿
最寄り駅(夜): 新宿御苑前

感想

Elasticsearchはとても簡単に設定できる上に、利用するのも簡単です。
Elasticsearch凄い。Kibana凄い。しかも新プロダクト(Beats)もあるらしい。
データの量にもよりますが、Elasticsearchにとりあえず登録してみると色々と便利です。
ログなんかはfluentdとかで自動に登録することもできるので、組み合わせれば色々出来そうです。

記事書くのむずかしい…

100
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
100
Help us understand the problem. What is going on with this article?