赞
踩
DBSCAN 是一种著名的密度聚类算法,它基于一组“邻域”(neighborhood)参数(ε,MinPts)来刻画样本分布的紧密程度.给定数据集D={},
DBSCAN定义的基本概念(MinPts = 3):虚线显示出ε-邻域, 是核心对象,
由
密度直达,
由
密度可达,
与
密度相连.由上图我们可以直观地理解概念
基于这些概念,DBSCAN将“簇”定义为: 由密度可达关系导出的最大的密度相连样本集合.形式化地说,给定邻域参数(ε, MinPts),簇∈
是满足以下性质的非空样本子集:
连接性(connectivity ): ∈
,
∈
与
密度相连
最大性(maximality): ∈
,
由
密度可达
∈
那么,如何从数据集D中找出满足以上性质的聚类簇呢?实际上,若为核心对象,由
密度可达的所有样本组成的集合记为
= {
∈
由
密度可达},则不难证明
即为满足连接性与最大性的簇.
于是,DBSCAN算法先任选数据集中的一个核心对象为“种子”(seed),再由此出发确定相应的聚类簇,算法描述如图下图所示.在第1~7行中,算法先根据给定的邻域参数(ε, MinPts)找出所有核心对象;然后在第10~24行中,以任一核心对象为出发点,找出由其密度可达的样本生成聚类簇,直到所有核心对象均被访问过为止.
Visualizing DBSCAN Clustering (naftaliharris.com)
通过这个网站,我们可以直观地看到DBSCAN的聚类过程
某个样本可能到两个核心对象的距离都小于Eps,但是这两个核心对象由于不是密度直达,又不属于同一个聚类簇,那么如果界定这个样本的类别呢?如图这个蓝点该分给哪个簇呢?
一般来说,此时DBSCAN采用先来后到,先进行聚类的类别簇会标记这个样本为它的类别。也就是说BDSCAN的算法不是完全稳定的算法。
次代码没有根据上述伪代码编写
- import numpy as np
- import matplotlib.pyplot as plt
-
- def distance(x, y):
- return np.linalg.norm(x - y)
-
- def find_neighbors(center, eps, data):
- """
- 找出中心点的邻近点
- :param center: 中心点
- :param eps: 半径
- :param data: 数据集
- :return: 返回邻近点在data的索引
- """
- neighbors = []
- N, D = data.shape
- for i in range(N):
- if distance(center, data[i,:]) < eps:
- neighbors.append(i)
- return neighbors
-
- def DBscan(data, eps, min_samples):
- N, D = data.shape
- labels = np.full(N, -1) # 默认为-1噪声点
- cluster = 0
- for i in range(N):
- if labels[i] != -1: # 判断是否已经分类,是则遍历下一个
- continue
- # 该索引点的邻域点
- neighbors = find_neighbors(data[i,:], eps, data)
- # 邻域点为1则表示为噪声点,直接下一个
- if len(neighbors) == 1:
- continue
- # 判断是否为核心点,是则执行拓展聚类
- elif len(neighbors) >= min_samples:
- labels[i] = cluster
- expand_cluster(data, labels, neighbors, eps, min_samples, cluster)
- cluster += 1
- return labels
-
- def expand_cluster(data, labels, neighbors, eps, min_samples, cluster):
- for neib_index in neighbors:
- if labels[neib_index] == -1:
- labels[neib_index] = cluster
- nerb_nerbs = find_neighbors(data[neib_index,:], eps, data)
- if len(nerb_nerbs) >= min_samples:
- neighbors.extend(nerb_nerbs)
'运行
训练数据:
- data = np.loadtxt(r"data\Aggregation.txt") # 导入数据
- # 设置参数
- eps = 1.5
- min_samples = 5
- labels = DBscan(data, eps, min_samples)
我们可以看到,当eps、min_samples的值过大、过小都会对聚类结果造成影响
一种常用的方法是通过可视化数据分布和密度来选择邻域半径。可以绘制数据点的散点图,并根据数据点之间的距离来选择合适的邻域半径。可以尝试不同的邻域半径值,观察聚类结果的质量,选择能够较好地将数据点划分为不同聚类的邻域半径。
尽管DBSCAN算法在密度聚类中具有很多优点,但它也存在一些限制和挑战。下面是一些可能的改进方法,可以进一步提升DBSCAN算法的性能和适用性:
这些改进方法只是对DBSCAN算法进行优化的一部分,具体的改进方法取决于应用场景和需求。通过结合领域知识和实际问题的特点,可以选择适合的改进方法来提升DBSCAN算法的性能和适用性。
部分参考 周志华《机器学习》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。