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

news2024/9/25 23:19:59

【机器学习】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表示未分类

        # 簇ID
        cluster_id = 0

        for 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 += 1

        self.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_names

for 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/

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

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

相关文章

脉冲水表计量方法有哪些?

随着社会的发展和人们对资源的需求不断增长&#xff0c;水资源的有效利用显得尤为重要。而水表作为测量家庭和工业用水的关键设备&#xff0c;其准确性和稳定性对于水资源管理至关重要。本文将重点介绍水表脉冲数计量方法&#xff0c;以帮助读者更好地理解和应用水资源。 一、机…

Magnific AI:彻底改变 AI 生成图像的升级

在我最近与 Magnific AI 的讨论中&#xff0c;我不仅感到惊讶&#xff0c;而且对该工具提供的质量和可能性着迷。我发现 Magnific AI 能够转换人工智能生成的图像&#xff08;这些图像通常只能以低分辨率提供&#xff09;&#xff0c;尤其令人印象深刻&#xff0c;不仅在可打印…

【MATLAB第84期】基于MATLAB的波形叠加极限学习机SW-ELM代理模型的sobol全局敏感性分析法应用

【MATLAB第84期】基于MATLAB的波形叠加极限学习机SW-ELM代理模型的sobol全局敏感性分析法应用 前言 跟往期sobol区别&#xff1a; 1.sobol计算依赖于验证集样本&#xff0c;无需定义变量上下限。 2.SW-ELM自带激活函数&#xff0c;计算具有phi&#xff08;x&#xff09;e^x激…

Kafka基本原理及使用

目录 基本概念 单机版 环境准备 基本命令使用 集群版 消息模型 成员组成 1. Topic&#xff08;主题&#xff09;&#xff1a; 2. Partition&#xff08;分区&#xff09;&#xff1a; 3. Producer&#xff08;生产者&#xff09;&#xff1a; 4. Consumer&#xff08;…

多任务学习(Multi-task Learning)的详细过程和具体示例

多任务学习 1.多任务学习的基本思想2. 多任务学习的过程包括:3. 多任务学习的具体例子: 1.多任务学习的基本思想 多任务学习(Multi-task Learning)是一种机器学习的方法,它可以同时解决多个相关任务。 多任务学习的基本思想是:多个任务之间存在一定的相关性或公共特征,我们可…

文件操作学习总结

磁盘上的⽂件是⽂件。 但是在程序设计中&#xff0c;我们⼀般谈的⽂件有两种&#xff1a; 程序⽂件、数据⽂件 &#xff08;从⽂件功能的⻆度来分类 的&#xff09;。 程序⽂件 &#xff1a; 程序⽂件包括源 程序⽂件&#xff08;后缀为.c&#xff09; , ⽬标⽂件&#xff0…

虚幻学习笔记16—C++和3DUI(二)

一、前言 上一篇虚幻学习笔记15—C和UI&#xff08;一&#xff09;中介绍了通过C代码创建2D的ui&#xff0c;本章主要讲解怎么用C代码创建3D的UI&#xff0c;在虚幻学习笔记3—UI跟随弹窗这章中讲解了怎样用蓝图创建一个3D的UI&#xff0c;并且和其交互。 本系列使用的虚幻5.2.…

Hive参数操作和运行方式

Hive参数操作和运行方式 1、Hive参数操作 1、hive参数介绍 ​ hive当中的参数、变量都是以命名空间开头的&#xff0c;详情如下表所示&#xff1a; 命名空间读写权限含义hiveconf可读写hive-site.xml当中的各配置变量例&#xff1a;hive --hiveconf hive.cli.print.headert…

abpvnext框架的项目部署到linux arm64版的docker中

参考&#xff1a; windows10下安装的docker 导出镜像到另一个电脑_docker镜像拷贝另一台机器的镜像-CSDN博客 前提条件&#xff1a; 1、vs2022&#xff0c;我的电脑本机安装有windows版docker desktop 。 2、linux中已经安装好docker&#xff0c;安装了sftp。这部分可以自行…

vue proxy代理 和 Nginx 配置跨域

vue.config.js文件中配置的代理&#xff1a; devServer: {port: 9095,// open: true, // 配置项目在启动时自动在浏览器打开proxy: {/yh: { // /api是代理标识&#xff0c;一般是每个接口前的相同部分target: "http://192.168.5.58:8002", // 请求地址&#xff0c;一…

