DBSCAN算法,概念+示例,超详细!!

2023-05-16

DBSCAN

(Density-Based Spatial Clustering of Applications with Noise)

与划分和层次聚类方法不同,它将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域划分为簇,并可在噪声的空间数据库中发现任意形状的聚类

算法流程

  1. 选取一个点,以eps为半径,画一个圈,看圈有几个临近点

    若临近点个数大于某个阈值(min_points) ,则认为该点为某一簇的点;

    若小于min_points,则被标记为噪声点,然后处理下一个点

  2. 将临近点作为种子点 seeds = [4,7,9,10 ]

    遍历所有种子点

    ​ 若该点被标记为噪声点 ,则重标为聚类点

    ​ 若该点没有被标记过,则标记为聚类点

    ​ 并且以该点为圆心,以eps为半径画圈,若圈内点大于min_points,则将圈内点添加到种子点中

    ​ seeds = [4,7,9,10,1,7,9,16]

    在这里插入图片描述

  3. 重复步骤2,直到遍历完所有的种子点

    seeds = [4,7,9,10, 1,7,9,16] #第一次步骤2,标记4

    ​ 7的周围有12,4,小于min_points,seeds不扩展

    在这里插入图片描述

    seeds = [4,7,9,10, 1,7,9,16] #第二次步骤2,标记7

    ​ 9的周围有1,4,3,大于min_points,seeds扩展

    在这里插入图片描述

    seeds = [4,7,9,10, 1,7,9,16,1,4,3] #第三次步骤2,标记9

    ​ 10的周围有1,6,7,大于min_points,seeds扩展

    在这里插入图片描述

    seeds = [4,7,9,10, 1,7,9,16,1,4,3,1,6,7] #第四次步骤2,标记10

    ​ 1已经标记过,继续下一个点

    seeds = [4,7,9,10, 1,7,9,16,1,4,3,1,6,7]

    ​ 7已经标记过,继续下一个点

    seeds = [4,7,9,10, 1,7,9,16,1,4,3,1,6,7]

    ​ 9已经标记过,继续下一个点

    seeds = [4,7,9,10, 1,7,9,16,1,4,3,1,6,7]

    ​ 16的周围有12,4,小于min_points,seeds不扩展

    seeds = [4,7,9,10, 1,7,9,16,1,4,3,1,6,7]

    .

    .

    .

    重复进行画圈、标记

  4. 标记完一簇后

寻找一个未被标记的点,开始新一轮的聚类

​ 如果找到点5,周围点少,标记为NOISE

​ 如果找到点15,周围点少,标记为NOISE

​ 如果找到点19,开始新一轮聚类

在这里插入图片描述

.

.

.

最终效果

在这里插入图片描述

举例

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import DBSCAN
from sklearn import metrics

UNCLASSIFIED = 0        #点未被标记
NOISE = -1              #噪声点标记

# 计算数据点两两之间的距离
def getDistanceMatrix(datas):       #datas 是聚类数据
    N,D = np.shape(datas)    #读取datas的维度,维度是N x D(N指数据个数,D指特征维度)   ,shape函数用于获取矩阵的形状
    dists = np.zeros([N,N])     #zeros 函数:返回一个给定形状和类型的用0填充的数组,

    for i in range(N):      
        for j in range(N):
            vi = datas[i,:]     #切片 [开始,结束]
            vj = datas[j,:]
            dists[i,j]= np.sqrt(np.dot((vi-vj),(vi-vj)))    #欧式距离函数,返回点与点之间距离的数组
    return dists


#  寻找以点cluster_id 为中心,eps 为半径的圆内的所有点的id
def find_points_in_eps(point_id, eps, dists):
    index = dists[point_id] <= eps          #dists[point_id] 即:point_id 与 所有点的距离
    return np.where(index)[0].tolist()      #返回所有符合的点的集合


# 聚类扩展
# dists : 任意数据两两之间的距离  N x N
# labs :   所有数据的标签 labs N,
# cluster_id : 一个簇的标号
# eps : 密度评估半径
# seeds: 用来进行簇扩展的点
# min_points: 半径内最少的点数
def expand_cluster(dists, labs, cluster_id, seeds, eps, min_points):
    i = 0
    while i < len(seeds):   
        Pn = seeds[i]       #获取一个点
        if labs[Pn] == NOISE:   #如果是噪声点,则重新标记
            labs[Pn] = cluster_id
        elif labs[Pn] == UNCLASSIFIED:  #如果未被标记过,则进行标记
            labs[Pn] = cluster_id           
            new_seeds = find_points_in_eps(Pn, eps, dists) # 以新点为圆心再画圈,进行扩展
            if len(new_seeds) >= min_points:   #如果扩张的圈中数够多,则加入到seeds队列中 
                seeds = seeds + new_seeds   
        i += 1
                #通过挨个标记和扩展seeds里的数字,实现聚类过程
        
