机器学习DBSCAN密度聚类

引言

在机器学习的聚类任务中,K-means因其简单高效广为人知,但它有一个致命缺陷——假设簇是球形且密度均匀,且需要预先指定簇数。当数据存在任意形状的簇、噪声点或密度差异较大时,K-means的表现往往不尽如人意。这时候,DBSCAN(Density-Based Spatial Clustering of Applications with Noise) 作为基于密度的聚类算法,凭借其无需预设簇数、能识别噪声、处理任意形状簇的特性,成为工业界和学术界的神器

本文将从原理到代码,带你彻底搞懂DBSCAN,并通过实战案例掌握其核心技巧。

一、DBSCAN核心概念:用“密度”定义簇

要理解DBSCAN,首先需要明确5个核心概念:

1. ε邻域(ε-Neighborhood)

对于数据点 ppp,其ε邻域是指所有与 ppp 的距离不超过 ε\varepsilonε 的点的集合,数学上表示为:
Nε(p)={q∈D∣distance(p,q)≤ε}N_\varepsilon(p) = \{ q \in D \mid \text{distance}(p, q) \leq \varepsilon \}Nε(p)={qDdistance(p,q)ε}
其中 DDD 是数据集,distance\text{distance}distance 常用欧氏距离(连续数据)或曼哈顿距离(高维稀疏数据)。

2. 核心对象(Core Object)

如果数据点 ppp 的ε邻域内至少包含 min_samples\text{min\_samples}min_samples 个点(包括 ppp 自己),则 ppp 是一个核心对象。
换句话说,核心对象是“密度足够高”的点,是簇形成的基础。

3. 直接密度可达(Directly Density-Reachable)

如果点 qqq 位于核心对象 ppp 的ε邻域内(即 q∈Nε(p)q \in N_\varepsilon(p)qNε(p)),则称 qqqppp 出发是直接密度可达的。

4. 密度可达(Density-Reachable)

如果存在一个点序列 p1,p2,...,pnp_1, p_2, ..., p_np1,p2,...,pn,其中 p1=pp_1 = pp1=ppn=qp_n = qpn=q,且每个 pi+1p_{i+1}pi+1pip_ipi 直接密度可达,则称 qqqppp 出发是密度可达的。
密度可达是直接密度可达的传递扩展,但不具备对称性(即 qqq 密度可达 ppp 不代表 ppp 密度可达 qqq)。

5. 密度相连(Density-Connected)

如果存在一个核心对象 ooo,使得 pppqqq 都从 ooo 密度可达,则称 pppqqq密度相连的。
密度相连的点属于同一个簇。

6. 簇与噪声

  • :数据集中最大的密度相连点集(即无法通过密度可达扩展更多点)。
  • 噪声:不属于任何簇的点(不被任何核心对象密度可达)。

二、DBSCAN算法流程:从核心对象到簇的构建

DBSCAN的核心逻辑是“从核心对象出发,扩展密度可达的点形成簇”。具体步骤如下:

  1. 计算所有点的ε邻域:遍历数据集,为每个点计算其ε邻域内的点数量。
  2. 筛选核心对象:保留那些ε邻域内点数量 ≥ min_samples的点,标记为核心对象。
  3. 扩展簇:从任意一个未被访问的核心对象出发,递归地将其所有密度可达的点加入当前簇,并标记为已访问。
  4. 处理噪声:所有未被访问且不属于任何核心对象的点,标记为噪声。

聚类原理

三、代码实战:用Python实现DBSCAN

1. 环境准备与数据生成

我们使用 scikit-learn 提供的合成数据,并添加噪声。首先安装依赖:

pip install numpy pandas matplotlib scikit-learn

生成数据代码:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs, make_noise
from sklearn.preprocessing import StandardScaler# 生成3个真实簇(含噪声)
X, y_true = make_blobs(n_samples=300, centers=3, cluster_std=[1.0, 2.0, 0.8],  # 不同簇的密度差异random_state=42
)
X = StandardScaler().fit_transform(X)  # 标准化数据# 添加5%的噪声点(偏离真实簇)
noise = make_noise(n_samples=int(0.05*len(X)), noise_scale=3.0, random_state=42)[0]
X = np.concatenate([X, noise])# 可视化原始数据
plt.scatter(X[:, 0], X[:, 1], c='gray', s=10, label='Unclustered Data')
plt.title("Raw Data with Noise")
plt.legend()
plt.show()

2. 使用scikit-learn的DBSCAN

sklearn.cluster.DBSCAN 已经封装了高效的DBSCAN实现,我们直接调用并调参:

