《机器学习》之DBSCAN聚类
目录
一、简介
二、DBSCAN的核心概念
1. 核心点(Core Point)
2. E领域(Epsilon Neighborhood)
3. 直接密度可达(Directly Density-Reachable)
4. 边界点(Border Point)
5. 离群点(Noise Point 或 Outlier)
6、核心概念之间的关系
三、DBSCAN实现步骤
1、参数设置:
2、初始化:
3、遍历数据点:
编辑四、DBSCAN聚类优缺点
1、优点
2、缺点
五、DBSCAN聚类代码实现
1、API接口介绍
参数介绍:
属性介绍:
2、代码示例
结果展示:
编辑
六、总结
一、简介
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是基于密度的带噪声的空间聚类应用算法,它是将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域 划分为簇,并在噪声的空间数据集中发现任意形状的聚类。
二、DBSCAN的核心概念
1. 核心点(Core Point)
-
定义:
如果一个数据点在半径 ϵ 内的邻居数量(包括自身)至少为 MinPts(一个预设的最小点数),则该点称为核心点。 -
意义:
核心点是簇的基础,它们通过密度连接形成簇的主体。
2. E领域(Epsilon Neighborhood)
-
定义:
给定一个数据点 p 和半径 ϵ,p的 E 领域是指所有与 p 的距离不超过 ϵ 的数据点的集合。 -
公式:
其中,D 是数据集,dist(p,q) 是点 p 和点 q 之间的距离(通常为欧几里得距离)。
-
意义:
E 领域用于衡量数据点的局部密度。
3. 直接密度可达(Directly Density-Reachable)
-
定义:
如果点 q 在点 p 的 E 领域内,且 p 是核心点,则称 q 从 p 直接密度可达。 -
意义:
直接密度可达是密度连接的基础,用于构建簇。
4. 边界点(Border Point)
-
定义:
如果一个点不是核心点,但它在某个核心点的 E 领域内,则该点称为边界点。 -
意义:
边界点属于某个簇,但不是簇的核心部分。
5. 离群点(Noise Point 或 Outlier)
-
定义:
既不是核心点,也不是边界点的点称为离群点(噪声点)。 -
意义:
离群点被认为是数据中的噪声,不属于任何簇。
6、核心概念之间的关系
-
核心点是簇的基础,通过直接密度可达关系将其他点(核心点或边界点)连接到簇中。
-
边界点依赖于核心点,它们本身不足以扩展簇。
-
离群点是数据中的噪声,与任何簇无关。
三、DBSCAN实现步骤
1、参数设置:
- 设置半径 ϵ 和最小点数 MinPts。
2、初始化:
- 将所有数据点标记为未访问(unvisited)。
3、遍历数据点:
- 对于每个未访问的点 pp:
- 标记 pp 为已访问。
- 查找 pp 的 ϵϵ-邻域内的所有邻居点。
- 如果邻居点数量小于 MinPtsMinPts,将 pp 标记为噪声点。
- 否则:
- 创建一个新簇,并将 pp 加入该簇。
- 递归地将 pp 的所有密度可达点加入该簇。
- 输出结果:
- 返回所有簇和噪声点。
四、DBSCAN聚类优缺点
1、优点
-
无需指定簇数量:
自动发现簇的数量,适合未知结构的数据集。 -
处理噪声:
能够识别并排除噪声点,增强聚类结果的鲁棒性。 -
发现任意形状簇:
适用于非凸形簇和复杂分布的数据。 -
对初始值不敏感:
不依赖初始值,结果稳定。
2、缺点
-
参数敏感:
半径 ϵϵ 和 MinPtsMinPts 的选择对结果影响较大。 -
高维数据效果差:
在高维空间中,密度定义变得模糊,聚类效果下降。 -
对密度变化敏感:
难以处理密度差异较大的数据集。
五、DBSCAN聚类代码实现
1、API接口介绍
class sklearn.cluster.DBSCAN(eps=0.5, min_samples=5,
metric=’euclidean’, metric_params=None,
algorithm=’auto’, leaf_size=30, p=None, n_jobs=None)
参数介绍:
- eps: DBSCAN算法参数,即我们的ϵϵ-邻域的距离阈值,和样本距离超过ϵϵ的样本点不在ϵϵ-邻域内。默认值是0.5.一般需要通过在多组值里面选择一个合适的阈值。eps过大,则更多的点会落在核心对象的ϵϵ-邻域,此时我们的类别数可能会减少, 本来不应该是一类的样本也会被划为一类。反之则类别数可能会增大,本来是一类的样本却被划分开。
-
min_samples: DBSCAN算法参数,即样本点要成为核心对象所需要的ϵϵ-邻域的样本数阈值。默认值是5. 一般需要通过在多组值里面选择一个合适的阈值。通常和eps一起调参。在eps一定的情况下,min_samples过大,则核心对象会过少,此时簇内部分本来是一类的样本可能会被标为噪音点,类别数也会变多。反之min_samples过小的话,则会产生大量的核心对象,可能会导致类别数过少。
-
metric:最近邻距离度量参数。可以使用的距离度量较多,一般来说DBSCAN使用默认的欧式距离(即p=2的闵可夫斯基距离)就可以满足我们的需求。可以使用的距离度量参数有:
a) 欧式距离 “euclidean”:
b) 曼哈顿距离 “manhattan”
c) 切比雪夫距离“chebyshev”
…
-
algorithm:最近邻搜索算法参数,算法一共有三种,第一种是蛮力实现,第二种是KD树实现,第三种是球树实现。对于这个参数,一共有4种可选输入,‘brute’对应第一种蛮力实现,‘kd_tree’对应第二种KD树实现,‘ball_tree’对应第三种的球树实现, ‘auto’则会在上面三种算法中做权衡,选择一个拟合最好的最优算法。需要注意的是,如果输入样本特征是稀疏的时候,无论我们选择哪种算法,最后scikit-learn都会去用蛮力实现‘brute’。个人的经验,一般情况使用默认的 ‘auto’就够了。 如果数据量很大或者特征也很多,用"auto"建树时间可能会很长,效率不高,建议选择KD树实现‘kd_tree’,此时如果发现‘kd_tree’速度比较慢或者已经知道样本分布不是很均匀时,可以尝试用‘ball_tree’。而如果输入样本是稀疏的,无论你选择哪个算法最后实际运行的都是‘brute’。
-
p: 最近邻距离度量参数。只用于闵可夫斯基距离和带权重闵可夫斯基距离中p值的选择,p=1为曼哈顿距离, p=2为欧式距离。如果使用默认的欧式距离不需要管这个参数。
属性介绍:
-
Labels_:每个点的分类标签。
2、代码示例
import pandas as pd
from sklearn.cluster import DBSCAN
from sklearn import metrics
# 数据预处理
beer = pd.read_table(r'../data/beer.txt',sep=' ',encoding='utf-8',engine='python')
x = beer[["calories","sodium","alcohol","cost"]]
db = DBSCAN(eps=20,min_samples=2).fit(x)
labels = db.labels_
beer['cluster_db'] = labels
beer.sort_values('cluster_db')
# 轮廓系数
score = metrics.silhouette_score(x,beer.cluster_db)
print('DBSCAN:',score,sep='\n')
结果展示:
六、总结
DBSCAN是一种强大的密度聚类算法,能够发现任意形状的簇并有效处理噪声点。尽管对参数选择敏感,但在许多实际场景中(如异常检测、空间数据分析),DBSCAN表现优异。通过合理调整参数,可以充分发挥其优势,解决复杂的聚类问题。