def dbscan(datas, eps, min_points):
    dists = getDistanceMatrix(datas)        #获取点与点之间的距离,且以二维数组的形式
    # 将所有点的标签初始化为0
    n_points = datas.shape[0]           #shape[0]指读取读取矩阵第一维的长度      
    labs = [UNCLASSIFIED] * n_points       

    cluster_id = 0
    # 遍历所有点
    for point_id in range(n_points):
        if labs[point_id] != UNCLASSIFIED:  #如果被标记,则结束此次循环,表示该点已处理过
            continue                        #没有处理过,则计算寻找临近点
        seeds = find_points_in_eps(point_id, eps, dists)   #符合条件的点存到seeds中

        if len(seeds) < min_points: # 如果临近点过少,则标记为噪声点
            labs[point_id] = NOISE  
        else:                               #否则开启新一轮扩张
            cluster_id = cluster_id + 1     
            labs[point_id] = cluster_id     #标记当前点
            expand_cluster(dists, labs, cluster_id, seeds, eps, min_points)
    return labs, cluster_id
   
   
# 绘图         
                # 数据  聚类结果  聚类个数
def draw_cluster(datas,labs, n_cluster):     
    plt.cla()       
                #设计颜色                   
    colors = [plt.cm.Spectral(each)         
          for each in np.linspace(0, 1,n_cluster)]   #(起点,终点,几个元素)   
    
        #遍历所有点的坐标
    for i,lab in enumerate(labs):
        if lab ==NOISE:     #如果是噪声点 则为黑色
            plt.scatter(datas[i,0],datas[i,1],s=16.,color=(0,0,0))
        else:       #否则,根据类别的编号,来标记颜色
            plt.scatter(datas[i,0],datas[i,1],s=16.,color=colors[lab-1])
    plt.show()
    

