聚类分析算法——DBSCAN(密度聚类)算法详解

        本文要全面、深入地介绍理解 DBSCAN(Density-Based Spatial Clustering of Applications with Noise),我们需要从 算法的核心思想、步骤、底层原理、参数选择,以及 代码实现细节 上进行详细剖析。


1. DBSCAN 算法核心思想

        DBSCAN 是一种基于密度的聚类算法,旨在发现任意形状的簇,并且对 噪声点(outliers)具有鲁棒性(健壮性)。它通过在数据空间中找到高密度区域,将这些区域作为簇,同时把孤立点(密度低的点)归为噪声。

DBSCAN 的基本思想是:

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

2. DBSCAN 的基本概念

  1. ε-邻域(Epsilon-neighborhood):
    对于某个点 pp,以半径 εε 为边界的区域内所有的点称为该点的 ε-邻域。

  2. 核心点(Core Point)
    如果一个点 p 的 ε-邻域内至少有 minPts 个点(包括 p 自己),那么它被称为核心点。

  3. 边界点(Border Point)
    如果一个点 p 在某个核心点的 ε-邻域内,但自身不是核心点,它被称为边界点。

  4. 噪声点(Noise Point)
    如果一个点既不是核心点,也不属于任何核心点的邻域,它被认为是噪声点。

  5. 密度直达(Directly Density-Reachable)
    如果点 p 是核心点,并且点 q 在 p 的 ε-邻域内,那么 q 被称为从 p 密度直达

  6. 密度可达(Density-Reachable)
    如果存在一条核心点链表(p1→p2→...→pn​),使得每个点从前一个点密度直达,且 p1=p,pn=q,则 q 是从 p 密度可达 的。

  7. 密度相连(Density-Connected)
    如果存在一个点 o,使得 p 和 q 都从 o 密度可达,则称 p 和 q 是密度相连的。


3. DBSCAN 算法步骤

  1. 初始化
    从数据集中任意选择一个点 p,判断它是否为核心点(即 ε 邻域内是否包含至少 minPts 个点)。

  2. 扩展簇
    如果 p 是核心点,则开始一个新簇,将 p 及其邻域中的点加入簇中,并不断对新的核心点的邻域进行扩展。

  3. 处理噪声点
    如果一个点既不在任何簇中,也不满足成为核心点的条件,则将其标记为噪声点。

  4. 重复处理
    继续检查所有未访问的点,直到所有点都被访问为止。


4. DBSCAN 伪代码

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

5. DBSCAN 的时间复杂度分析

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

6. DBSCAN 的 Python 实现

我们使用 scikit-learn 中的 DBSCAN 实现,并演示如何手动实现核心逻辑。

6.1 使用 scikit-learn 的 DBSCAN

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 的点表示噪声点。
  • 其他标签表示该点属于的簇。

6.2 手动实现 DBSCAN 的核心逻辑

import numpy as npdef dbscan(X, eps, minPts):labels = [-1] * len(X)  # 初始化所有点为未分类(-1 表示噪声)C = 0  # 当前簇标签def region_query(P):return [i for i, Q in enumerate(X) if np.linalg.norm(P - Q) <= eps]def expand_cluster(P, neighbors):labels[P] = Ci = 0while i < len(neighbors):Q = neighbors[i]if labels[Q] == -1:  # 如果 Q 是噪声点,重新标记为簇点labels[Q] = Celif labels[Q] == -1:  # 如果 Q 还未分类labels[Q] = CQ_neighbors = region_query(X[Q])if len(Q_neighbors) >= minPts:neighbors += Q_neighbors  # 扩展邻域i += 1for P in range(len(X)):if labels[P] == -1:neighbors = region_query(X[P])if len(neighbors) < minPts:labels[P] = -1  # 标记为噪声else:C += 1  # 创建新簇expand_cluster(P, neighbors)return labels# 示例数据
X = np.array([[1, 2], [2, 2], [2, 3], [8, 7], [8, 8], [25, 80]])# 运行 DBSCAN
labels = dbscan(X, eps=3, minPts=2)
print("Cluster labels:", labels)


7. 参数选择与调优

  1. ε(eps)

    • ε 决定了邻域的大小。如果太小,簇会分散;太大,簇会合并。
    • 可以通过 k距离图(k-distance graph)来选择合适的 ε。
  2. minPts

    • 一般来说,minPts ≥ 数据维度的两倍。例如对于二维数据,可以设置 minPts = 4

8. DBSCAN 的优缺点

优点:

  • 可以发现任意形状的簇。
  • 不需要预先指定簇的数量。
  • 对噪声有鲁棒性。

缺点:

  • 当簇的密度差异较大时,效果不佳。
  • 高维数据中的性能较差。
  • 需要合理选择 ε 和 minPts 参数。

9. 总结

        DBSCAN 是一种基于密度的聚类算法,特别适用于发现任意形状的簇,并且具有处理噪声点的能力。通过合理选择参数 ε 和 minPts,它可以在空间数据分析、图像处理、异常检测等领域发挥重要作用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/456957.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习技术演进:从 CNN、RNN 到 Transformer 的发展与原理解析

深度学习的技术演进经历了从卷积神经网络&#xff08;CNN&#xff09;到循环神经网络&#xff08;RNN&#xff09;再到 Transformer 的重要发展。这三个架构分别擅长处理图像、序列数据和多种任务的特征&#xff0c;标志着深度学习在不同领域取得的进步。 1. 卷积神经网络&…

java智能物流管理系统源码(springboot)

项目简介 智能物流管理系统实现了以下功能&#xff1a; 智能物流管理系统的主要使用者分为管理员&#xff0c;顾客&#xff0c;员工&#xff0c;店主。功能有个人中心&#xff0c;顾客管理&#xff0c;员工管理&#xff0c;店主管理&#xff0c;门店信息管理&#xff0c;门店…

Go 语言中的 for range 循环教程

在 Go 语言中&#xff0c;for range 循环是一个方便的语法结构&#xff0c;用于遍历数组、切片、映射和字符串。本教程将通过示例代码来帮助理解如何在 Go 中使用 for range 循环。 package mainimport "fmt"func main() {// 遍历切片并计算和nums : []int{2, 3, 4}…

OpenCV视觉分析之目标跟踪(1)计算密集光流的类DISOpticalFlow的介绍

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 这个类实现了 Dense Inverse Search (DIS) 光流算法。更多关于该算法的细节可以在文献 146中找到。该实现包含了三个预设参数集&#xff0c;以提…

Visual studio 下载安装

1&#xff0c;Visual stutdio 网址 下载 Visual Studio Tools - 免费安装 Windows、Mac、Linux 2&#xff0c;下划页面&#xff0c;点击 较早的下载 3&#xff0c;选择对应的版本进行下载

蓝牙技术的多种模式详解

蓝牙作为一种广泛应用的无线通信技术&#xff0c;已经在我们的日常生活中无处不在。随着技术的发展&#xff0c;蓝牙已经不再仅限于传统的音频传输&#xff0c;而是扩展到了各种应用领域。本文将深入探讨蓝牙的各种模式及其应用场景。 1. 经典蓝牙&#xff08;BR/EDR&#xff…

单链表OJ题:移除链表元素(力扣)

目录 解法一&#xff1a;带头节点的新链表 解法二&#xff1a;不带头节点的新指向关系链表 总结 这是一道简单的力扣题目&#xff0c;关于解法的话&#xff0c;这里提供了二种思路&#xff0c;重点解释前两种&#xff0c;还有一种思路好想&#xff0c;但是时间复杂度为O(n^2…

一站式学习 Shell 脚本语法与编程技巧,踏出自动化的第一步

文章目录 1. 初识 Shell 解释器1.1 Shell 类型1.2 Shell 的父子关系 2. 编写第一个 Shell 脚本3. Shell 脚本语法3.1 脚本格式3.2 注释3.2.1 单行注释3.2.2 多行注释 3.3 Shell 变量3.3.1 系统预定义变量&#xff08;环境变量&#xff09;printenv 查看所有环境变量set 查看所有…

SMT 生产可视化:提升电子组装流程效率

通过图扑 HT 对表面贴装技术&#xff08;SMT&#xff09;生产线的实时数据采集与可视化分析&#xff0c;实现对产品质量、产能利用率和流程优化的有效监控&#xff0c;助力生产效率最大化与质量提升。

