大家好,我是锋哥。最近连载更新《Scikit-learn Python机器学习》技术专题。 本课程主要讲解基于Scikit-learn的Python机器学习知识,包括机器学习概述,特征工程(数据集,特征抽取,特征预处理,特征降维等),分类算法(K-临近算法,朴素贝叶斯算法,决策树等),回归与聚类算法(线性回归,欠拟合,逻辑回归与二分类,K-means算法)等。 同时也配套视频教程《Scikit-learn Python机器学习 视频教程》
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,由Martin Ester、Hans-Peter Kriegel、Jörg Sander和Xiaowei Xu于1996年提出。与K-means等基于距离的聚类方法不同,DBSCAN能够发现任意形状的簇,并且能够识别出噪声点。
DBSCAN的基本概念
-
核心点(Core Point) :
- 如果某个点的ε邻域内(半径为ε的区域)包含至少
MinPts个点(包括该点本身),则该点被认为是核心点。
- 如果某个点的ε邻域内(半径为ε的区域)包含至少
-
边界点(Border Point) :
- 边界点是指不属于核心点,但位于某个核心点的ε邻域内的点。边界点的邻域内的点数小于
MinPts,因此不能形成核心点。
- 边界点是指不属于核心点,但位于某个核心点的ε邻域内的点。边界点的邻域内的点数小于
-
噪声点(Noise Point) :
- 如果一个点既不是核心点,也不在任何核心点的ε邻域内,它就是噪声点。噪声点不属于任何簇。
-
ε邻域(Epsilon Neighborhood) :
- 给定一个点
P和一个距离阈值ε,ε邻域指的是距离点P小于或等于ε的所有点组成的区域。
- 给定一个点
-
MinPts(最小邻域点数) :
MinPts是指一个点被认为是核心点所需的最小邻域点数。通常MinPts设置为数据维度的2倍或更大。
DBSCAN的工作原理
DBSCAN的聚类过程是通过以下几个步骤实现的:
-
选择一个未访问的点:从数据集中选择一个未被访问的点。
-
检查该点的ε邻域
:计算该点的ε邻域内包含的点的数量。
- 如果邻域内的点数大于或等于
MinPts,该点是核心点,算法开始扩展一个簇。所有位于该点的ε邻域内的点都将被加入到簇中。 - 如果邻域内的点数小于
MinPts,则该点是噪声点,暂时标记为噪声。
- 如果邻域内的点数大于或等于
-
扩展簇:对于核心点的邻域内的每个点,重复上述步骤。如果邻域内的某个点是核心点,则继续扩展簇。
-
继续此过程,直到所有点都被访问过。
DBSCAN的数学公式原理
DBSCAN的公式与计算距离、邻域和密度等概念紧密相关,关键公式如下:
DBSCAN的优缺点
优点:
- 能够发现任意形状的簇:不像K-means假设簇是圆形的,DBSCAN可以处理任意形状的簇。
- 自动识别噪声点:DBSCAN可以自动将噪声点标记出来,而不需要额外的操作。
- 不需要预设簇的数量:与K-means不同,DBSCAN不需要用户预设簇的数量。
缺点:
- 对参数敏感:DBSCAN依赖于
ε和MinPts的选择,尤其是ε的值,这可能影响聚类效果。 - 无法处理密度差异大的簇:如果数据集包含不同密度的簇,DBSCAN可能会失败。
- 高维数据的效果较差:在高维数据中,DBSCAN可能会因为稀疏性问题导致聚类结果不佳。
API介绍
在 sklearn 中,DBSCAN 的实现类是 sklearn.cluster.DBSCAN ,构造方法通常如下:
sklearn.cluster.DBSCAN(eps=0.5, min_samples=5, metric='euclidean', algorithm='auto', leaf_size=30, p=None, n_jobs=None)
核心参数介绍:
-
eps (default=0.5)
eps表示核心点邻域的最大半径。即,两个点的欧几里得距离如果小于eps,则认为它们是邻居。这个值决定了如何定义“密集区域”。eps越大,聚类结果越稀疏。 -
min_samples (default=5)
min_samples表示一个核心点的最小邻居数。若一个点的邻域中有min_samples个及以上点,它就会被认为是核心点。通常来说,min_samples应该设置为比数据维度更大的值,例如 4 或 5。 -
metric (default='euclidean') 这个参数定义了计算距离的方式,
'euclidean'是最常用的距离度量方式。你可以选择其他距离度量,例如'manhattan'、'cosine'等。 -
algorithm (default='auto')
algorithm用来指定在聚类过程中使用的算法。常见的有以下几种:'auto': 自动选择最合适的算法。'ball_tree': 使用球树算法,适合高维空间。'kd_tree': 使用k-d树算法,适合低维空间。'brute': 进行暴力搜索,计算所有点的距离,适合小规模数据。
-
leaf_size (default=30)
leaf_size仅在algorithm='ball_tree'或kd_tree'时有效。它影响构建树的数据结构的大小,较小的值可能会提高精度,但计算量较大;较大的值则可能提高效率。 -
p (default=None) 仅在
metric='minkowski'时有效。p是 Minkowski 距离的一个参数。当p=1时,表示曼哈顿距离;当p=2时,表示欧几里得距离。 -
n_jobs (default=None)
n_jobs表示使用多少个CPU核心进行并行计算。None表示不进行并行计算,-1表示使用所有CPU核心。
具体示例
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN
from sklearn.datasets import make_blobs
# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
# 生成生成高斯分布示例数据集
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)
# 使用DBSCAN进行聚类
db = DBSCAN(eps=0.5, min_samples=5)
y_db = db.fit_predict(X)
# 可视化结果
plt.figure(figsize=(8, 6))
plt.scatter(X[:, 0], X[:, 1], c=y_db, cmap='Paired', marker='o')
plt.title('DBSCAN 聚类结果')
plt.show()
解释:
make_blobs函数生成了一个包含4个簇的数据集。DBSCAN(eps=0.5, min_samples=5):设置ε=0.5(邻域半径)和MinPts=5(每个核心点的最小邻域点数)。fit_predict(X):应用DBSCAN聚类算法,并返回每个点的聚类标签。噪声点会被标记为-1。- 可视化图显示了聚类结果,簇的点会有不同的颜色,噪声点会显示为孤立点。
运行截图: