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

【机器学习】密度聚类:从底层手写实现DBSCAN

【机器学习】Building-DBSCAN-from-Scratch

  • 概念
  • 代码
    • 数据导入
    • 实现DBSCAN
    • 使用样例及其可视化
  • 补充资料

概念

DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪声的基于密度的聚类方法)是一种基于密度的空间聚类算法。该算法将具有足够密度的区域划分为簇,并在具有噪声的空间数据库中发现任意形状的簇,它将簇定义为密度相连的点的最大集合。

该算法的核心概念是识别位于高密度区域的样本点,并将它们划分为簇。以图中的点A为例,我们观察到A点周围有较高的点密度。根据DBSCAN算法的特定参数——即邻域半径(Epsilon)和最小点数(MinPts)——我们可以确定一个点是否为核心点、边界点或离群点。

在这里插入图片描述

在此过程中,算法首先随机选择一个样本点(如A点)并围绕其绘制一个圆,其半径等于邻域半径。如果在这个圆内的样本点数量达到或超过MinPts的阈值,则该点被视为核心点,并且圆心会移动到圆内的另一个样本点,继续探索相邻区域。这个过程持续进行,直到没有更多的点可以加入到当前簇中。此时,圆内最后一个样本点被视为边界点,如B或C。而那些未能被纳入任何簇的点,如N,被视为离群点。

通过这种方式,DBSCAN算法有效地将样本空间中距离相近的点聚合在一起,形成不同的簇,同时识别并排除噪声或异常值。这种基于密度的聚类方法特别适合于处理具有复杂结构或不规则形状的数据集。

在这里插入图片描述

代码

数据导入

from sklearn.datasets import load_iris  # 导入数据集iris
import matplotlib.pyplot as plt  # 导入绘图库
import numpy as np  # 导入numpy库
# 加载Iris数据集
iris = load_iris()
X = iris.data  # 获得其特征向量,150*4

实现DBSCAN

在OurDBSCAN类中,我们首先通过初始化函数设置了邻域半径eps和最小样本数min_samples,这两个参数是确定簇的关键。在fit方法中,对输入数据集X的每个点进行遍历和分类处理。

算法开始时,所有点都标记为未分类。接着,对每个点,先检查其状态,如果已经分类则跳过,否则通过_find_neighbors方法找出该点的所有邻居。这一步骤涉及计算点与其他所有点之间的欧氏距离,判断是否在设定的邻域半径内。如果一个点的邻居数少于min_samples,则将其标记为噪声。

当一个点有足够多的邻居被确定为核心点后,算法会创建一个新的簇,并通过迭代地探索该点的邻居来扩展这个簇。在此过程中,每个新发现的点都会被检查是否也是核心点,如果是,它的邻居也会被加入到当前簇中。这种方式使得DBSCAN能够根据密度将数据集中的点聚合成多个簇,同时识别和剔除噪声点,有效应对具有不规则形状或包含噪声和异常值的数据集。

class OurDBSCAN:def __init__(self, eps, min_samples):"""初始化DBSCAN对象。参数:eps (float): 邻域的半径。min_samples (int): 核心点的邻域中的最小样本数。"""self.eps = eps  # 邻域的半径self.min_samples = min_samples  # 核心点的最小样本数self.labels_ = None  # 簇标签def fit(self, X):"""将DBSCAN模型拟合到输入数据。参数:X (array-like): 输入数据。返回:None"""# 将所有点标记为-1(未分类)labels = -1 * np.ones(X.shape[0])  # -1表示未分类# 簇IDcluster_id = 0for i in range(X.shape[0]):  # 遍历所有点# 如果该点已被访问过,则跳过if labels[i] != -1:continue# 找到当前点的所有邻居neighbors = self._find_neighbors(i, X)# 如果邻居数小于min_samples,则标记为噪声并继续if len(neighbors) < self.min_samples:labels[i] = -2  # -2表示噪声continue# 否则,开始一个新的簇labels[i] = cluster_id# 找到当前簇的所有邻居seeds = set(neighbors)  # 邻居集合seeds.remove(i)  # 移除当前点while seeds:  # 只要种子集合不为空# 取出一个邻居current_point = seeds.pop()# 如果是噪声,则将其标记为当前簇if labels[current_point] == -2:labels[current_point] = cluster_id# 如果已经处理过,则跳过if labels[current_point] != -1:continue# 否则,将其标记为当前簇labels[current_point] = cluster_id# 找到当前点的所有邻居current_neighbors = self._find_neighbors(current_point, X)# 如果当前点是核心点,则将其邻居添加到种子集合中if len(current_neighbors) >= self.min_samples:seeds.update(current_neighbors)# 移动到下一个簇cluster_id += 1self.labels_ = labels  # 保存簇标签def _find_neighbors(self, point_idx, X):"""找到给定点的邻居。参数:point_idx (int): 点的索引。X (array-like): 输入数据。返回:neighbors (list): 邻居的索引。"""neighbors = []for i, point in enumerate(X):  # 遍历所有点if np.linalg.norm(X[point_idx] - point) <= self.eps:  # 计算距离neighbors.append(i)return neighbors