听见文本的魅力:AI 与未来的语音交互

AI 与未来的语音交互 引言什么是文本转语音&#xff08;TTS&#xff09;&#xff1f;当前 TTS 技术现状国内海外文本转语音能力调研文本转语音能力说明多情感风格SSML语音合成标记语言 未来趋势 引言 随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;文本转…

OpenCV视觉分析之运动分析(4)背景减除类:BackgroundSubtractorKNN的一系列set函数的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 BackgroundSubtractorKNN类有一系列的set函数&#xff0c;下面我们一一列举他们的名字和用法。 一系列set函数 函数setDetectShadows() setDe…

笔记整理—linux驱动开发部分(1)驱动梗概

驱动可以分为广义上的和狭义上的驱动。广义上的驱动是用于操作硬件的代码&#xff0c;而狭义上的驱动为基于内核系统之上让硬件去被操作的逻辑方法。 linux体系架构&#xff1a; 1.分层思想 &#xff1a;在OS中间还会有许多层。 : 2.驱动的上面是系统调用&#xff08;API&…

JavaScript网页设计案例教程:从零开始构建一个响应式网页

JavaScript网页设计案例教程&#xff1a;从零开始构建一个响应式网页 前言 在当今互联网时代&#xff0c;网页设计已成为一项重要技能。JavaScript作为网页开发的核心技术之一&#xff0c;能够让网页变得更加生动和交互。本文将带您通过一个实际案例&#xff0c;逐步学习如何…

万字图文实战:从0到1构建 UniApp + Vue3 + TypeScript 移动端跨平台开源脚手架

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f343; vue-uniapp-template &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f…

【C语言】控制台学生成绩管理系统

文章目录 C语言编程&#xff1a;学生成绩管理系统一、程序概述二、代码实现三、程序解释 C语言编程&#xff1a;学生成绩管理系统 在这篇文章中&#xff0c;我们将一起探讨如何使用C语言来创建一个简单的学生成绩管理系统。这个系统将允许用户输入学生数量、学号和成绩&#x…

钉钉录播抓取视频

爬取钉钉视频 免责声明 此脚本仅供学习参考&#xff0c;切勿违法使用下载他人资源进行售卖&#xff0c;本人不但任何责任! 仓库地址: GItee 源码仓库 执行顺序 poxyM3u8开启代理getM3u8url用于获取m3u8文件userAgent随机请求头downVideo|downVideoThreadTqdm单线程下载和…

水轮发电机油压自动化控制系统解决方案介绍

在现代水电工程中&#xff0c;水轮机组油压自动化控制系统&#xff0c;不仅直接关系到水轮发电机组的安全稳定运行&#xff0c;还影响着整个水电站的生产效率和经济效益。 一、系统概述 国科JSF油压自动控制系统&#xff0c;适用于水轮发电机组调速器油压及主阀&#xff08;蝶…

Golang | Leetcode Golang题解之第503题下一个更大元素II

题目&#xff1a; 题解&#xff1a; func nextGreaterElements(nums []int) []int {n : len(nums)ans : make([]int, n)for i : range ans {ans[i] -1}stack : []int{}for i : 0; i < n*2-1; i {for len(stack) > 0 && nums[stack[len(stack)-1]] < nums[i%…

01 springboot-整合日志(logback-config.xml)

logback-config.xml 是一个用于配置 Logback 日志框架的 XML 文件&#xff0c;通常位于项目的 classpath 下的根目录或者 src/main/resources 目录下。 Logback 提供了丰富的配置选项&#xff0c;可以满足各种不同的日志需求。需要根据具体情况进行配置。 项目创建&#xff0…

Nginx、Tomcat等项目部署问题及解决方案详解

目录 前言1. Nginx部署后未按预期显示结果1.1 查看Nginx的启动情况1.2 解决启动失败的常见原因 2. 端口开启问题2.1 Windows环境下的端口开放2.2 Linux环境下的端口开放 3. 重视日志分析3.1 Nginx日志分析3.2 Tomcat日志分析 4. 开发环境与部署后运行结果不同4.1 开发环境与生产…