当前位置: 首页 > news >正文

DBSCAN 密度聚类分析算法

1. DBSCAN 算法简介


DBSCAN 是一种基于密度的聚类算法,旨在发现任意形状的,并且对噪声点outliers)具有鲁棒性。

DBSCAN 通过在数据空间中找到高密度区域,将这些区域作为簇,同时把孤立点(密度低的点)归为噪声

DBSCAN 的基本思想是:

  • 在某个点的邻域半径ϵ\epsilonϵepsilon)内,如果有足够多的点(超过一个阈值 minPts),就认为这个区域是一个高密度区域,可以扩展成一个簇。
  • 一个簇通过密度相连(density-connected)的点进行扩展。
  • 无法归属于任何簇的点被认为是噪声点。

可以前往 DBSCAN 数据可视化网站来了解执行的流程。

在这里插入图片描述

2. DBSCAN 的基本概念


  • ϵ\epsilonϵ-邻域(Epsilon-neighborhood)
    对于某个点 PPP,以半径 ϵ\epsilonϵ 为边界的区域内所有的点称为该点的 ϵ\epsilonϵ 邻域。
  • 核心点Core Point
    如果一个点 PPPϵ\epsilonϵ 邻域内至少有 minPts 个点(包括 PPP 自己),那么它被称为核心点。
  • 边界点Border Point
    如果一个点 PPP 在某个核心的 ϵ\epsilonϵ 邻域内,但自身不是核心点,它被称为边界点。
  • 噪声点Noise Point
    如果一个点既不是核心点,也不属于任何核心点的领域,它被认为是噪声点。
  • 密度直达Directly Density-Reachable
    如果点 PPP 是核心点,并且点 QQQPPPϵ\epsilonϵ 邻域内,那么 QQQ 被称为 PPP 的密度直达。
  • 密度可达Density-Reachable
    如果存在一条核心点链表(P1→P2→...→PnP_1 \rightarrow P_2 \rightarrow ... \rightarrow P_nP1P2...Pn),使得每个点从前一个点密度直达,且 P1=PP_1=PP1=PPn=QP_n=QPn=Q,则 Q 是从 P 密度可达的。
  • 密度相连Density-Connected
    如果存在一个点 OOO,使得 PPPQQQ 都从 OOO 密度可达,则称 PPPQQQ 是密度相连的。

3. DBSCAN 算法步骤


  • 初始化
    从数据集中任意选择一个点 PPP,判断它是否为核心点(即 ϵ\epsilonϵ 邻域内是否包含至少 minPts 个点)。
  • 扩展簇
    如果 PPP 是核心点,则开始一个新簇,将 PPP 及其邻域中的点加入簇中,并不断对新的核心点的邻域进行扩展。
  • 处理噪声点
    如果一个点既不在任何簇中,也不满足成为核心点的条件,则将其标记为噪声点。
  • 重复处理
    继续检查所有未访问的点,直到所有点都被访问为止。

4. DBSCAN 伪代码


DBSCAN(D, epsilon, minPts):C = 0   # 初始化簇标签for each unvisited point P in dataset D:mark P as visitedNeighbors = getNeighbors(P, epsilon)    # 获取邻域内的所有点if size(Neighbors) < minPts:mark P as NOISE # 认为该点是噪声else:C = C + 1   # 创建新簇expandCluster(P, Neighbors, C, epsilon, minPts)expandCluster(P, Neighbors, C, epsilon, minPts):add P to cluster Cfor each point Q in Neighbors:if Q is not visited:mark Q as visitedNeighborsQ = getNeighbors(Q, epsilon)if size(NeighborsQ) >= minPts:Neighbors = Neighbors U NeighborsQ  # 扩展簇if Q is not yet assigned to any cluster:add Q to cluster C