使用样例及其可视化

# 使用手动实现的 DBSCAN,不使用 NearestNeighbors
manual_dbscan_nn = OurDBSCAN(eps=0.5, min_samples=5)
manual_dbscan_nn.fit(X)
# 创建一个图形和子图
fig, axs = plt.subplots(2, 3, figsize=(15, 10))# 组合特征以创建散点图
feature_combinations = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
feature_names = iris.feature_namesfor i, (fi, fj) in enumerate(feature_combinations):ax = axs[i//3, i % 3]ax.scatter(X[:, fi], X[:, fj], c=manual_dbscan_nn.labels_, cmap='viridis',marker='o', edgecolor='k', s=50)ax.set_xlabel(feature_names[fi])ax.set_ylabel(feature_names[fj])ax.set_title(f'DBSCAN Clustering with {feature_names[fi]} vs {feature_names[fj]}')plt.tight_layout()
plt.show()

在这里插入图片描述
在IRIS数据集中,每个样本都有四个特征:花萼长度(sepal length)、花萼宽度(sepal width)、花瓣长度(petal length)和花瓣宽度(petal width),所有的这些特征都以厘米为单位进行测量。在第一行的图表中,我们可以看到花萼长度与花萼宽度、花瓣长度和花瓣宽度的聚类关系。在第二行,展示的是花萼宽度与花瓣长度、花瓣宽度的聚类效果,以及花瓣长度与花瓣宽度的聚类情况。

通过DBSCAN算法的密度聚类特性,我们可以看到在密度较高的区域形成了聚类簇,而在密度较低的区域,点则被标记为噪声点或者位于不同簇的边界。

补充资料

一个有趣的DBSCAN可视化网站:
https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/

相关文章:

【机器学习】密度聚类:从底层手写实现DBSCAN

【机器学习】Building-DBSCAN-from-Scratch 概念代码数据导入实现DBSCAN使用样例及其可视化 补充资料 概念 DBSCAN&#xff08;Density-Based Spatial Clustering of Applications with Noise&#xff0c;具有噪声的基于密度的聚类方法&#xff09;是一种基于密度的空间聚类算…...

2023-12-20 二叉搜索树的最近公共祖先和二叉搜索树中的插入操作和删除二叉搜索树中的节点

235. 二叉搜索树的最近公共祖先 思想&#xff1a;和二叉树的公共最近祖先节点的思路基本一致的&#xff01;就是不用从下往上遍历处理&#xff01;可以利用的二叉搜索树的特点从上往下处理了&#xff01;而且最近公共节点肯定是第一个出现在【q&#xff0c;p】这个区间的内的&…...

pytorch文本分类(三)模型框架(DNNtextCNN)

pytorch文本分类&#xff08;三&#xff09;模型框架&#xff08;DNN&textCNN&#xff09; 原任务链接 目录 pytorch文本分类&#xff08;三&#xff09;模型框架&#xff08;DNN&textCNN&#xff09;1. 背景知识深度学习 2. DNN2.1 从感知器到神经网络2.2 DNN的基本…...

<长篇文章!!>数据结构与算法的重要知识点与概要总结 ( •̀ ω •́ )✧✧临近考试和查漏补缺的小伙伴看这一篇就都懂啦~

目录 一、数据结构概论二、算法概论三、线性表四、栈五、队列六、串七、多维数组与矩阵八、广义表九、树与二叉树十、图 一、数据结构概论 1、数据元素和数据项 数据由数据元素组成&#xff0c;即数据元素是数据的基本单位&#xff0c;而数据元素又由若干个数据项组成&#xf…...

【安全】audispd调研

audispd调研 1 问题背景 在Linux中&#xff0c;当某个进程调用audit_set_pid将自己的pid保存到内核的audit模块后&#xff0c;如果有日志生成&#xff0c;kaudit内核线程就会通过netlink通信机制将审计日志发送给audit_pid&#xff0c;因此&#xff0c;只能有一个进程占用aud…...

WINDOWS(WIN11)通过IP添加网络打印机

点击添加设备 点击手动添加 使用IP地址或主机名添加打印机 选择TCP/IP设备&#xff0c;输入打印机地址 如果有正确驱动就安装&#xff0c;没有就取消。 通过手动设置添加本地打印机或网络打印机 使用现有的端口 根据打印机IP&#xff0c;选择标准端口。 成功&#xff01; 到…...

华为数通试题

选择题 华为数通推出的面向企业的云计算平台是&#xff1f; A) FusionSphere B) CloudEngine C) Agile Controller D) eSight 下面哪个不是华为数通的核心交换机系列&#xff1f; A) S12700 B) S5700 C) S9300 D) CloudEngine 华为数通的企业级路由器系列包括哪个&#xff1f…...

Labview Vision 机器视觉使用,从下载程序安装应用,到实战找硬币并输出值

1.前言 大家好,今天我要和机器人一起配合来打算 做机器视觉 用Labview 和 Vision 联动实现机器的视觉 2.下载软件-软件的安装 我们除了基础款的labview软件 还要安装视觉四件套 1.Labview 编程平台&#xff08;我是 2023 q3&#xff09; 2. NI - IMAQdx &#xff08;驱动软…...

【delphi11】delphi基础探索【三、基础组件和事件】

目录 基础组件 1. TButton&#xff08;按钮&#xff09; 2. TLabel&#xff08;标签&#xff09; 3. TEdit&#xff08;编辑框&#xff09; 4. TMemo&#xff08;多行编辑框&#xff09; 5. TComboBox&#xff08;组合框&#xff09; 6. TCheckBox&#xff08;复选框&…...

react hooks浅谈

一.useEffect useEffect是hooks中的生命周期函数 1.只要页面更新就触发回调&#xff1a; useEffect(() > { // 执行逻辑 }) 2.只运行一次&#xff08;组件挂载和卸载时执行&#xff09;&#xff0c;第二个参数传空数组[]&#xff1a; useEffect(() > { // },[]) 3. 条件…...

stable diffusion webui之lora调用

1.触发词底模lora效果最好&#xff08;分数不一定要取到1&#xff0c;0.8也行&#xff09;&#xff1b; 2.引用时一定要使用<lora:>&#xff0c;例如<lora:C4D_geometry_bg_v2.5:0.8>&#xff1b; "prompt": "(masterpiece:1.3), (best quality:1.…...

FormData文件上传多文件上传

一、简介 ​ 通常情况下&#xff0c;前端在使用post请求提交数据的时候&#xff0c;请求都是采用application/json 或 application/x-www-form-urlencoded编码类型&#xff0c;分别是借助JSON字符串来传递参数或者keyvalue格式字符串&#xff08;多参数通过&进行连接&#…...

八股文打卡day4——计算机网络(4)

TCP和UDP的概念、特点、区别和对应的使用场景&#xff1f; 我的回答&#xff1a; 概念&#xff1a; TCP是传输控制协议&#xff0c;是面向连接、可靠的、基于字节流的传输层通信协议。 UDP是用户数据报协议&#xff0c;是无连接、不可靠的&#xff0c;基于数据报的传输层通信…...

TensorFlow(2):Windows安装TensorFlow

1 安装python环境 这一步请自行安装&#xff0c;这边不做介绍。 2 安装anaconda 下载路径&#xff1a;Index of /&#xff0c;用户自行选择自己的需要的版本。 3 环境配置 3.1 anaconda环境配置 找到设置&#xff0c;点击系统->系统信息->高级系统设置->环境变量…...

一文解决idea导入源码控制台爆红问题

文章目录 唠嗑部分背景说明idea查看maven配置 言归正传安装mavenidea配置maven 结语及资料获取 唠嗑部分 背景说明 很多新手伙伴们在导入项目源码时&#xff0c;都会遇到大片依赖爆红&#xff0c;项目跑不起来&#xff0c;小白也是把自己电脑重新配置了一番&#xff0c;复现了…...

排序算法——快排

快速排序算法最早是由图灵奖获得者Tony Hoare设计出来的,他在形式化方法理论以 及ALGOL.60编程语言的发明中都有卓越的贡献,是20世纪最伟大的计算机科学家之—。 而这快速排序算法只是他众多贡献中的—个小发明而已。 快速排序&#xff08;Quick Sort&#xff09;的基本算法思…...

第二节TypeScript 基础语法

1、typescript程序由以下几个部分组成&#xff1a; 模块函数变量语句和表达式注释 2、开始第一个typescript程序 创建一个typescript程序&#xff0c;使之输出“hello typescript”&#xff1a; 代码&#xff1a; var message:string "hello typescript" cons…...

Go、Python、Java、JavaScript等语言的求余(取模)计算

余数符号规则&#xff1a; Go&#xff08;%&#xff09;&#xff1a; 余数与被除数符号一致 Java&#xff08;%&#xff09;&#xff1a; 余数与被除数符号一致 JavaScript&#xff08;%&#xff09;&#xff1a; 余数与被除数符号一致 Python&#xff08;%&#xff09;…...

scrapy快加构造并发送请求

scrapy数据建模与请求 学习目标&#xff1a; 应用 在scrapy项目中进行建模应用 构造Request对象&#xff0c;并发送请求应用 利用meta参数在不同的解析函数中传递数据 1. 数据建模 通常在做项目的过程中&#xff0c;在items.py中进行数据建模 1.1 为什么建模 定义item即提前…...

【C++】谈谈深拷贝与浅拷贝

目录 一、浅拷贝 1.定义 2.示例 3.问题 二、深拷贝 1.定义 2.示例 3.优点 三、考虑场景 浅拷贝的考虑 1.性能要求 2.简单地数据结构 3.资源管理 深拷贝的考虑 1.动态内存分配 2.复杂数据结构 3.资源管理 总结 一、浅拷贝 1.定义 浅拷贝是指对对象进行复制时…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...