如何聚合地图上的点


 !密集恐惧症患者慎入 !


主要内容


  • 问题背景
  • 他山之石
  • 相关算法
  • 如何使用
  • 下一步 ...


问题背景


为啥要先聚合一下呢?
因为数据量大的时候体验差~

  • 点较多时,后端吐数多,网络传输速度慢
  • 前端绘制点多,页面响应慢,重绘、析构易出问题
  • 视觉效果差,密集恐惧症患者问你多大仇
  • 交互效果差,详情、联动不易使用
  • 其他变通方案,麻点图?鼓捣起来不是很有趣


他山之石


哪些产品值得寨一下

  • elong 的大地图
  • mafengwo 的区块
  • dealangel 的交互模式
  • booking 跨城市的显示


相关算法


都是数据挖掘基础知识
没有高大上的东西,但细节较多

  • kmeans ++
  • dbscan
  • optics
  • density peak

kmeans & kmeans ++

      kmeans —— since 1957:


  1. 从 D 中随机取 k 个元素,作为 k 个簇的中心
  2. 计算其他元素到 k 个簇中心的距离,根据距离做划分
  3. 重新计算 k 个簇各自的中心,计算方法是取平均数
  4. 将 D 中全部元素按照新的中心重新聚类
  5. 重复第 4 步,直到聚类结果不再变化

kmeans & kmeans  ++

kmeans & kmeans ++

      优点

  1. kmeans 经典、简单
  2. 复杂度为 O(nkt),n是点数,k是簇数,t是迭代次数。通常 k<<n。这个算法经常以局部最优结束
  3. 凸状数据表现良好

缺点

  1. 不适合于非凸状的簇,或者大小差别很大的簇
  2. 簇的数目 k 如何给出
  3. 对初值敏感,不同的初始值可能导致聚类结果差异大
  4. 对噪声敏感,少量的噪声能够对平均值产生极大影响

kmeans & kmeans ++


kmeans++ —— since 2007


如果不知道选几个 k,那就不同的 k 都算一下,选最优

k 个初始点随机选取,但依概率控制不能太近

特征正规化,计算过程中排除孤立的数据点

dbscan


dbscan


Density-Based Spatial Clustering of Applications with Noise

一个比较有代表性的基于密度的聚类算法
它将簇定义为密度相连的点的最大集合
能够把具有足够高密度的区域划分为簇
并可在噪声的空间数据库中发现任意形状的聚类


正好符合地图上点聚合的原始想法
我们恰好也是在找『哪儿块比较密』

dbscan


算法思想
哪儿比较密?哪些密集点能连成一片 

两个变量:多大的半径(eps) 区域中至少包含多少个点(minPts) 可被视为『密集』

几个概念:核心对象、直接密度可达、密度可达、密度相连


过程

算法可从任意点出发,它在出发点的距离 eps 之内发现所有附近点

  如果附近点的数量 >= minPts,群被形成。 出发点和它的邻居增加到这群,并且出发点被标记为visited。 然后递归评估所有未被标记为visited的该群成员,从而对群进行扩展。

  如果邻居的数量比minPts少,则该点暂时被标记作为噪声。

  如果群充分地被扩展(群内的所有点被标记为visited),然后重复地去处理unvisited点

dbscan


不好理解吗?

就是求一个数据集内密度相连的最大集,有啥不好理解的O(∩_∩)O~

可以联想一下:

火灾是如何产生的
感冒是如何传播的

dbscan


广告时间

Life is short, you need Python -- Bruce Eckel

机器学习实验田

dbscan

核心代码
 def cluster(points, eps=EPS, min_samples=MIN_SAMPLES):
    X = np.array(points)
    #X = StandardScaler().fit_transform(X)

    db = DBSCAN(eps=eps, min_samples=min_samples).fit(X)

    labels = db.labels_
    core_mask = np.zeros_like(labels, dtype=bool)
    core_mask[db.core_sample_indices_] = True

    return labels, core_mask

dbscan

optics


dbscan 很牛吗?
dbscan 参数:多大的半径(eps) 区域中至少包含多少个点(minPts) 可被视为『密集』
你来告诉我,北京是多大面积内有多少个饭店,可视为『饭店密集区』

好,我们可以这样:
 def get_params(delta_lat, delta_lng, count, n=400, k=1.5):
    area = delta_lat * delta_lng

    if count < n:
        n = count + 1  # 防止 count 为 0 出错

    eps = max(math.sqrt((area / n) / math.pi), 0.0015)
    min_samples = max(math.ceil(k * count / n), 4)

    return eps, min_samples


optics


optics

一个例子击溃 dbscan

optics


dbscan 搞不定数据集内有多种密度分布
该轮到 optics 出场了~

  • optics : ordering point to identify the cluster structure
  • 算法不显示地产生数据聚类,它只是对数据对象集中的对象进行调序,输出一个有序的对象列表(cluster-ordering)
  • cluster-ordering 包含了足够的信息用来提取聚类
  • 和 dbscan,optics 最大优点是对输入参数不敏感

optics


optics


optics

没什么给力的库,sklearn 中的 optics 还在 pull request 中
只能自己动手,200+ 行

optics 中的精髓在于自动抽取聚合结构(尚未看到实现)

optics


density peak


直到几个星期之前

density peak


density peak


算法简单,超级容易实现

关键实现语焉不详

一帮人在跟,作者招架不过来

主要是发表在 science 上~

gotcha


  • 数据挖掘(聚类)基础知识
  • 复习了概率统计
  • 复习 & 学习若干数据结构、算法
  • 又一次使用 python 科学计算、机器学习库
  • 难得地看 paper,写实现
  • 学习了 geo 知识
  • 鼓捣了 postgis、geojson
  • 学习了数据可视化
  • 学习了百度地图 api
  • 参考了若干地图产品

finally



next steps ...


效果优化,能够适配我们的坐标数据

地图产品上对用户产生有用的交互效果

离线数据可运营,可产生指导意义

性能优化,不拖前端后退






Questions ?




Thank you !

point-cluster-algorithms-in-map

By songchao

point-cluster-algorithms-in-map

如何聚合地图上的点

  • 1,343