如何在地图上寻找最密集点的位置?

简介: 最近我在工作中遇到了一个小的需求点,大概是需要在地图上展示出一堆点中的点密度最密集的位置。最开始没想到好的方法,就使用了一个非常简单的策略——所有点的坐标求平均值,这个方法大部分的时候好用,因为大部分城市所有点位基本上都是围绕某个中心点向四周发散的。但我们实际在线上使用的时候,遇到了两个特殊的case。

最近我在工作中遇到了一个小的需求点,大概是需要在地图上展示出一堆点中的点密度最密集的位置。最开始没想到好的方法,就使用了一个非常简单的策略——所有点的坐标求平均值,这个方法大部分的时候好用,因为大部分城市所有点位基本上都是围绕某个中心点向四周发散的。但我们实际在线上使用的时候,遇到了两个特殊的case。


 首先就是当点位分布呈现出异形,比如哑铃型数据分布在两头,你们求平均值的方法就会找到中间数据密度最稀疏的地方,就比如我们在成都的数据上遇到的一样,下图中的红色点位就是按平均值求出来的中心点。

image.png

 另外一种异常case就是数据呈现圆周分布的时候,比如北京的数据,北京的中心是故宫,我们不可能会有点位,如果直接求平均值的话,计算出来的中心点就在故宫附近,这里的数据反而是最稀疏的,如下图所示。

image.png

 后来查询资料,了解到核密度这一方法可以解决我们所遇到的问题,经过实验后发现效果还不错,所以在这里分享给大家。 核密度的思路也很简单,就是遍历所有的点位,计算其他点到当前点的核密度总值,然后找出平均密度最大的点。举个简单例子,给定一个点,如果其他某个点距这个点距离近,密度值就高,反之就远,这个点到其他所有点的密度和求平均就是这个点最终的密度值,这里我们可以直接选用距离的倒数来当成核函数,不过这个核函数是线性的,最终结果和我求平均值差异不大。


 优化下思路,如果某个点的距离越远,是不是其带来的密度值应该越小? 前人也是这么想的,于是就有了很多非线性核函数,而我最终使用了高斯核,调整好核函数的带宽后,其他点带来的密度值也会随着距离,以正态分布的方式衰减如下图,举例越远纵轴的坐标值越低,图中的sigma就是我们核函数的里的带宽。

image.png

 接下来看下计算过程和效果,由于我们是Java系统,我的最终实现是用了java调用了simle包,整体代码如下:

private double[] getHotpot(double[][] data) {
  // 创建高斯核
  MercerKernel<double[]> kernel = new GaussianKernel(0.02);
  // 计算所有点的核密度估计
  double[] densities = new double[data.length];
  for (int i = 0; i < data.length; i++) {
    for (int j = 0; j < data.length; j++) {
    densities[i] += kernel.k(data[i], data[j]);
    }
    // 计算平均密度
    densities[i] /= data.length;
  }
  // 找出密度最大的点
  int maxDensityIndex = 0;
  for (int i = 1; i < densities.length; i++) {
    if (densities[i] > densities[maxDensityIndex]) {
    maxDensityIndex = i;
    }
  }
  return data[maxDensityIndex];
  }


 这里我带宽(高斯核中的sigma)用了0.02,这个也是多次调试后的结果,如果过大会导致算出来的密度值更接近于全局平均值,过小的话会出现几个点集中在一起,但周围没有其他点的情况,我们还是拿上面两个异常的case看下核密度方法的效果。 首先就是成都哑铃型的数据。

image.png

再来就是北京的环形数据

image.png

 上面的图中,我使用了python中的sklearn来实现核密度,使用了folium来绘制地图,完整的代码也贴出来供大家参考。


# -*- coding: utf-8 -*-
import folium
import pandas as pd
from sklearn.neighbors import KernelDensity
import numpy as np
def getCenterPoint(sites):
    points = sites[['latitude', 'longitude']].values
    weights = sites['score'].values
    # 实例化KernelDensity对象
    kde = KernelDensity(kernel='gaussian', bandwidth=0.02)
    # 对数据进行拟合
    kde.fit(points) 
    # 使用KDE模型评估每个点的密度
    log_densities = kde.score_samples(points)
    # 密度最高的点是评估密度最高(即,log_densities值最大)的点
    highest_density_point = points[np.argmax(log_densities)]
    print(highest_density_point.tolist())
    return highest_density_point.tolist()