2023年12月GESP认证Scratch图形化等级考试(四级)真题试卷

2023年12月GESP认证Scratch图形化等级考试&#xff08;四级&#xff09;真题试卷 题目总数&#xff1a;27 总分数&#xff1a;100 选择题 第 1 题 单选题 现代计算机是指电子计算机&#xff0c;它所基于的是&#xff08; &#xff09;体系结构 A. 艾伦图灵 B. …

Kafka为什么能高效读写数据

1&#xff09;Kafka 本身是分布式集群&#xff0c;可以采用分区技术&#xff0c;并行度高&#xff08;生产消费方并行度高&#xff09;&#xff1b; 2&#xff09;读数据采用稀疏索引&#xff0c;可以快速定位要消费的数据&#xff1b; 3&#xff09;顺序写磁盘&#xff1b; …

vue3项目引入电子签名(可横屏竖屏)

实现效果&#xff1a;&#xff08;左边横屏&#xff0c;右边竖屏&#xff09; 前言&#xff1a;【使用开源项目smooth-signature 实现签名的功能。Gitee 地址是 &#xff1a;GitHub - linjc/smooth-signature: H5带笔锋手写签名&#xff0c;支持PC端和移动端&#xff0c;任何前…

局域网其他pc如何访问宿主机虚拟机IP?

文章目录 背景贝瑞蒲公英设置虚拟机网络连接测试 背景 使用贝瑞蒲公英异地组网&#xff0c;将家里的pc作为pgsql服务器在公司使用&#xff0c;但是虚拟机的ip和端口访问不了 贝瑞蒲公英 设置虚拟机网络 就是添加端口转发规则 连接测试 公网内其他pc连接测试 可以看到已经连接成…

【python基础】-- yarn add 添加依赖的各种类型

目录 1、安装 yarn 1.1 使用npm安装 1.2 查看版本 1.3 yarn 淘宝源配置 2、安装命令说明 2.1 yarn add&#xff08;会更新package.json和yarn.lock&#xff09; 2.2 yarn install 2.3 一些操作 2.3.1 发布包 2.3.2 移除一个包 2.3.3 更新一个依赖 2.3.4 运行脚本 …

知乎上高频提问:Redis到底是单线程还是多线程程序?

1.概述 这里我们先给出问题的全面回答&#xff1a;Redis到底是多线程还是单线程程序要看是针对哪个功能而言&#xff0c;对于核心业务功能部分(命令操作处理数据)&#xff0c;Redis是单线程的&#xff0c;主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的&#xff…

Potplayer播放器远程访问群晖WebDav本地资源【内网穿透】

文章目录 本教程解决的问题是&#xff1a;按照本教程方法操作后&#xff0c;达到的效果是&#xff1a;1 使用环境要求&#xff1a;2 配置webdav3 测试局域网使用potplayer访问webdav3 内网穿透&#xff0c;映射至公网4 使用固定地址在potplayer访问webdav 国内流媒体平台的内容…

node.js mongoose aggregate

目录 官方文档 简述 Aggregate的原型方法 aggregate进行操作 官方文档 Mongoose v8.0.3: Aggregate 简述 在 Mongoose 中&#xff0c;Aggregate 是用于执行 MongoDB 聚合操作的类。MongoDB 聚合操作是一种强大的数据处理工具&#xff0c;可以用于对集合中的文档进行变换和…

智慧安防视频监控EasyCVR如何通过回调接口向第三方平台推送RTSP视频通道离线通知

安防视频监控系统EasyCVR能在局域网、公网、专网等复杂的网络环境中部署&#xff0c;可支持4G、5G、WiFi、有线等方式进行视频的接入与传输、处理和分发。平台能将接入的视频流进行汇聚、转码、多格式输出和分发&#xff0c;具体包括&#xff1a;RTMP、RTSP、HTTP-FLV、WebSock…

微信视频号本地生活服务商如何申请,最新方法来了

随着某平台的本地生活服务商被清退&#xff0c;大量的服务商开始想着如何转型&#xff0c;但辛苦一年打下来的商家资源&#xff0c;如何才能效果最大化&#xff1f;最好的方式就是重新找一个平台进行接盘。 随着视频号本地生活业务的开展&#xff0c;这一下就受到广大创业者&a…