DBSCAN 基于密度的空间带噪聚类法
DBSCAN
(Density - Based Spatial Clustering of Applications with Noise)即基于密度的空间聚类算法,它是一种典型的密度聚类算法,以下从核心概念、算法步骤、优缺点及应用场景等方面进行解释。
核心概念
- 密度:密度是指在一个特定区域内数据点的数量。DBSCAN 算法使用一个半径参数 ϵ \epsilon ϵ来定义这个区域。在半径为的圆形区域内,数据点的数量就是该区域的密度。
- 核心点:如果一个数据点在其邻域内包含的数据点数量大于或等于某个阈值 m i n P t s minPts minPts,则该数据点被定义为核心点。核心点是密度聚类的关键,它们代表了高密度区域的中心。
- 边界点:边界点是指在其 ϵ \epsilon ϵ邻域内的数据点数量小于 m i n P t s minPts minPts,但该点落在某个核心点的邻域内。边界点位于高密度区域的边缘,它们依赖于核心点来确定所属的聚类。
- 噪声点:噪声点是指既不是核心点也不是边界点的数据点。这些点通常位于低密度区域,与任何高密度聚类都没有明显的关联,被视为数据中的噪声或异常值。
优缺点
优点
- 能发现任意形状的簇 ,DBSCAN 基于密度连接的概念来定义聚类,因此不受限于特定的聚类形状,能够识别出具有复杂形状和不规则边界的聚类。
- 无需事先知道要形成的簇类的数量,DBSCAN 算法通过数据点的密度分布自动识别聚类,用户只需要设置邻域半径和最小点数这两个参数,算法就能根据数据的实际情况确定聚类的数量。
- 能够识别出数据集中的噪声点,DBSCAN 算法将那些既不属于任何聚类的核心点,也不落在任何核心点的邻域内的数据点标记为噪声点。这种对噪声点的识别能力使得 DBSCAN 在处理包含噪声和异常值的数据集时表现出色。
缺点
- 对参数敏感,DBSCAN 算法的性能高度依赖于邻域半径 ϵ \epsilon ϵ和最小点数 m i n P t s minPts minPts这两个参数的选择。不同的参数设置可能会导致完全不同的聚类结果。
- 计算复杂度高,对于包含个数据点的数据集,DBSCAN 算法的时间复杂度通常为 O ( n 2 ) O(n^{2}) O(n2)。这是因为在算法的执行过程中,需要对每个数据点计算其与其他所有数据点之间的距离,以确定其邻域内的数据点数量。
示例
考虑要聚类的某个空间中的一组点。假设 ε ε ε 是一个参数,指定邻域相对于某个点的半径。为了 DBSCAN 聚类的目的,这些点被分类为核心点、(直接)可达点和异常值,如下所示:
- 点 p p p 是一个核心点,如果至少 m i n P t s = 4 minPts=4 minPts=4个点在它的距离 ε ε ε 内(包括 p p p)。
- 如果点 q q q 与核心点 p p p 在距离 ε ε ε 内,则点 q q q 可从 p p p 直接到达。点 q q q 只被称为可从核心点直接到达。
- 如果有 p 1 = p p_{1}=p p1=p 和 p n = q p_{n}=q pn=q 的路径 p 1 , … , p n p_{1},…,p_{n} p1,…,pn,其中每个 p i + 1 p_{i+1} pi+1 都可以从 p i p_{i} pi 直接到达,则可以从 p p p 到达点 q q q。请注意,这意味着初始点和路径上的所有点必须是核心点, q q q 可能除外。
- 从任何其他点无法到达的所有点都是异常值或噪声点。
如果 p p p 是一个核心点,那么它与所有可从它到达的点(核心或非核心)一起形成一个集群。每个集群至少包含一个核心点;非核心点可以是集群的一部分,但它们形成了集群的 “边缘”,因为它们不能用于到达更多的点。
在这个图中,
m
i
n
P
t
s
=
4
minPts=4
minPts=4。点
A
A
A 和其他红点是核心点,因为在
ε
ε
ε 半径内围绕这些点的区域至少包含 4 个点(包括点本身)。因为它们都是可以相互到达的,所以它们形成了一个集群。点
B
B
B 和
C
C
C 不是核心点,而是可以从
A
A
A(通过其他核心点)到达的,因此也属于集群。点
N
N
N 是一个噪声点,既不是核心点,也不是直接可到达的。
算法
DBSCAN 需要两个参数:
ε
(
e
p
s
)
ε(eps)
ε(eps) 和形成密集区域所需的最小点数
m
i
n
P
t
s
minPts
minPts。
从一个未被访问的任意起点开始。检索该点的
ε
ε
ε 邻域,如果它包含足够多的点,则启动一个集群。否则,该点被标记为噪声。请注意,该点稍后可能会在另一个点的足够大的
ε
ε
ε 环境中找到,因此成为集群的一部分。
如果一个点被发现是集群的稠密部分,它的 ε ε ε 邻域也是该集群的一部分。因此,在 ε ε ε 邻域中找到的所有点都被添加,当它们也是稠密时,它们自己的 ε ε ε 邻域也是如此。这个过程一直持续到完全找到密度连接的集群。然后,检索并处理一个新的未访问点,从而发现另一个集群或噪声。
DBSCAN 可以与任何距离函数(以及相似度函数或其他谓词)一起使用。因此,距离函数(distFunc)可以看作是一个附加参数。
该算法可以用伪代码表示如下:
DBSCAN(DB, distFunc, eps, minPts) {
C := 0 /* Cluster counter */
for each point P in database DB {
if label(P) ≠ undefined then continue /* Previously processed in inner loop */
Neighbors N := RangeQuery(DB, distFunc, P, eps) /* Find neighbors */
if |N| < minPts then { /* Density check */
label(P) := Noise /* Label as Noise */
continue
}
C := C + 1 /* next cluster label */
label(P) := C /* Label initial point */
SeedSet S := N \ {P} /* Neighbors to expand */
for each point Q in S { /* Process every seed point Q */
if label(Q) = Noise then label(Q) := C /* Change Noise to border point */
if label(Q) ≠ undefined then continue /* Previously processed (e.g., border point) */
label(Q) := C /* Label neighbor */
Neighbors N := RangeQuery(DB, distFunc, Q, eps) /* Find neighbors */
if |N| ≥ minPts then { /* Density check (if Q is a core point) */
S := S ∪ N /* Add new neighbors to seed set */
}
}
}
}
RangeQuery(DB, distFunc, Q, eps) {
Neighbors N := empty list
for each point P in database DB { /* Scan all points in the database */
if distFunc(Q, P) ≤ eps then { /* Compute distance and check epsilon */
N := N ∪ {P} /* Add to result */
}
}
return N
}
DBSCAN 算法可以抽象为以下步骤:
- 找到每个点的 ε ( e p s ) ε(eps) ε(eps)邻域中的点,并识别出邻域超过 m i n P t s minPts minPts 的核心点。
- 在邻接图上找到核心点的连通分支,忽略所有非核心点。
- 如果集群是 ε ( e p s ) ε(eps) ε(eps)邻居,则将每个非核心点分配给附近的集群,否则将其分配给噪声。
一个简单的实现需要在步骤 1 中存储邻域,因此需要大量内存。原始 DBSCAN 算法不需要通过一次执行一个点来执行这些步骤。
参数估计
对于 DBSCAN,需要参数 ε ε ε 和 m i n P t s minPts minPts。参数必须由用户指定。理想情况下, ε ε ε 的值由要解决的问题给出(例如物理距离), m i n P t s minPts minPts 是所需的最小集群大小。
-
m i n P t s minPts minPts:
根据经验,最小 m i n P t s minPts minPts 可以从数据集中的维数 D D D 中得出,即 m i n P t s ≥ D + 1 minPts≥D+1 minPts≥D+1。 m i n P t s = 1 minPts=1 minPts=1 的低值没有意义,因为根据定义,每个点都是一个核心点。对于 m i n P t s ≤ 2 minPts≤2 minPts≤2,结果将与使用单个链接度量的分层聚类相同,树状图在高度 ε ε ε 处切割。因此, m i n P t s minPts minPts必须选择至少 3 个点。然而,对于有噪声的数据集,较大的值通常更好,并且会产生更显着的聚类。根据经验,可以使用 m i n P t s = 2 ・ d i m minPts=2・dim minPts=2・dim,但对于非常大的数据、有噪声的数据或包含许多重复项的数据,可能有必要选择更大的值。 -
ε ε ε:可以使用
k-distance
图来选择 ε ε ε 的值,绘制到 k = m i n P t s − 1 k=minPts-1 k=minPts−1 最近邻的距离,从最大值到最小值排序。 ε ε ε 的好值是这个图显示 “弯头” 的地方:如果 ε ε ε 选择得太小,很大一部分数据将不会被聚类;而对于 ε ε ε的值太高,集群将合并,大多数对象将在同一个集群中。一般来说, ε ε ε 的小值更可取,根据经验,只有一小部分点应该在彼此的距离内。 -
距离函数:
距离函数的选择与 ε ε ε 的选择紧密耦合,对结果有重大影响。一般来说,在选择参数 ε ε ε 之前,有必要首先确定数据集的合理相似性度量。这个参数没有估计,但是需要为数据集适当地选择距离函数。
参考
- https://en.wikipedia.org/wiki/DBSCAN
- https://zhuanlan.zhihu.com/p/152453383