西瓜书学习笔记——密度聚类(公式推导+举例应用)

文章目录

      • 算法介绍
      • 实验分析

算法介绍

密度聚类是一种无监督学习的聚类方法,其目标是根据数据点的密度分布将它们分组成不同的簇。与传统的基于距离的聚类方法(如K均值)不同,密度聚类方法不需要预先指定簇的数量,而是通过发现数据点周围的密度高度来确定簇的形状和大小。我们基于DBSCAN算法来实现密度聚类。

DBSCAN是基于一组邻域参数 ( ϵ , M i n P t s ) (\epsilon,MinPts) (ϵ,MinPts)来刻画样本分布的紧密程度,给定数据集 D = { x 1 , x 2 , . . . , x m } D=\{x_1,x_2,...,x_m\} D={x1,x2,...,xm}定义以下几个概念:

  • ϵ \epsilon ϵ-邻域:对 x j ∈ D x_j\in D xjD,其 ϵ \epsilon ϵ-邻域包含样本集 D D D中不大于 ϵ \epsilon ϵ的样本点,即 N ϵ ( x j ) = { x i ∈ D ∣ dist ⁡ ( x i , x j ) ⩽ ϵ } N_\epsilon\left(\boldsymbol{x}_j\right)=\left\{\boldsymbol{x}_i \in D \mid \operatorname{dist}\left(\boldsymbol{x}_i, \boldsymbol{x}_j\right) \leqslant \epsilon\right\} Nϵ(xj)={xiDdist(xi,xj)ϵ}
  • 核心对象:若 x j x_j xj ϵ \epsilon ϵ-邻域至少包含了 M i n P t s MinPts MinPts个样本,即 ∣ N ϵ ( x j ) ∣ ⩾ M i n P t s \left|N_\epsilon\left(\boldsymbol{x}_j\right)\right| \geqslant MinPts Nϵ(xj)MinPts,则 x j x_j xj是一个核心对象。
  • 密度直达:若 x j x_j xj位于 x i x_i xi ϵ \epsilon ϵ-邻域中,且 x i x_i xi是核心对象,则称 x j x_j xj x i x_i xi密度直达。
  • 密度可达:对 x i x_i xi x j x_j xj,若存在样本序列 p 1 , p 2 , . . . , p n p_1,p_2,...,p_n p1,p2,...,pn,其中 p 1 = x i p_1=x_i p1=xi p n = x j p_n=x_j pn=xj p i + 1 p_{i+1} pi+1 p i p_i pi密度直达,则称 x j x_j xj x i x_i xi密度可达。
  • 密度相连:对 x i x_i xi x j x_j xj,若存在 x k x_k xk使得 x i x_i xi x j x_j xj均由 x k x_k xk密度可达,则称 x i x_i xi x j x_j xj密度相连。
    在这里插入图片描述
    DBSCAN算法将定义为:由密度可达关系导出的最大密度相连的集合。于是,DBSCAN算法先任选数据集中的一个核心对象为种子,由此出发确定相应的聚类簇,其算法流程图如下所示:

在这里插入图片描述

实验分析

数据集如下表所示:
在这里插入图片描述
读入数据集:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

data = pd.read_csv('data/4.0.csv')

定义距离函数:

# 定义距离函数
def distance(point1, point2):
    return np.linalg.norm(point1 - point2)

ϵ \epsilon ϵ-邻域函数:

# 定义 epsilon-邻域 函数
def epsilon_neighborhood(point, epsilon, data):
    neighbors = []
    for i, other_point in enumerate(data):
        if distance(point, other_point) <= epsilon:
            neighbors.append(i)
    return neighbors

定义核心对象判定函数:

# 定义核心对象判定函数
def is_core_object(point, epsilon, min_pts, data):
    neighbors = epsilon_neighborhood(point, epsilon, data)
    return len(neighbors) >= min_pts

定义 DBSCAN 算法:

def dbscan(data, epsilon, min_pts):
    labels = [0] * len(data)
    cluster_id = 0

    for i, point in enumerate(data):
        if labels[i] != 0:
            continue

        neighbors = epsilon_neighborhood(point, epsilon, data)

        if len(neighbors) < min_pts:
            labels[i] = -1  # 标记为噪声点
            continue

        cluster_id += 1
        labels[i] = cluster_id

        for neighbor in neighbors:
            if labels[neighbor] == -1:
                labels[neighbor] = cluster_id
            if labels[neighbor] != 0:
                continue

            labels[neighbor] = cluster_id
            other_neighbors = epsilon_neighborhood(data[neighbor], epsilon, data)

            if len(other_neighbors) >= min_pts:
                neighbors.extend(other_neighbors)

    return labels