5. DBSCAN 的时间复杂度分析


  • 邻域查询:在每次扩展时,需要查找一个点的 ϵ\epsilonϵ 邻域。如果使用 KD-Tree 或 Ball-Tree 等空间索引结构,这个操作的复杂度为 O(log⁡n)O(\log n)O(logn)
  • 总体复杂度:如果对每个点进行邻域查询,算法的时间复杂度为 O(n⋅log⁡n)O(n·\log n)O(nlogn)。如果不使用索引结构,最坏情况下是 O(n2)O(n^2)O(n2)

6. DBSCAN 的 Python 实现


方法一:使用 scikit-learn

在这里插入图片描述

聚类代码如下

from sklearn.cluster import DBSCAN
import numpy as np# 生成示例数据
X = np.array([[1, 2], [2, 2], [2, 3],[8, 7], [8, 8], [25, 80]])# 初始化 DBSCAN 模型
db = DBSCAN(eps=3, min_samples=2).fit(X)# 获取聚类标签
labels = db.labels_print("Cluster labels:", labels)

输出:

Cluster labels: [ 0 0 0 1 1 -1]

其中:

  • 标签为 -1 的点表示噪声点
  • 其他标签表示该点属于的

方法二:手动实现

import numpy as np
from sklearn.metrics import pairwise_distancesclass DBSCAN:def __init__(self, eps=1.0, min_samples=5):self.eps = epsself.min_samples = min_samplesdef fit(self, X):# 计算所有点之间的距离矩阵distances = pairwise_distances(X)# 初始化标签:0表示未访问,-1表示噪声labels = np.zeros(X.shape[0], dtype=int)cluster_id = 0for i in range(X.shape[0]):if labels[i] != 0:  # 已访问过的点跳过continue# 找到当前点的所有邻居neighbors = self._find_neighbors(i, distances)if len(neighbors) < self.min_samples:labels[i] = -1  # 标记为噪声else:cluster_id += 1self._expand_cluster(i, neighbors, labels, cluster_id, distances)self.labels_ = labelsreturn selfdef _find_neighbors(self, point_idx, distances):"""找到给定点的所有ε-邻域内的邻居"""return np.where(distances[point_idx] <= self.eps)[0]def _expand_cluster(self, point_idx, neighbors, labels, cluster_id, distances):"""从核心点扩展聚类"""labels[point_idx] = cluster_idi = 0while i < len(neighbors):current_point = neighbors[i]if labels[current_point] == -1:  # 如果是噪声,改为边界点labels[current_point] = cluster_idelif labels[current_point] == 0:  # 如果是未访问点labels[current_point] = cluster_id# 找到当前点的所有邻居current_neighbors = self._find_neighbors(current_point, distances)if len(current_neighbors) >= self.min_samples:# 将新邻居加入列表(合并邻居)neighbors = np.concatenate([neighbors, current_neighbors])i += 1# 测试代码
if __name__ == "__main__":# 使用你提供的示例数据X = np.array([[1, 2], [2, 2], [2, 3], [8, 7], [8, 8], [25, 80]])# 创建并运行DBSCANdbscan = DBSCAN(eps=3, min_samples=2)dbscan.fit(X)# 打印结果print("聚类结果:", dbscan.labels_)# 可视化结果import matplotlib.pyplot as pltplt.figure(figsize=(10, 6))colors = ['red', 'blue', 'green', 'purple', 'orange']for i in range(len(X)):if dbscan.labels_[i] == -1:plt.scatter(X[i, 0], X[i, 1], c='black', marker='x', s=100, label='Noise' if i == 0 else "")else:plt.scatter(X[i, 0], X[i, 1], c=colors[dbscan.labels_[i] - 1], label=f'Cluster {dbscan.labels_[i]}' if i == 0 or dbscan.labels_[i] != dbscan.labels_[i-1] else "")plt.title('DBSCAN Clustering Result')plt.xlabel('X coordinate')plt.ylabel('Y coordinate')plt.legend()plt.grid(True)plt.show()

