传统机器学习(四)聚类算法DBSCAN

news2025/1/21 0:51:38

传统机器学习(四)聚类算法DBSCAN

1.1 算法概述

DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪声的基于密度的聚类方法)是一种基于密度的空间聚类算法。

该算法将具有足够密度的区域划分为簇,并在具有噪声的空间数据库中发现任意形状的簇,它将簇定义为密度相连的点的最大集合。

1.1.1 基本概念

核心对象: 若某个点的密度达到算法设定的阈值,则其为核心点(即r 邻域内点的数量不小于 minPts )

e-邻域的距离阈值:设定的半径

直接密度可达: 若某点p在点q的 r 域内,且q是核心点,则p-q直接密度可达

密度可达: 若有一个点的序列q0、q1、…qk,对任意qi-qi-1是直接密度可达的则称从q0到qk密度可达,这实际上是直接密度可达的“传播”

边界点:属于某一个类的非核心点,不能发展下线了

噪声点: 不属于任何一个类簇的点,从任何一个核心点出发都是密度不可达的

在这里插入图片描述

上面这些点是分布在样本空间的众多样本,现在我们的目标是把这些在样本空间中距离相近的聚成一类。

我们发现A点附近的点密度较大,红色的圆圈根据一定的规则在这里滚啊滚,最终收纳了A附近的5个点,标记为红色也就是定为同一个簇。

其它没有被收纳的根据一样的规则成簇。

形象来说,我们可以认为这是系统在众多样本点中随机选中一个,围绕这个被选中的样本点画一个圆,规定这个圆的半径以及圆内最少包含的样本点,如果在指定半径内有足够多的样本点在内,那么这个圆圈的圆心就转移到这个内部样本点,继续去圈附近其它的样本点,类似传销一样,继续去发展下线。

等到这个滚来滚去的圈发现所圈住的样本点数量少于预先指定的值(minPts),就停止了。那么我们称最开始那个点为核心点,如A,停下来的那个点为边界点,如B、C,没得滚的那个点为离群点,如N)。

基于密度这点有什么好处呢?

我们知道kmeans聚类算法只能处理球形的簇,也就是一个聚成实心的团(这是因为算法本身计算平均距离的局限)。但往往现实中还会有各种形状,比如下面图,环形和不规则形,这个时候,那些传统的聚类算法显然就悲剧了。

在这里插入图片描述

1.1.2 DBSCAN工作流程

在这里插入图片描述

1.1.3 参数选择及可视化

参数选择

DBSCAN算法的两个参数,这两个参数比较难指定:

  • 半径: 半径是最难指定的 ,大了,圈住的就多了,簇的个数就少了;反之,簇的个数就多了,这对我们最后的结果是有影响的。这个时候,K距离可以帮助我们来设定半径r,也就是要找到突变点。

    首先选中一个点,计算它和所有其它点的距离,从小到大排序,d1,d2,d3,d4等等,假如我们发现 d3 和 d4 之间的差异很大,于是认为前面的距离是比较合适的,那么就可以指定出来 r 半径的大小。虽然是一个可取的方式,但是有时候比较麻烦 ,大部分还是都试一试进行观察,用k距离需要做大量实验来观察,很难一次性把这些值都选准。

  • MinPts: 这个参数就是圈住的点的个数,也相当于是一个密度,一般这个值都是偏小一些,然后进行多次尝试。

可视化

有一个网站(https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/)可以把我们DBSCAN的迭代过程动态图画出来

在这里插入图片描述

设置好参数,点击GO! 就开始聚类了!

在这里插入图片描述

1.1.4 DNSCAN优缺点

优点

  • 不需要指定簇个数

  • 可以发现任意形状的簇

  • 擅长找到离群点( 检测任务)

  • 两个参数就够了

缺点

  • 高维数据有些困难(可以做降维)

  • 参数难以选择(参数对结果的影响非常大)

  • Sklearn中效率很慢(数据削减策略)

1.2 DBScan算法案例

1.2.1 不同半径对算法结果影响

1.2.1.1 利用sklearn中make_moons方法产生数据集

make_moons是函数用来生成数据集,在sklearn.datasets里,具体用法如下:

sklearn.datasets.make_moons(n_samples=100, *, shuffle=True, noise=None, random_state=None)

主要参数作用如下:

n_numbers:生成样本数量

shuffle:是否打乱,类似于将数据集random一下

noise:默认是false,数据集是否加入高斯噪声

random_state:生成随机种子,给定一个int型数据,能够保证每次生成数据相同。

import numpy as np
import os
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12
import warnings
warnings.filterwarnings('ignore')
np.random.seed(42)


# 导入make_moons
from sklearn.datasets import make_moons
X, y = make_moons(n_samples=1000, noise=0.05, random_state=42)

# 绘制图像
plt.plot(X[:,0],X[:,1],'b.')

在这里插入图片描述

1.2.2.2 DBScan算法

from sklearn.cluster import DBSCAN

# 设置半径为0.05,阈值为5
dbscan = DBSCAN(eps = 0.05,min_samples=5)
dbscan.fit(X)

在这里插入图片描述

在这里插入图片描述

不同半径对聚类结果的影响

dbscan2 = DBSCAN(eps = 0.2,min_samples=5)
dbscan2.fit(X)
# 图像展示
def plot_dbscan(dbscan, X, size, show_xlabels=True, show_ylabels=True):
    core_mask = np.zeros_like(dbscan.labels_, dtype=bool)
    core_mask[dbscan.core_sample_indices_] = True
    anomalies_mask = dbscan.labels_ == -1
    non_core_mask = ~(core_mask | anomalies_mask)

    cores = dbscan.components_
    anomalies = X[anomalies_mask]
    non_cores = X[non_core_mask]

    plt.scatter(cores[:, 0], cores[:, 1],
                c=dbscan.labels_[core_mask], marker='o', s=size, cmap="Paired")
    plt.scatter(cores[:, 0], cores[:, 1], marker='*', s=20, c=dbscan.labels_[core_mask])
    plt.scatter(anomalies[:, 0], anomalies[:, 1],
                c="r", marker="x", s=100)
    plt.scatter(non_cores[:, 0], non_cores[:, 1], c=dbscan.labels_[non_core_mask], marker=".")
    if show_xlabels:
        plt.xlabel("$x_1$", fontsize=14)
    else:
        plt.tick_params(labelbottom='off')
    if show_ylabels:
        plt.ylabel("$x_2$", fontsize=14, rotation=0)
    else:
        plt.tick_params(labelleft='off')
    plt.title("eps={:.2f}, min_samples={}".format(dbscan.eps, dbscan.min_samples), fontsize=14)
plt.figure(figsize=(12, 4))

plt.subplot(121)
plot_dbscan(dbscan, X, size=100)

plt.subplot(122)
plot_dbscan(dbscan2, X, size=600, show_ylabels=False)

plt.show()

在这里插入图片描述

1.2.2 鸢尾花数据集的DBSCAN的聚类案例

import pandas as pd
from sklearn.datasets import load_iris
# 导入数据,sklearn自带鸢尾花数据集
iris = load_iris().data
iris[:5]

在这里插入图片描述

from sklearn.cluster import DBSCAN
iris_db = DBSCAN(eps=0.6,min_samples=4).fit_predict(iris)

# 设置半径为0.6,最小样本量为2,建模
db = DBSCAN(eps=10, min_samples=2).fit(iris)

# 统计每一类的数量
counts = pd.value_counts(iris_db,sort=True)
counts

在这里插入图片描述

# 可视化
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = [u'Microsoft YaHei']

fig,ax = plt.subplots(1,2,figsize=(12,12))


# 画真实数据结果
ax1 = ax[0]
ax1.scatter(x=iris[:,0],y=iris[:,1],s=250,c=load_iris().target)
ax1.set_title('真实分类',fontsize=20)



# 画聚类后的结果
ax2 = ax[1]
ax2.scatter(x=iris[:,0],y=iris[:,1],s=250,c=iris_db)
ax2.set_title('DBSCAN聚类结果',fontsize=20)

plt.show()

在这里插入图片描述

我们可以从上面这个图里观察聚类效果的好坏,但是当数据量很大,或者指标很多的时候,观察起来就会非常麻烦。