from sklearn.cluster import DBSCAN# 初始化DBSCAN,关键参数:eps=ε,min_samples=min_samples
dbscan = DBSCAN(eps=0.8, min_samples=5)
clusters = dbscan.fit_predict(X)  # 输出:-1表示噪声,其他为簇标签# 统计结果
n_clusters = len(set(clusters)) - (1 if -1 in clusters else 0)  # 排除噪声标签-1
n_noise = np.sum(clusters == -1)
print(f"Estimated number of clusters: {n_clusters}")
print(f"Estimated number of noise points: {n_noise}")# 可视化聚类结果
plt.scatter(X[:, 0], X[:, 1], c=clusters, s=10, cmap='viridis')
plt.title(f"DBSCAN Clustering (eps=0.8, min_samples=5)")
plt.colorbar(label='Cluster ID (-1=Noise)')
plt.show()

3. 关键参数调优:如何选择ε和min_samples?

DBSCAN的效果高度依赖两个参数:

  • eps(ε):邻域半径,太小会导致很多簇被分割,太大可能合并不同簇。
  • min_samples:核心对象的最小邻域点数,通常设置为维度+1(如2维数据设为3-5)。

调参技巧:k-distance图
k-distance图通过计算每个点到其第k近邻的距离并排序,绘制折线图。曲线的“拐点”对应的距离即为合适的ε(通常k=min_samples-1)。

from sklearn.neighbors import NearestNeighbors
import numpy as np# 计算每个点的k近邻距离(k=min_samples-1=4)
min_samples = 5
k = min_samples - 1
neighbors = NearestNeighbors(n_neighbors=k)
neighbors_fit = neighbors.fit(X)
distances, indices = neighbors_fit.kneighbors(X)# 排序距离并绘制
distances = np.sort(distances, axis=0)[:, 1]  # 取第k近邻的距离(排除自己)
plt.plot(distances)
plt.xlabel("Points sorted by distance")
plt.ylabel(f"{k}-th Nearest Neighbor Distance")
plt.title("k-distance Plot for ε Selection")
plt.grid(True)
plt.show()

解读k-distance图
曲线从左下到右上逐渐上升,当出现一个明显的“跳跃”(拐点)时,对应的距离即为合适的ε。例如,若拐点在距离0.8处,则设置eps=0.8

四、DBSCAN的优缺点与适用场景

优点:

  • 无需预设簇数:自动根据数据密度划分簇。
  • 抗噪声能力强:明确识别噪声点(标签-1)。
  • 处理任意形状簇:不依赖簇的球形假设。

缺点:

  • 参数敏感:ε和min_samples的选择对结果影响大。
  • 高维数据效果下降:高维空间中距离度量失效(维度诅咒)。
  • 密度不均匀时表现差:若簇间密度差异大,难以找到统一的ε。

适用场景:

  • 数据分布有明显密度差异(如用户分群中的高价值/低活跃用户)。
  • 存在噪声或离群点(如金融欺诈检测)。
  • 簇形状不规则(如地理区域的用户分布)。

五、总结

DBSCAN是一种强大的密度聚类算法,核心是通过“核心对象”和“密度可达”定义簇,天然抗噪声且能处理任意形状的簇。实战中需重点调参ε和min_samples,推荐使用k-distance图辅助选择ε。下次遇到传统聚类算法无法解决的复杂数据时,不妨试试DBSCAN

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

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

相关文章

RecyclerView 缓存机制

一、四级缓存体系1. Scrap 缓存(临时缓存)位置:mAttachedScrap 和 mChangedScrap作用:存储当前屏幕可见但被标记为移除的 ViewHolder用于局部刷新(如 notifyItemChanged())特点:生命周期短&…

大模型SSE流式输出技术

文章目录背景:为什么需要流式输出SSE 流式输出很多厂商还是小 chunk背景:为什么需要流式输出 大模型的响应通常很长,比如几百甚至几千个 token,如果等模型一次性生成完才返回: 延迟高:用户要等很久才能看…

[Flutter] v3.24 AAPT:错误:未找到资源 android:attr/lStar。

推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战 前提 将 Flutter 升级到 3.24.4 后,构建在我的本地电脑上通过,但Github actions 构建时失败。 Flutt…

go语言标准库学习, fmt标准输出,Time 时间,Flag,Log日志,Strconv