# 创建一个以给定经纬度为中心的地图,初始缩放级别设为14
m = folium.Map(zoom_start=14)
for i, s in data.iterrows():
    # 在地图上添加一个点标记
    folium.Marker(
        location=[s['latitude'], s['longitude']],  # 经纬度
        popup=s['resblock'], 
    ).add_to(m)
# 保存为html文件
centerPoint = getCenterPoint(cityDf)
folium.Marker(
    location=centerPoint,  # 经纬度
    popup='中心点',  # 弹出内容
    radius=50,
    icon=folium.Icon(color="red", icon="info-sign")
).add_to(m)
m.location = centerPoint
m.save('map.html')
目录
相关文章
|
移动开发 JavaScript 小程序
uniapp中组件库的Radio 单选框丰富的使用方法
uniapp中组件库的Radio 单选框丰富的使用方法
1859 0
|
人工智能 数据库管理 数据挖掘
「瑶池 Data Agent 入门训练营」火热进行中,参营可得棒球帽等多重好礼!
还在为数据报表熬夜?「瑶池Data Agent入门训练营」课程全部上线!7节实战课,教你一句话生成报告、分析问题根源、预测销售链路;定制AI助手,效率提升10倍。完成学习可获得阿里云结营证书,前100名还可赢取实物奖,2月28日正式结营!
「瑶池 Data Agent 入门训练营」火热进行中,参营可得棒球帽等多重好礼!
|
8月前
|
存储 安全 程序员
为什么已经删除的数据还能恢复?数据恢复的原理是什么?
删除数据并非彻底清除,而是标记为可覆盖,原内容仍暂存于存储设备中。只要未被新数据覆盖,通过专业软件即可恢复。本文详解其原理并推荐实用免费工具,支持硬盘、U盘、手机等多设备文件找回。
2064 0
|
人工智能 运维 云计算
全新无影,来了!
全新无影,来了!
|
监控 数据可视化 定位技术
2024年最强看板工具大对比:哪款最适合公司团建旅游活动策划?
本文介绍了5款看板工具(板栗看板、Trello、Asana、Monday.com、ClickUp)及其在公司团建旅游策划中的应用,通过具体案例展示了如何利用这些工具高效管理活动的各个环节,包括目的地规划、任务分配、预算管理、日程安排、团队沟通与反馈等,旨在提升团队协作效率和活动策划质量。
2024年最强看板工具大对比:哪款最适合公司团建旅游活动策划?
|
人工智能 算法 搜索推荐
CoAT: 基于蒙特卡洛树搜索和关联记忆的大模型推理能力优化框架
研究者提出了一种新的关联思维链(CoAT)方法,通过整合蒙特卡洛树搜索(MCTS)和关联记忆机制,提升大语言模型(LLMs)的推理能力。CoAT框架优化了MCTS算法,增强了结构化推理和动态知识整合,适用于复杂推理、多跳问答和代码生成等任务。实验结果显示,CoAT在精确匹配和F1分数上表现优异,超越了多个基线模型。然而,该方法在计算资源消耗和实时推理速度方面仍有改进空间。
1484 5
CoAT: 基于蒙特卡洛树搜索和关联记忆的大模型推理能力优化框架
|
运维 安全 网络安全
自动化运维:使用Python脚本实现批量部署
【8月更文挑战第2天】在现代IT基础设施管理中,自动化运维成为提升效率、减少人为错误的关键。本文将通过一个实际的Python脚本示例,展示如何实现服务器的批量部署,包括环境准备、代码实现及执行过程。文章旨在为运维工程师提供一种简化日常任务的方法,同时强调安全性和可维护性的重要性。
|
容灾 Cloud Native 关系型数据库
实现MySQL异地多活场景
现代化互联网企业面临的最大威胁是意外导致的数据丢失或不可用。为应对这一挑战,企业通常采用“主从高可用”架构,但单一机房内的高可用仍存风险。真正的高可用需通过“跨机房容灾”或“异地容灾”实现。异地容灾将服务器部署在不同地域的机房中,确保一处受灾时,其他机房能迅速接管业务。更进一步的“异地多活”方案则让各节点同步处理业务流量,确保数据一致性,提高资源利用率。NineData 提供了实现这一方案的强大工具。
672 0
|
监控 C++
深入理解 uni-app 页面生命周期(一):onLoad vs onShow
深入理解 uni-app 页面生命周期(一):onLoad vs onShow
2916 0