这时候可以使用轮廓系数来判定结果好坏,聚类结果的轮廓系数,定义为S,是该聚类是否合理、有效的度量。

聚类结果的轮廓系数的取值在[-1,1]之间,值越大,说明同类样本相距约近,不同样本相距越远,则聚类效果越好

轮廓系数以及其他的评价函数都定义在sklearn.metrics模块中,在sklearn中函数silhouette_score()计算所有点的平均轮廓系数。

from sklearn import metrics

# 就是下面这个函数可以计算轮廓系数
score = metrics.silhouette_score(iris,iris_db)
score

# 0.42300259179079075

1.2.3 k-means和DBSCAN聚类对比

import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN
from sklearn.cluster import KMeans
from sklearn import datasets
# 生成数据
x, y = datasets.make_circles(n_samples=2000, factor=0.5, noise=0.05)

# k-means方法聚类
kmeans_model = KMeans(n_clusters=2)
kmeans_model.fit(x)
kmeans_result = kmeans_model.predict(x)

# DBSCAN方法聚类
dbscan_model = DBSCAN(eps=0.2, min_samples=50)
dbscan_model.fit(x)
dbscan_result = dbscan_model.fit_predict(x)


# 绘制图像
plt.figure(figsize=(12, 4))
plt.subplot(121)
plt.scatter(x[:, 0], x[:, 1], c=kmeans_result)
plt.title('kmeans_model')

plt.subplot(122)
plt.scatter(x[:, 0], x[:, 1], c=dbscan_result)
plt.title('dbscan_result')

plt.show()

在这里插入图片描述

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

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

相关文章

【C++学习】类和对象--对象特性(2)

静态成员 静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员。 静态成员变量: 所有对象共享同一份数据 在编译阶段分配内存 类内声明,类外初始化 静态成员函数: 所有对象共享同一个函数 静态成员函数只能访问静态…

MyBatis小技巧

一、MyBatis中接口代理机制及使用 我们不难发现,以前编写dao/mapper实现类中的方法代码很固定,基本上就是一行代码,通过SqlSession对象调用insert、delete、update、select等方法,这个类中的方法没有任何业务逻辑,既然…

【Cadence】 ADS Dynamic Link使用教程

ADS Dynamic Link使用教程 1.新建一个Cadence Schematic2.打开ADS3.在ADS新建Schematic4.加入控件OPTIONS5.加入Netlist6.仿真测试7.写在最后 1.新建一个Cadence Schematic 随便搭了一个Cascode 注意这个时候不要新建symbol 2.打开ADS 3.在ADS新建Schematic 选择对应的Cade…

BI技巧丨计算组环形图

当我们使用Power BI时,会发现其内置了许多可视化组件,这些组件可以帮我们快速地创建各种类型的报表和仪表板,这是非常方便的。但是,我们也会发现,有些组件的细节功能并不是很完善,这就导致了我们在平常使用…

解决 mapper.xml 文件的 resultType 爆红问题:Cannot resolve symbol ‘xxx‘

解决mapper.xml文件的resultType爆红问题:Cannot resolve symbol xxx 1.问题描述2.问题分析3.问题解决3.1 配置注解(推荐)3.2 配置全类名3.3 删除插件 4.事件感悟 系统:Win10 JDK:1.8.0_333 IDEA:2022.2.4 …

【C++】Qt环境下的五子棋小程序

实现要求 这个程序是一个基于Qt的五子棋游戏,实现了人机对战和双人对战两种游戏模式,提供了基本的棋谱记录和游戏音效功能。程序采用了MVC模式,将数据与界面分离,实现了代码的模块化和可扩展性。主要构建包括三个文件&#xff0c…

Java - 数据结构,哈希表

一、概念 顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较。顺序查找时间复杂度为O(N),平衡树中为树的高度,即O( ),搜索的效率取决于搜…

Ambari【部署 01】最新版本ambari-2.7.7下载编译打包安装使用(踩坑实录)

Ambari 官网 本次安装的为当前最新版本 2.7.7 文档 。 1.环境及准备 1.1 环境 # 系统 [roottcloud ~]# cat /etc/centos-release CentOS Linux release 7.9.2009 (Core) # JDK [roottcloud ~]# java -version java version "1.8.0_241" Java(TM) SE Runtime Envir…