设置超参数:

# 设置 epsilon 和 min_pts 参数
epsilon_value = 0.1
min_pts_value = 4

执行DBSCAN算法并绘制结果:

# 执行 DBSCAN 算法
result_labels = dbscan(data.to_numpy(), epsilon_value, min_pts_value)

# 获取唯一的聚类标签
unique_labels = np.unique(result_labels)

# 绘制结果
plt.figure(figsize=(8, 8))
for label in unique_labels:
    if label == -1:
        plt.scatter(data['Density'][result_labels == label], data['Sugar inclusion rate'][result_labels == label], 
                    c='gray', marker='o', edgecolors='black', s=70, label='Noise')
    else:
        plt.scatter(data['Density'][result_labels == label], data['Sugar inclusion rate'][result_labels == label], 
                    label=f'Cluster {label}', marker='o', edgecolors='black', s=70)

plt.title('DBSCAN Clustering Result')
plt.xlabel('Density')
plt.ylabel('Sugar inclusion rate')
plt.legend()
plt.show()

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MGRE实验报告二

实验要求&#xff1a; 实验预览图&#xff1a; 实验分析&#xff1a; 1、对R1-R5配置IP地址&#xff0c;同时R1-R5每个路由器各有一个环回 2.1、对R1、R3、R4路由器开启虚拟接口1&#xff0c;分别配置隧道IP、接口封装协议&#xff0c;接口类型、定义封装源、开启伪广播功能&…

Mysql 删除数据

从数据表中删除数据使用DELETE语句&#xff0c;DELETE语句允许WHERE子句指定删除条件。DELETE语句基本语法格式如下&#xff1a; DELETE FROM table_name [WHERE <condition>]; table_name指定要执行删除操作的表&#xff1b;“[WHERE <condition>]”为可选参数&a…

Nginx 1.25配置QUIC和HTTP3

Nginx 1.25配置QUIC和HTTP/3 Nginx在编译时需要配置相应的SSL库&#xff0c;以确保能够支持HTTP3.0和HTTP2.0等基于HTTPS的协议。这些加密算法主要由OpenSSL提供。另外&#xff0c;BoringSSL是谷歌创建的OpenSSL分支&#xff0c;专门用于支持TLS 1.3的UDP协议的0-RTT数据传输加…

从C向C++6——运算符重载

本文的主要知识点是C中的运算符重载。 1.运算符重载 所谓重载&#xff0c;就是赋予新的含义。函数重载&#xff08;Function Overloading&#xff09;可以让一个函数名有多种功能&#xff0c;在不同情况下进行不同的操作。**运算符重载&#xff08;Operator Overloading&#…

【VS Code+Verilog+Vivado使用】(1)常用插件

文章目录 1 常用插件1.1 Chinese Language Pack1.2 Verilog-HDL/SV/BSV1.2.1 语法高亮1.2.2 代码片段1.2.3 代码检查1.2.4 Ctags1.2.4.1 自动补全设置1设置2 1.2.4.2 悬停显示1.2.4.3 转到定义1.2.4.4 查看定义1.2.4.5 模块例化设置1 1.3 vscode-icons1.4 Hex Editor1.5 Error …

Web开发8:前后端分离开发

在现代的 Web 开发中&#xff0c;前后端分离开发已经成为了一种常见的架构模式。它的优势在于前端和后端可以独立开发&#xff0c;互不干扰&#xff0c;同时也提供了更好的可扩展性和灵活性。本篇博客将介绍前后端分离开发的概念、优势以及如何实现。 什么是前后端分离开发&am…

国考省考行测:逻辑判断,分析推理,排除法,假设法

国考省考行测&#xff1a;逻辑判断&#xff0c;分析推理 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要的还是申论和行测&#xff0c;所以大家认真准备吧&#xff0c;我讲一起屡屡申论和…

【数据结构与算法】之哈希表系列-20240129

这里写目录标题 一、217. 存在重复元素二、219. 存在重复元素 II三、242. 有效的字母异位词四、268. 丢失的数字五、290. 单词规律六、349. 两个数组的交集七、350. 两个数组的交集 II 一、217. 存在重复元素 简单 给你一个整数数组 nums 。如果任一值在数组中出现至少两次 &a…

Java 面试题之 IO(二)

字符流 文章目录 字符流Reader&#xff08;字符输入流&#xff09;Writer&#xff08;字符输出流&#xff09; 文章来自Java Guide 用于学习如有侵权&#xff0c;立即删除 不管是文件读写还是网络发送接收&#xff0c;信息的最小存储单元都是字节。 那为什么 I/O 流操作要分为字…

【linux】-linux操作系统分支及包管理系统

