使用Elasticsearch和Python可以轻松进行生活范围的推定
简述
我要试着写点东西,说说如果将行动历史的位置信息注册到Elasticsearch中,就可以方便地利用,并且可以很好地进行可视化的问题。
前提知識

因为本次要使用Elasticsearch,所以简单介绍一下。
Elasticsearch是一种常与Apache Solr进行比较的全文搜索引擎。它使用无模式的架构,所有的输入输出都以REST和JSON格式进行。此外,它是用Java实现的。
- 詳しくはElasticsearchの紹介と特徴
安装可以通过yum或brew很容易地完成。请根据您想使用的环境自行查找。顺便一提,Elasticsearch的GUI插件elasticsearch-head非常方便,建议一起安装。
Elasticsearch的设置
一旦成功启动Elasticsearch后,我们将开始设置要使用的索引(类似于数据库中的表)的配置。
为此,首先我们将使用json格式创建索引的映射方法。
本次假设存在以下类似数据集的日志。
{
"id":1,
"uuid":"7ef82126c32c55f7272d5ca5dd5e40c6",
"time":"2015-12-03T04:21:01.641Z",
"lat":35.658546,
"lng":139.729281,
"accuracy":47.126048
}
为了使这种数据集能够成功映射,我们对每个字段进行了类型等设置。这次我们选择了以下设置来映射geo数据集的类型。可以想象我们正在对geo数据集进行类型映射的设置。
{
"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字段的类型。geo_point是Elasticsearch提供的类型,通过设置经纬度来进行使用。通过设置该字段的类型,可以方便地进行搜索等操作。详细内容稍后会说明。
在创建了映射设置之后,可以使用它来创建索引。本次使用的索引名称是test_geo。在Elasticsearch运行的状态下,通过发送以下的curl命令即可完成创建。
curl -XPOST 'localhost:9200/test_geo' -d @geo_mapping.json
数据的注册
假设数据以日志文件的形式存储,并且我们会将数据注册到从日志文件创建的索引中。
由于这次有官方的Python客户端,我们将尝试使用它。
- 公式: elasticsearch-py
这个可以很容易地通过使用pip进行安装。
pip install elasticsearch
以下是使用这个进行注册的程序的感觉。
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'])
该程序的要点是将lat和lon合并成location,以便将其调整为适合geo_point的形式。
执行此程序后,logs.json中的行为历史信息将被注册到Elasticsearch中。非常简单。
在Kibana中进行数据可视化
数据已经注册了,剩下的就是煮或者烤了。
Kibana是一个官方提供的可视化工具,可以将数据可视化显示在Elasticsearch中注册的数据上。
目前Kibana4已经发布,建议下载最新版本试试看。
下载后,只需执行./bin/kibana命令,就可以在5601端口启动HTTP服务器。更详细的设置方法等,请参考相关文档。
实际启动后,通过任意合适的浏览器访问即可进行仪表盘的配置。
尝试调整一下,玩一下,就可以轻松地创建像下面这样的热力图等。


生活圈估计
我已经注册了数据,所以我将尝试使用它。
这次我将尝试做这篇论文(基于移动设备位置信息的信息推荐系统)中的生活圈估计。
因为我使用了geo_type在位置信息上进行了注册,所以我可以发送这样的查询,即获取距离特定位置多少公里以内的数据。
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
}
}
}
}
}
}
实际上,利用这个方法进行生活圈估计的结果如下所示。
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等自动注册,所以结合起来可以做很多事情。
写文章真难…