如何聚合地图上的点
!密集恐惧症患者慎入 !
主要内容
- 问题背景
- 他山之石
- 相关算法
- 如何使用
- 下一步 ...
问题背景
为啥要先聚合一下呢?
因为数据量大的时候体验差~
- 点较多时,后端吐数多,网络传输速度慢
- 前端绘制点多,页面响应慢,重绘、析构易出问题
- 视觉效果差,密集恐惧症患者问你多大仇
- 交互效果差,详情、联动不易使用
- 其他变通方案,麻点图?鼓捣起来不是很有趣
他山之石
哪些产品值得寨一下
-
elong 的大地图
- mafengwo 的区块
- dealangel 的交互模式
- booking 跨城市的显示
相关算法
都是数据挖掘基础知识
没有高大上的东西,但细节较多
- kmeans ++
- dbscan
- optics
- density peak
kmeans & kmeans ++
kmeans —— since 1957:
-
从 D 中随机取 k 个元素,作为 k 个簇的中心
- 计算其他元素到 k 个簇中心的距离,根据距离做划分
- 重新计算 k 个簇各自的中心,计算方法是取平均数
- 将 D 中全部元素按照新的中心重新聚类
- 重复第 4 步,直到聚类结果不再变化
kmeans & kmeans ++
kmeans & kmeans ++
优点
-
kmeans 经典、简单
- 复杂度为 O(nkt),n是点数,k是簇数,t是迭代次数。通常 k<<n。这个算法经常以局部最优结束
- 凸状数据表现良好
缺点
-
不适合于非凸状的簇,或者大小差别很大的簇
-
簇的数目 k 如何给出
-
对初值敏感,不同的初始值可能导致聚类结果差异大
-
对噪声敏感,少量的噪声能够对平均值产生极大影响
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