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

机器学习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.lryc.cn/news/615423.html

相关文章:

  • 讯飞晓医-讯飞医疗推出的个人AI健康助手
  • 复杂环境下车牌识别准确率↑29%:陌讯动态特征融合算法实战解析
  • 编译技术的两条演化支线:从前端 UI 框架到底层编译器的智能测试
  • Office安装使用?借助Ohook开源工具?【图文详解】微软Office产品
  • 每周算法思考:栈与队列
  • 【数据结构入门】栈和队列
  • 物理AI与人形机器人:从实验室到产业化的关键跨越
  • day15_keep going on
  • [激光原理与应用-202]:光学器件 - 增益晶体 - Nd:YVO₄增益晶体的制造过程与使用过程
  • RecyclerView 缓存机制
  • 202506 电子学会青少年等级考试机器人六级器人理论真题
  • 【自动化运维神器Ansible】playbook自动化部署Nginx案例解析:助力从零构建高效Web服务
  • Kettle ETL 工具存在的问题以及替代方案的探索
  • AWT 事件监听器深入浅出:Action/Mouse/Key/Window 全解析与实战
  • B2.0:对硬件学习的一些个人心得感悟
  • 跨境电商系统开发:ZKmall开源商城的技术选型与代码规范实践
  • Linux 中CentOS Stream 8 - yum -y update 异常报错问题
  • MySQL 主备(Master-Slave)复制 的搭建
  • 每日五个pyecharts可视化图表-line:从入门到精通
  • 基于springboot+vue开发的校园食堂评价系统【源码+sql+可运行】【50809】
  • 计算机系统设计中都有什么任务~计算密集~IO密集~逻辑密集等
  • 通过 Docker 运行 Prometheus 入门
  • 如何在 Excel 中快速求和?【图文详解】Excel求和技巧,Excel求和公式大全,多种方式求和
  • 轻松Linux-5.进程控制
  • drippingblues靶机
  • Easysearch 冷热架构实战
  • 从 AI 到实时视频通道:基于模块化架构的低延迟直播全链路实践
  • Docker容器lnmp平台部署discuz论坛
  • 配送算法10 Batching and Matching for Food Delivery in Dynamic Road Networks
  • 算法篇----分治(快排)