在地理定位云中获得更多可能的位置

Get more probable positions in geolocation cloud

我不知道如何获取有关我要解决的这个问题的一些信息。我希望你告诉我要搜索的关键字或任何相关信息。

我有一组用户的地理位置(纬度、经度)。我想知道不同位置组的中间点(不确定这个概念)。

例如,我每分钟记录一次野生动物的位置,所以我得到类似 的信息。

我要处理的是得到最常见的(?)点组和中点(类似于

并且知道例如中点组第一是最“重复”的,所以它是动物睡觉的地方,第二组是动物喝水的地方,第三组是吃的地方(例如)。

我在 csv 数据库中有这些点,所以我可以使用 elasticsearch、java 甚至 python 来获取这些信息。

关于这个的任何线索都会非常有趣。

这是一个典型的 clustering 用例,我基本上看到两个选项:

1。基于质心的聚类

可以通过 centroid aggregations 在 Elasticsearch 中找到它。

2。基于密度的聚类

DBC is a much better approach b/c it's outlier-based. Here's a python implementation. There might be better ones out there, incl. scikit's very own。与他们不太熟悉,所以我现在只能说这些。


我来这里是为了谈论 Elasticsearch,所以您可以按照选项 #1 的方式进行操作:

  1. 设置索引
PUT animals
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_point"
      }
    }
  }
}
  1. 向其中添加一些位置
POST _bulk
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[7.5146484375,51.17934297928927]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[7.207031249999999,50.94458443495011]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[7.734374999999999,51.069016659603896]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[7.536621093749999,50.94458443495011]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[8.525390625,51.16556659836182]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[9.55810546875,50.83369767098071]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[9.0087890625,51.138001488062564]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[10.21728515625,50.56928286558243]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[10.87646484375,50.84757295365389]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[11.25,50.84757295365389]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[11.09619140625,50.77815527465925]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[11.513671874999998,50.84757295365389]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[11.3818359375,50.708634400828224]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[11.00830078125,50.736455137010665]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[11.6455078125,51.52241608253253]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[10.78857421875,50.3734961443035]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[10.546875,49.96535590991311]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[10.01953125,49.681846899401286]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[9.29443359375,49.85215166776998]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[8.942871093749998,49.710272582105695]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[9.20654296875,49.5822260446217]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[8.98681640625,49.52520834197442]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[8.6572265625,49.603590524348704]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[11.546630859375,50.14874640066278]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[11.865234375,50.0289165635219]}
{"index":{"_index":"animals","_type":"_doc"}}
{"location":[11.42578125,50.52041218671901]}

我根据你的草图在德国使用了一些随机点:

  1. 计算质心
POST animals/_search
{
  "size": 0,
  "aggs": {
    "weighted": {
      "geohash_grid": {
        "field": "location",
        "precision": 2
      },
      "aggs": {
        "centroid": {
          "geo_centroid": {
            "field": "location"
          }
        }
      }
    }
  }
}

这遍历了所有的点,而不是只是那些在你的草图中“明确绑定”的点。这意味着将有异常值包含需要跳过的很少的点。

所以采用 Elasticsearch returns 的桶,只过滤较大的桶(我在这里使用 JS 而不是 python),并使用 TurfJS 将它们转换为 geojson:

turf.featureCollection(
  buckets.filter(p => p.doc_count > 3)
         .map(p => turf.point([
           p.centroid.location.lon,
           p.centroid.location.lat
         ])))

产生以下结果:

如您所见,“中心”偏斜 b/c 浓度“不够高”。随着更集中的群体,算法变得更好。

但坦率地说,DBSCAN 是到达这里的方式,而不是加权质心。