7. DBSCAN 的优缺点


  • 优点:
    • 可以发现任意形状的簇。
    • 不需要预先指定簇的数量。
    • 对噪声有鲁棒性。
  • 缺点
    • 当簇的密度差异较大时,效果不佳。
    • 高维数据(超过 10 维)中的性能较差,非常消耗 CPU 和 GPU 以及内存性能。
    • 需要合理选择 ϵ\epsilonϵ 和 minPts 参数。

文章转载自:

http://9n7UErJq.bkjhx.cn
http://BWUMHvL7.bkjhx.cn
http://wofufEIL.bkjhx.cn
http://arZP4u4N.bkjhx.cn
http://EIQamJi6.bkjhx.cn
http://HmEQm9fC.bkjhx.cn
http://9w3KxctR.bkjhx.cn
http://VR6Fjb0F.bkjhx.cn
http://rHavVdMp.bkjhx.cn
http://lGKgHWIi.bkjhx.cn
http://U2EwE511.bkjhx.cn
http://Fdtt2mBU.bkjhx.cn
http://VBzFpVJp.bkjhx.cn
http://qoeRprOr.bkjhx.cn
http://WsZS0CNu.bkjhx.cn
http://nj1SHnyo.bkjhx.cn
http://W9da76Yn.bkjhx.cn
http://hMjgcnUt.bkjhx.cn
http://ekNKsuoq.bkjhx.cn
http://kkYVYDcs.bkjhx.cn
http://hlHmaW6x.bkjhx.cn
http://UXIN207a.bkjhx.cn
http://YrzDEzrN.bkjhx.cn
http://qy0DhlRr.bkjhx.cn
http://nzyEHAnf.bkjhx.cn
http://hySamL8x.bkjhx.cn
http://Ct12a2kp.bkjhx.cn
http://8lYBpIcb.bkjhx.cn
http://h2NTl0cp.bkjhx.cn
http://dOYsWVB4.bkjhx.cn
http://www.dtcms.com/a/364464.html

相关文章:

  • 第二章:技术基石:写出“活”的代码(2)
  • DVWA靶场通关笔记-存储型XSS(Stored Impossible级别)
  • K8s Pod CrashLoopBackOff:从镜像构建到探针配置的排查过程
  • AI Agent重构SOC:下一代智能安全运营平台的能力跃迁
  • 解析SWOT分析和PV/UV这两个在产品与运营领域至关重要的知识点。
  • 【LeetCode 热题 100】72. 编辑距离——(解法一)记忆化搜索
  • 【LM358AD差分检测电压差】2022-11-30
  • 刻意练习理论
  • C++ 多线程编程
  • 【IO】进程间通信(IPC)练习
  • CAD/BIM软件产品技术深度分析文章写作计划
  • 7.4Element Plus 分页与表格组件
  • java spring cloud 企业工程管理系统源码+二次开发+定制化服务
  • 深兰科技AI问诊助手走访打浦桥街道社区卫生服务中心
  • Llama.cpp与CUDA Graph:深度学习推理框架的兼容性深度解析
  • Elasticsearch(text和keyword)区别分析
  • 怎么删除word空白页?【图文详解】删除最后一页空白页?5种删除word文档空白页方法?
  • Few-Shot Prompting 实战:用5个例子让GPT-4学会复杂任务
  • 线程与同步
  • 【Unity Shader学习笔记】(四)Shader编程
  • Java设计模式之结构型—适配器模式
  • SQLAlchemy ORM 入门教程
  • Low-Light Image Enhancement via Structure Modeling and Guidance 论文阅读
  • SQLint3 模块如何使用
  • Linux awk命令完全指南:从原理到实战,搞定文本处理难题
  • SQL(window)日志在linux 下查看
  • LangChain实战(十三):Agent Types详解与选择策略
  • 机器学习从入门到精通 - KNN与SVM实战指南:高维空间中的分类奥秘
  • Spring Boot 工程启动时自动执行任务方法
  • 图像正向扭曲反向扭曲