java模板/策略模式打怪兽

模板&策略模式 实现姿势 我们会从简单到复杂,讲解代码正确的实现姿势,分别为最 Low 方式、常规方式、模板模式和策略模式。 最 Low 方式 假如现在有 3 个奥特曼,都喜欢 “训练,飞翔,打怪兽” public class OldTig…

jsp+java自行车租赁租借和买卖系统

自行车租借和买卖系统 系统包括四个模块。1,系统模块,2,车辆管理模块,3.租借车管理模块,4,买卖车管理模块。 1,系统模块包括: 连接数据库,工作人员登录,退出。 2&#…

《类和对象》(中篇)

本文主要介绍类里面的六大默认成员函数 文章目录 前言类的6个默认成员函数1、构造函数1.1 概念1.2 特性 2、析构函数2.1 概念2.2 特性 3 、拷贝构造函数3.1 概念3.2 特性3.3 使用场景 4、运算符重载4.1 规则4.2 赋值运算符重载 5、const 成员6、取地址与const取地址操作符重载总…

Shiro安全框架简介

一、权限管理 1.1 什么是权限管理 基本上只要涉及到用户参数的系统都要进行权限管理,使用权限管理实现了对用户访问系统的控制,不同的用户访问不同的资源。按照安全规则或者安全策略控制用户访问资源,而且只能访问被授权的资源 权限管理包括认…

学成在线笔记+踩坑(1)——项目思路、架构、父工程和基础工程,Gogs使用

【黑马Java笔记踩坑汇总】JavaSEJavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线牛客面试题 目录 简历-技术架构 项目预览 后台页面 课程管理 媒资管理页面上传视频 新增课程 课程管理页提交审核 审核员审核后发布课程 前台页面 主页 验证码登录…

uniapp系列-超详细教你在uni-app+vue3里通过web-view组件传递信息打开H5页面写入localstorage并解决兼容性

web-view是什么 web-view 是一个 web 浏览器组件,可以用来承载网页的容器,会自动铺满整个页面(nvue 使用需要手动指定宽高)。点击这里直达官网文档点击这里下载我的代码demo本文最下面还有一些常见或者奇怪问题解决方案哦~ 为什…

GMRES算法及Matlab程序

关于GMRES的总结 一些理论以及代码 首先是我们要解决的问题,也就是最常见的问题,即求解 A x b Axb Axb Galerkin条件 krylov子空间 我们所做的GMRES实际上就是在Galerkin条件的扩张下,n o r m ( r ) normnorm不断减小的一个过程。这也是…

家用洗地机哪种好?性价比高的洗地机推荐

选择清洁家电时,首先需要考虑你需要清洁的区域和清洁的方式。如果你需要清洁的是地面,那么洗地机可能是一个不错的选择。洗地机的优势在于它可以自动清洁地面,并且可以在较短的时间内完成清洁工作。相比于其他的清洁家电,洗地机的…

设计链表(链表篇)

你可以选择使用单链表或者双链表,设计并实现自己的链表。 单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。 如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点…

Linux_红帽8学习笔记分享_5

Linux_红帽8学习笔记分享_5 文章目录 Linux_红帽8学习笔记分享_51. UMASK反掩码1.1如何查看反掩码umask1.2 UMASK反掩码的作用1.2.1对于目录来说1.2.2对于文件来说 1.3如何修改UMASK反掩码1.4普通用户反掩码的测试 2.whereis的使用3. SUID权限弥补(主要针对文件,所有者执行位变…

第14章_数据结构与集合源码

第14章_数据结构与集合源码 讲师:尚硅谷-宋红康(江湖人称:康师傅) 官网:http://www.atguigu.com 本章专题与脉络 1. 数据结构剖析 我们举一个形象的例子来理解数据结构的作用: 战场:程序运行…

认识Object类和深浅拷贝

本文介绍了Object类以及Object类部分方法,toString方法,equals和hashCode方法(重写前和重写后的对比),getClass方法,clone方法,以及拷贝新对象时会出现的深浅拷贝, 内容较长,耗时一天,建议收藏后观看~ Object类和深浅拷贝 一.初识Object类1.Object类接收所有子类实例2.Object类…