**
算法思想 干货分享
**
DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪声的基于密度的聚类方法)是一种典型的基于密度的空间聚类算法。和K-Means,BIRCH这些一般只适用于凸样本集的聚类相比,DBSCAN既可以适用于凸样本集,也可以适用于非凸样本集。同时,DBSCAN能够基于数据密度自动确定簇的数量,找出异常点,也不需要预先指定簇的数量。DBSCAN算法的显著优点是聚类速度快且能够有效处理噪声点和发现任意形状的空间聚类。该算法不适合处理有不同密度的簇以及一些高维的数据,尤其当空间聚类的密度不均匀、聚类间距差相差很大时,聚类质量较差。
由于其能够有效地识别地理数据中的空间聚类与异常噪点,DBSCAN聚类算法已经在地理分析中得到了广泛应用,例如识别地理空间上的相关性,聚集性与分布趋势,用以分析城市中的人口密度分布情况;通过热点检测来寻找人口聚集,病毒高传播风险的热点区域;帮助识别提取出地理数据中的自然边界或区域边界等等。
DBSCAN是基于一组邻域来描述样本集的紧密程度的,参数(ϵ, MinPts)用来描述邻域的样本分布紧密程度。其中,ϵ描述了某一样本的邻域距离阈值,MinPts描述了某一样本的距离为ϵ的邻域中样本个数的阈值。
假设样本集是D=(x1,x2,…,xm),则DBSCAN具体的密度描述如下:
1) ϵ-邻域:对于xj∈D,其ϵ-邻域包含样本集D中与xj的距离不大于ϵ的子样本集,即Nϵ(xj)={xi∈D|distance(xi,xj)≤ϵ}, 这个子样本集的个数记为|Nϵ(xj)|。
- 核心对象:对于任一样本xj∈D,如果其ϵ-邻域对应的Nϵ(xj)至少包含MinPts个样本,即如果|Nϵ(xj)|≥MinPts,则xj是核心对象。
3)密度直达:如果xi位于xj的ϵ-邻域中,且xj是核心对象,则称xi由xj密度直达。注意反之不一定成立,即此时不能说xj由xi密度直达, 除非且xi也是核心对象。
4)密度可达:对于xi和xj,如果存在样本样本序列p1,p2,…,pT,满足p1=xi,pT=xj, 且pt+1由pt密度直达,则称xj由xi密度可达。也就是说,密度可达满足传递性。此时序列中的传递样本p1,p2,…,pT−1均为核心对象,因为只有核心对象才能使其他样本密度直达。注意密度可达也不满足对称性,这个可以由密度直达的不对称性得出。
5)密度相连:对于xi和xj,如果存在核心对象样本xk,使xi和xj均由xk密度可达,则称xi和xj密度相连。注意密度相连关系是满足对称性的。
从下图可以很容易看出理解上述定义,图中MinPts=5,红色的点都是核心对象,因为其ϵ-邻域至少有5个样本。黑色的样本是非核心对象。所有核心对象密度直达的样本在以红色核心对象为中心的超球体内,如果不在超球体内,则不能密度直达。图中用绿色箭头连起来的核心对象组成了密度可达的样本序列。在这些密度可达的样本序列的ϵ-邻域内所有的样本相互都是密度相连的。
聚类过程: 由密度可达关系导出的最大密度相连的样本集合,即为我们最终聚类的一个类别,或者说一个簇。每个簇里面可以有一个或者多个核心对象。如果只有一个核心对象,则簇里其他的非核心对象样本都在这个核心对象的ϵ-邻域里;如果有多个核心对象,则簇里的任意一个核心对象的ϵ-邻域中一定有一个其他的核心对象,否则这两个核心对象无法密度可达。这些核心对象的ϵ-邻域里所有的样本的集合组成的一个DBSCAN聚类簇。那么怎么才能找到这样的簇样本集合呢?DBSCAN使用的方法很简单,它任意选择一个没有类别的核心对象作为种子,然后找到所有这个核心对象能够密度可达的样本集合,即为一个聚类簇。接着继续选择另一个没有类别的核心对象去寻找密度可达的样本集合,这样就得到另一个聚类簇。一直运行到所有核心对象都有类别为止。
算法实现 干货分享
import numpy as np
import matplotlib.pyplot as plt
def euclidean_distance(p1, p2):
return np.sqrt(np.sum((p1 - p2) ** 2))
def neighbors(data, point_idx, eps):
"""返回所有在eps距离之内的点的索引"""
return [i for i in range(len(data)) if euclidean_distance(data[point_idx], data[i]) < eps]
def dbscan(data, eps, min_samples):
labels = [-1] * len(data) # 初始化所有点的标签为 -1 (未分类)
cluster_id = 0
for i in range(len(data)):
if labels[i] != -1: # 如果已经归为某个簇则跳过
continue
# 找到点i的所有邻居
nbrs = neighbors(data, i, eps)
# 对于密度不足的点标记为噪声点
if len(nbrs) < min_samples:
labels[i] = -1
continue
# 处理新的聚类
labels[i] = cluster_id
j = 0
while j < len(nbrs):
nbr = nbrs[j]
if labels[nbr] == -1: # 将噪声点添加到当前聚类
labels[nbr] = cluster_id
elif labels[nbr] == -1: # 扩展新的聚类
labels[nbr] = cluster_id
new_nbrs = neighbors(data, nbr, eps)
if len(new_nbrs) >= min_samples:
nbrs += new_nbrs
j += 1
cluster_id += 1
return labels
# 示例数据
data = np.array([[1, 2],
[5, 6],
[1, 1],
[5, 7],
[1, 1.5],
[5, 5],
[10, 10],
[11, 11],
[10, 11],
[11, 10]])
# 调用手写的dbscan函数
labels = dbscan(data, eps=1.5, min_samples=2)
# 可视化结果
plt.scatter(data[:, 0], data[:, 1], c=labels)
plt.title("Handwritten DBSCAN Spatial Clustering")
plt.show()
在ArcGIS Pro中的应用
干货分享
打开基于密度的聚类工具,添加待聚类点要素,选择方法为DBSCAN,输入最小要素数。
下图中展示了对一系列点要素的聚类结果,其中,第一张图为原始散点,第二张图为聚类结果,灰色为异常噪点。
题外话
当下这个大数据时代不掌握一门编程语言怎么跟的上脚本呢?当下最火的编程语言Python前景一片光明!如果你也想跟上时代提升自己那么请看一下.
感兴趣的小伙伴,赠送全套Python学习资料,包含面试题、简历资料等具体看下方。
一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python必备开发工具
工具都帮大家整理好了,安装就可直接上手!
三、最新Python学习笔记
当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
四、Python视频合集
观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
五、实战案例
纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
六、面试宝典