向外输出 fmt包实现了类似C语言printf和scanf的格式化I/O。主要分为向外输出内容和获取输入内容两大部分。 内置输出 不需要引入标准库,方便 package mainfunc main() {print("我是控制台打印,我不换行 可以自己控制换行 \n我是另一行")prin…

ElementUI之表格

文章目录使用ElementUI使用在线引入的方式表格1. 带状态表格row-class-name"Function({row, rowIndex})/String"2. 固定表头(height"string/number"属性)2.1 属性的取值2.2 动态响应式高度使用演示2.3 ​​自定义滚动条样式​​2.4 表头高度定制获取一行信…

K8S 的 Master组件

K8S 的 Master 组件有哪些?每个组件的作用? K8s 大脑的 4 大核心模块,掌控全局! Kubernetes 集群的 Master(主节点) 就像一座 指挥中心,负责整个集群的调度、管理和控制。它由 4 大核心组件组成…

如何 让ubuntu 在root 下安装的docker 在 普通用户下也能用

在 Ubuntu 系统中,如果 Docker 是以 root 用户安装的,普通用户默认无法直接使用 Docker 命令(会报权限错误)。要让普通用户也能使用 Docker,可以按照以下步骤操作:方法 1:将用户加入 docker 用户…

模板方法模式:优雅封装算法骨架

目录 一、模板方法模式 1、结构 2、特性 3、优缺点 3.1、优点 3.2、缺点 4、使用场景 5、实现示例 5.1、抽象类 5.2、实现类 5.3、测试类 一、模板方法模式 模板方法模式(Template Method Pattern)是一种行为设计模式,它在一个方…

韦东山STM32_HAl库入门教程(SPI)学习笔记[09]内容

(1)SPI程序层次一、核心逻辑:“SPI Flash 操作” 是怎么跑起来的?要读写 SPI Flash,需同时理解 硬件连接(怎么接线) 和 软件分层(谁负责发指令、谁负责控制逻辑)&#xf…

线上Linux服务器的优化设置、系统安全与网络安全策略

一、Linux服务器的优化设置 线上Linux的优化配置序号基础优化配置内容说明1最小化安装系统【仅安装需要的,按需安装、不用不装】,必须安装的有基本开发环境、基本网络包、基本应用包。2ssh登录策略优化 Linux服务器上的ssh服务端配置文件是【/et…

基于人眼视觉特性的相关图像增强基础知识介绍

目录 1. 传统的灰度级动态范围优化配置方法 2.基于视觉特性的灰度级动态范围调整优化 1. 传统的灰度级动态范围优化配置方法 传统的灰度级动态范围调整方法主要包括线性动态范围调整及非线性动态 范围调整。线性动态范围调整是最简单的灰度级动态范围调整方法,观察…

Selenium使用超全指南

🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快概述selenium是网页应用中最流行的自动化测试工具,可以用来做自动化测试或者浏览器爬虫等。官网地址为:相对于另外一款web自动化测试工具QT…

Go通道操作全解析:从基础到高并发模式

一、channel类型 Go 语言中的通道(channel)是一种特殊的类型。它类似于传送带或队列,遵循先进先出(FIFO)原则,确保数据收发顺序的一致性。每个通道都是特定类型的导管,因此在声明时必须指定其元素类型。 channel是一种类型, 一种引用类型。 声明通道类型的格式如下:…

Linux网络--1、网络基础

目录 一、网络发展 二、理解分层 2.1OSI七层模型 2.2TCP/IP分层模型 2.3分层的好处 三、认识协议 3.1初步认识 3.2了解指定组织 3.3具体协议理解 3.3.1是什么 3.3.2为什么 3.3.3与OS的关系 3.4总结 四、网络传输流程 4.1局域网网络传输 4.1.1通信过程 4.1.2概念解析 4.2跨网…

前端视角下关于 WebSocket 的简单理解

参考 RFC 6455: The WebSocket Protocol WebSocket 协议基础 协议本质:在单个 TCP 连接上提供全双工通信通道的协议核心优势: 双向实时通信(服务器主动推送)低延迟(相比 HTTP 轮询)高效数据传输&#xff0…

自动化一键部署 LNMP 环境

第一步:准备环境 & 准备脚本文件1. 你在 CentOS 7 的服务器/虚拟机里打开终端,确认你有 root 权限或者能用 sudo。输入下面命令确认你的系统版本:cat /etc/centos-release你应该看到类似:CentOS Linux release 7.9.2009 (Core…

react之React.cloneElement()

react提供的这个方法克隆组件的方法,可能我们在平常的开发中用的很少,主要可能是我们并不知道或者并不了解这个方法。因为我在之前react的children文章中用到过,所以我就进行了一系列的测试,发现真的非常的好用。我们同样使用一些…

学习Java的Day27

今天学习的主要内容是在IntelliJ IDEA开发环境中,通过部署Tomcat服务器并连接MySQL数据库,实现了一个完整的留言板系统。这个项目涵盖了前后端开发的全流程,具体包括以下关键环节:开发环境搭建使用IntelliJ IDEA Ultimate版&#…

【计算机网络 | 第3篇】物理媒介

文章目录物理媒介介绍与物理媒体的分类🥝成本考量引导型传输媒体🍋引导型传输媒体:双绞线🍋‍🟩双绞线类别双绞线的发展历程双绞线的物理限制引导型传输媒体:同轴电缆🍋‍🟩结构组成…

golang的切片

切片 为什么需要切片 用于元素的个数不确定,所以无法通过数组的形式来进行统计。此时就需要切片 切片,也因此可以粗略地理解为动态数组数组的长度不能用变量来确定,这时候切片slice也就派上用场了 切片地基本介绍 切片的英文是slice切片是数组…