DBSCAN算法,概念+示例,超详细!!
DBSCAN
(Density-Based Spatial Clustering of Applications with Noise)
与划分和层次聚类方法不同,它将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域划分为簇,并可在噪声的空间数据库中发现任意形状的聚类
算法流程
选取一个点,以eps为半径,画一个圈,看圈有几个临近点
若临近点个数大于某个阈值(min_points) ,则认为该点为某一簇的点;
若小于min_points,则被标记为噪声点,然后处理下一个点
将临近点作为种子点 seeds = [4,7,9,10 ]
遍历所有种子点
若该点被标记为噪声点 ,则重标为聚类点
若该点没有被标记过,则标记为聚类点
并且以该点为圆心,以eps为半径画圈,若圈内点大于min_points,则将圈内点添加到种子点中
seeds = [4,7,9,10,1,7,9,16]
重复步骤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]
.
.
.
重复进行画圈、标记
标记完一簇后
寻找一个未被标记的点,开始新一轮的聚类
如果找到点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 metricsUNCLASSIFIED = 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 = 0while i < len(seeds): Pn = seeds[i] #获取一个点if labs[Pn] == NOISE: #如果是噪声点,则重新标记labs[Pn] = cluster_idelif 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) #获取点与点之间的距离,且以二维数组的形式# 将所有点的标签初始化为0n_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__":## 数据1centers = [[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)#### 数据正则化,让参与的数据减去均值出方差,是临均值,标准差成了1datas = StandardScaler().fit_transform(datas) #计算训练数据的均值和方差,并基于计算出来的均值和方差来转换训练数据,从而把数据转换成标准的正态分布eps = 0.3min_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表示噪声点
DBSCAN算法,概念+示例,超详细!!相关推荐
- 点云处理算法整理(超详细教程)
点云处理算法整理(超详细教程) 目录 一. 线性回归_最小二乘法.梯度下降法 二. 线性回归_最小二乘法.RANSAC算法 三. 最近点迭代_ICP算法 四. 常见三角网格划分_voronoi图和De ...
- 单目标跟踪--KCF算法(核化相关滤波算法)Python实现(超详细)
Tracking-KCF Algorithm 注:本文涉及的算法的代码实践已上传至GitHub,恳求大佬们指点!^ _ ^ 1. 目标检测跟踪与算法背景概述 目标跟踪任务在许多的计算机视觉系统中都 ...
- Spark工作原理及基础概念(超详细!)
目录 一.Spark概述 (1)概述 (2)Spark整体架构 (3)Spark特性 (4)Spark与MR (5)Spark Streaming与Storm (6)Spark SQL与Hive 二. ...
- 点云处理算法整理(超详细教程)十大点云数据处理技术梳理
研究点云数据时,感觉无从下手? 看看这十大点云数据处理技术,换个思路学点云. 点云 · 定义 简言之,在获取物体表面每个采样点的空间坐标后,得到的是一个点的集合,称之为"点云".包 ...
- 十大经典排序算法----堆排序(超详细)
目录 1. 堆排序的基础知识 1.1 大顶堆&&小顶堆 1.2 向下调整算法 1.3 物理结构与逻辑结构的关系 2. 堆排序详解 2.1 堆排序整体思路 2.2 思路详解 2.2.1 ...
- 9种常用排序算法总结(超详细)
以int型数据为例,且0号下标数组用来做为交换辅助空间,数据从1号下标开始存储 一.插入排序 基本思想:每一趟将一个待排序的记录,按其关键字的大小插入到已经排好序的一组记录的适当位置上,直到全部待排序 ...
- Matlab实现DBSCAN算法(每行代码标注详细注解)
本文主要为了完成平日作业,并进一步加深对算法的理解.也希望对来访的读者有所帮助. 目录 一.什么是DBSCAN算法 二.DBSCAN算法的意义 三.DBSCAN算法代码解析 1.关键概念 2.大致思路 ...
- 决策树:CART决策树剪枝算法(超详细)
文章目录 CART算法 1. CART生成算法 2. CART剪枝算法 CART剪枝算法流程 CART剪枝算法解析( 超详细 ) CART算法 CART假设决策树是二叉树,内部结点特征的取值为&quo ...
- 数据挖掘领域十大经典算法之—SVM算法(超详细附代码)
相关文章: 数据挖掘领域十大经典算法之-C4.5算法(超详细附代码) 数据挖掘领域十大经典算法之-K-Means算法(超详细附代码) 数据挖掘领域十大经典算法之-Apriori算法 数据挖掘领域十大经 ...
- 数据挖掘领域十大经典算法之—AdaBoost算法(超详细附代码)
相关文章: 数据挖掘领域十大经典算法之-C4.5算法(超详细附代码) 数据挖掘领域十大经典算法之-K-Means算法(超详细附代码) 数据挖掘领域十大经典算法之-SVM算法(超详细附代码) 数据挖掘领 ...
最新文章
- cvpr2019/cvpr2018/cvpr2017(Papers/Codes/Project/Paper reading)
- python文件和目录操作方法大全(含实例)
- UVA - 12083 Guardian of Decency (二分匹配)
- Nemuria UML架构图 第2次迭代. 添加了缓冲层
- 高端android手机,高端机型很难选择?这几款手机就很不错,你肯定有中意的
- 受限玻尔兹曼机准备知识——MCMC方法和Gibbs采样
- android 服务自动结束,Android服务自动停止
- 加固工程验收规范50550_轻质隔墙怎样做才规范,看完这3点
- 【Java】Java中String、StringBuilder、StringBuffer三者的区别
- 我的开源项目:TS封装格式分析器
- CC2530 串口通信
- ElasticSearch7.8.0下载与安装
- 免费直播系统源码,可控的跑马灯,无需焦点
- 【IT领导力】IT 使命、愿景和价值观声明:成功的基础
- Django 使用 squashmigrations 合并 migration 文件
- 罗夏墨迹测验(转载)
- Android 函数响应式编程(RxJava3)
- 【汇正财经】大盘低开回升
- python数据分析入门【二】 --- 数据处理
- 后端返回amr格式音频前端处理播放播放(个人笔迹)
热门文章
- mapStruct 之 基本使用
- 云原生向量数据库Milvus(二)-数据与索引的处理流程、索引类型及Schema
- 解决命令行下载Google Drive大文件出现的问题
- vb.net 获取系统图标_优麒麟19.10.1正式发布:控制面板新增图标主题与字体高级设置...
- MySQL的字符串拼接函数
- 准备度假了吗?比防晒霜更重要的备忘清单
- IDEA配置Gitee
- 苹果前员工被控收回扣和欺诈 致公司损失上千万美元
- python运行测试文件unittest报错:空套件
- C++序列化与反序列化的简单探索