一、Linux主要版本分支 免费的&#xff1a;ubuntu、centos&#xff0c;分属红帽、大便分支。 centos渐渐退出&#xff0c;CentOS 之父创造的 Rocky Linux&#xff08;再见 CentOS! Rocky Linux 要来了&#xff09; 二、Rocky Linux 官方地址&#xff1a;https://rockylinux.…

【大数据】Flink 架构(三):事件时间处理

《Flink 架构》系列&#xff08;已完结&#xff09;&#xff0c;共包含以下 6 篇文章&#xff1a; Flink 架构&#xff08;一&#xff09;&#xff1a;系统架构Flink 架构&#xff08;二&#xff09;&#xff1a;数据传输Flink 架构&#xff08;三&#xff09;&#xff1a;事件…

【Python笔记-设计模式】建造者模式

一、说明 又称生成器&#xff0c;是一种创建型设计模式&#xff0c;使其能够分步骤创建复杂对象。允许使用相同的创建代码生成不同类型和形式的对象。 (一) 解决问题 对象的创建问题&#xff1a;当一个对象的构建过程复杂&#xff0c;且部分构建过程相互独立时&#xff0c;可…

吉利汽车:S-SDLC融入开发体系,推动智能汽车安全发展

吉利汽车是中国汽车行业的知名品牌&#xff0c;是一家具有国际化视野的汽车企业&#xff0c;在中国汽车市场自主品牌中占据领军地位。吉利汽车集团数字化中心利用数字化技术优势赋能业务升级&#xff0c;推动研发效率提升和产品安全能力拓展&#xff0c;进行整体数字化转型。 在…

键盘上Ins键的作用

前几天编写文档时&#xff0c;发现一个问题&#xff1a;插入内容时&#xff0c;输入的字符将会覆盖光标位置后的字符。原来是按到了键盘上的 Ins键&#xff0c;解决方法是&#xff1a;再按一次 Ins键&#xff08;Ins键如果独立作为一键时&#xff0c;否则使用 “Fn Ins”组合键…

C++ —— 智能指针

C —— 智能指针 文章目录 C —— 智能指针一、为什么需要使用智能指针&#xff1f;二、内存泄漏什么是内存泄漏&#xff1f;内存泄漏的危害&#xff1f;内存泄漏分类 三、智能指针的使用及原理1. RAII2. 智能指针的原理 三、智能指针的缺陷及其发展3.1 std::auto_ptr3.2 std::…

华为笔记本matebook pro X如何扩容 C 盘空间

一、前提条件 磁盘扩展与合并必须是相邻分区空间&#xff0c;且两个磁盘类型需要相同。以磁盘分区为 C 盘和 D 盘为例&#xff0c;如果您希望增加 C 盘容量&#xff0c;可以先将 D 盘合并到 C 盘&#xff0c;然后重新创建磁盘分区&#xff0c;分配 C 盘和 D 盘的空间大小。 访…

Element ui 的组件弹窗 el-dialog点击的时候全屏变灰问题解决

最近在使用Element UI 的弹窗组件的时候发现这个组件各种的应用都没有问题&#xff0c;数据和元素的应用都是正确的但是在点击显示这个弹窗的时候全屏幕都会变灰。 这也不是因为增加了modal 遮挡幕的问题&#xff0c;在经过不断的排查代码的时候基本排除了代码的问题&#xf…

利用外卖系统源码构建高效的在线订餐平台

在当今数字化时代&#xff0c;外卖服务已成为人们日常生活中不可或缺的一部分。为了满足用户需求&#xff0c;许多创业者和企业都希望搭建自己的在线订餐平台。利用现有的外卖系统源码&#xff0c;可以快速构建一个高效、安全的在线订餐平台。本文将介绍如何利用外卖系统源码来…

Qt SQLite3数据库加密 QtCipherSqlitePlugin

在客户端软件开发过程中&#xff0c;基本都会涉及到数据库的开发。QT支持的数据库也有好几种&#xff08;QSQLITE, QODBC, QODBC3, QPSQL, QPSQL7&#xff09;&#xff0c;SQLite就是其中之一&#xff0c;但这个 SQLite 是官方提供的开源版本&#xff0c;没有加密功能的。如果对…

k8s 进阶实战笔记 | 应用的蓝绿、金丝雀发布笔记

文章目录 应用的蓝绿、金丝雀发布笔记应用升级策略停机升级滚动更新蓝绿发布金丝雀发布 应用的蓝绿、金丝雀发布笔记 应用升级策略 Deployment.spec.strategy 设置 Recreate&#xff1a;同时删除所有副本&#xff0c;停机升级策略 不存在新老版本共存 存在某个时间段服务不可…