if __name__== "__main__":
    
    ## 数据1
    centers = [[1, 1], [-1, -1], [1, -1]]       #三个中心点的坐标
    #datas为样本数据集,labels_true为样本数据集的标签
    datas, labels_true = make_blobs(n_samples=750, centers=centers, cluster_std=0.4,
                             random_state=0) 
                              #产生一组随机数datas,中心点是centers,方差是0.4,产生750个点
    
    ## 数据2
    #file_name = "spiral"
    #with open(file_name+".txt","r",encoding="utf-8") as f:
    #    lines = f.read().splitlines()
    #lines = [line.split("\t")[:-1] for line in lines]
    #datas = np.array(lines).astype(np.float32)
    ###
    
    # 数据正则化,让参与的数据减去均值出方差,是临均值,标准差成了1
    datas = StandardScaler().fit_transform(datas) #计算训练数据的均值和方差,并基于计算出来的均值和方差来转换训练数据,从而把数据转换成标准的正态分布
    eps = 0.3
    min_points = 10
    	#手动实现DBSCAN
    	#dbscan算法,labs是最终结果,cluster_id是分成了多少类
    labs, cluster_id = dbscan(datas, eps=eps, min_points=min_points)
    print("labs of my dbscan")
    print(labs)
    
    #sklearn里的DBSCAN 算法
    #分类器     # 半径      min_points           对datas进行聚类
    db = DBSCAN(eps=eps, min_samples=min_points).fit(datas)
    skl_labels = db.labels_
    print("labs of sk-DBSCAN")
    print(skl_labels)
    #画出 
    draw_cluster(datas,labs, cluster_id)

    # dbscan 输出,123表示聚类点,-1表示噪声点
    # sklearn 输出  012表示聚类点,-1表示噪声点

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DBSCAN算法,概念+示例,超详细!! 的相关文章

  • Python学习2——DBSCAN聚类算法

    一 原理 参考博文 xff1a DBSCAN聚类算法Python实现 徐奕的专栏 CSDN博客 dbscan python https blog csdn net xyisv article details 88918448 DBSCAN是
  • python DBSCAN聚类算法

    文章目录 DBSCAN聚类算法基本思想基本概念工作流程参数选择DBSCAN的优劣势 代码分析 61 61 Matplotlib Pyplot 61 61 61 61 make blobs 61 61 61 61 StandardScaler
  • 【数据挖掘】DBSCAN聚类算法(python实现)

    一 python代码 39 39 39 Author Vici date 2020 5 14 39 39 39 import math 39 39 39 Point类 xff0c 记录坐标x xff0c y和点的名字id 39 39 39
  • 【机器学习】DBSCAN聚类算法(含Python实现)

    文章目录 一 算法介绍二 例子三 Python实现3 1 例13 2 算法参数详解3 3 鸢尾花数据集 一 算法介绍 DBSCAN xff08 Density Based Spatial Clustering of Applications
  • DBSCAN聚类算法

    DBSCAN是一种非常著名的基于密度的聚类算法 其英文全称是 Density Based Spatial Clustering of Applications with Noise xff0c 意即 xff1a 一种基于密度 xff0c 对
  • DBSCAN聚类算法原理总结

    点击上方 小白学视觉 xff0c 选择加 34 星标 34 或 置顶 重磅干货 xff0c 第一时间送达 DBSCAN是基于密度空间的聚类算法 xff0c 在机器学习和数据挖掘领域有广泛的应用 xff0c 其聚类原理通俗点讲是每个簇类的密度
  • 备战数学建模44-聚类模型(攻坚站8)

    物以类聚 人以群分 所谓的聚类 就是将样本划分为由类似的对象组成的多个类的过程 聚类后 我们可以更加准确的在每个类中单独使用统计模型进行估计 分析或预测 也可以探究不同类之间的相关性和主要差异 聚类和上一讲分类的区别 分类是已知类别的 聚类
  • 【机器学习】DBSCAN密度聚类算法(理论 + 图解)

    文章目录 一 前言 二 DBSCAN聚类算法 三 DBSCAN算法步骤 四 算法的理解 五 常用评估方法 轮廓系数 一 前言 之前学聚类算法的时候 有层次聚类 系统聚类 K means聚类 K中心聚类 最后呢 被DBSCAN聚类算法迷上了
  • 解决:TypeError: '(slice(None, None, None), 1)' is an invalid key

    问题背景 使用matplotlib将DBSCAN分类结果散点图可视化时提示此TypeError 源代码 from sklearn cluster import DBSCAN import pandas as pd import matplo
  • “泰迪杯”挑战赛 - 通过聚类方法对航空客运的客户进行细分

    目 录 挖掘目标 分析方法与过程 2 1 总体流程 2 2 具体步骤 步骤一 数据预处理 步骤二 群体聚类 步骤三 行为特征聚类 2 3 结果分析 第一类 第二类 第三类 结论 参考文献 1 挖掘目标 本次建模目标是在航空公司的海量会员数据
  • DBSCAN点云聚类

    1 DBSCAN算法原理 DBSCAN是一种基于密度的聚类方法 其将点分为核心点与非核心点 后续采用类似区域增长方式进行处理 下图为DBSCAN聚类结果 可见其可以对任意类别的数据进行聚类 无需定义类别数量 DBSCAN聚类说明 DBSCA
  • 八种点云聚类方法(一)— DBSCAN

    本文为博主原创文章 未经博主允许不得转载 本文为专栏 python三维点云从基础到深度学习 系列文章 地址为 https blog csdn net suiyingy article details 124017716 传统机器学习聚类的方
  • DBSCAN sklearn 非常慢

    我正在尝试对包含超过 100 万个数据点的数据集进行聚类 一列包含文本 另一列包含与其对应的数值 我面临的问题是它被卡住并且永远不会完成 我尝试过处理大约 100 000 个较小的数据集 它运行得相当快 但当我开始增加数据点时 它开始变慢
  • ELKI:在 Java 中的自定义对象上运行 DBSCAN

    我正在尝试在 JAVA 中使用 ELKI 来运行 DBSCAN 为了进行测试 我使用了 FileBasedDatabaseConnection 现在我想使用我的自定义对象作为参数来运行 DBSCAN 我的对象具有以下结构 public cl
  • 如何在Python中绘制k距离图

    如何在 DBSCAN 中绘制 在 python 中 给定最小点值的距离图 我正在寻找拐点和相应的 epsilon 值 在 sklearn 中 我没有看到任何返回此类距离的方法 我错过了什么吗 您可能想使用 numpy 提供的矩阵运算来加速距
  • 在坐标和非空间特征上对地理空间数据进行聚类

    假设我将以下数据帧存储为称为坐标的变量 其中前几行如下所示 business lat business lng business rating 0 19 111841 72 910729 5 1 19 111342 72 908387 5
  • Python:3 维空间中的 DBSCAN

    我一直在寻找 3 维点的 DBSCAN 实现 但运气不佳 有谁知道我的图书馆可以处理这个问题或者有这方面的经验吗 我假设 DBSCAN 算法可以处理 3 个维度 通过将 e 值设置为半径度量并通过欧几里德分离测量点之间的距离 如果有人尝试过
  • DBSCAN 算法可以创建少于 minPts 的簇吗?

    我刚刚编写了 DBSCAN 算法 我想知道 DBSCAN 算法是否可以允许集群中的点数少于所使用的 minPts 参数 我一直在使用http people cs nctu edu tw rsliang dbscan testdatagen
  • 我很难理解 OPTICS 聚类算法中排序的概念

    我很难理解 OPTICS 聚类算法中排序的概念 如果有人对顺序给出逻辑和直观的解释 并解释什么 我将不胜感激res order下面的代码做了什么以及什么是可靠性图 可以通过命令 plot res 获得 library dbscan set
  • 使用纬度/经度对的自定义距离度量进行聚类

    我试图为 scikit learn DBSCAN 实现指定一个自定义聚类函数 def geodistance latLngA latLngB print latLngA latLngB return vincenty latLngA lat

随机推荐