简 介:下面是我在学习时候的记录并加上自己的理解。本文意在记录自己近期学习过程中的所学所得,如有错误,欢迎大家指正。
关键词:Python、机器学习、密度聚类、DBSCAN
一、DBSCAN聚类
首先介绍以下密度聚类,它是基于我们数据的密度或者紧密程度进行分类,考虑数据样本的可连接性,然后进行不断地扩展每个簇完成聚类的任务。
基于密度算法的核心思想就是根据样本点某一邻域内的样本数定义样本的密度,该类算法可以实现那种不规则的空间聚类,比如说月牙型,而像K-Means这种聚类算法一般适用于那种样本成堆型的数据,而且它还有个优点就是不用指定簇的数量。
DBSCAN算法是一种非常著名的基于密度聚类方法,它是采用邻域半径以及邻域内样本数进行定义簇,一般采用 ϵ \epsilonϵ 代表邻域半径,用 M MM 进行表示邻域内的样本数阈值。
介绍几个相关的概念:
- 核心点(核心对象):如果以某个样本为中心,以预先设定的 ϵ \epsilonϵ 为半径,进行构造邻域,如果该邻域内的样本数大于我们设定的阈值M,那么该点就为核心点。
- 密度直达:某一核心点和它的邻域内的样本成为密度直达
- 密度可达:如果核心点A与B密度直达,而B与C密度直达,那么A和C为密度可达
- 密度相连:如果A与B密度可达,而B与C密度可达,那么A与C成为密度相连
DBSCAN的算法核心就是要构造一系列密度相连的样本,这些样本就会被分成一个簇。
如果一个样本数据既不是核心点也不属于任何一个核心点的邻域内,那么就称他为噪音点,该点是一个异常样本数据,偏于大多数的样本,它处在样本较为稀疏的区域。
下图最下方的点就是一个噪音点,他在整个算法过程中不参与,所有说DBSCAN不对异常值敏感,如果某样本处在较为稀疏的位置,它是不会被忽略掉的,不会被分到某一簇中。
二、算法的详细流程
算法实现的伪代码:
- 输入样本数据D(x1,x2,…xn)
- 设定参数 邻域半径r和样本数阈值M
- 初始化核心点集合 Ω = ∅ \Omega=\varnothingΩ=∅
- 迭代每个样本数据,判断是否为核心点,依据就是以r为半径,进行画邻域,判断邻域内的样本数是否大于M,如果大于M,则将其加入核心点集合中,否则跳过
- 初始化簇类数k=0
- 迭代核心点集合
- 然后将该核心点邻域内的样本全部加入队列中,如果邻域内的某一样本也为核心点,则将它邻域内的所有样本也加入到队列中,知道队列为空
- 刚才遍历到的所有样本全部归为1个簇中
- 然后遍历 Ω \OmegaΩ 中还剩下的核心点,知道所有的核心点都被遍历完
可以说每迭代一次大的循环,就会生成一个簇类,而且6-9步骤与BFS(广度优先搜索)采用队列实现非常相似,将相邻的节点入队,然后将当前节点出队,不断将对列中每个节点的相邻元素添加到队列,直到队列为空,迭代结束。
这里有个在线浏览的DBSCAN算法的实现流程的网址,它可以自己定义邻域半径和M,然后网站自动按照指定参数进行聚类。
[DBSCAN在线可视化网址](Visualizing DBSCAN Clustering (naftaliharris.com))
在实现过程中存在几个问题就是,初始的邻域半径和阈值M的设立,因为在初期我们无法知道数据的信息,所以对于参数的设立难以确定,所以这需要大量的探索测试和一定的数据经验。
但是它也有一些好处就是它无须指定簇的个数,因为它是基于密度,算法是按照核心点不断进行扩张领域来划分簇的,所以簇的个数和算法有关,也就是与邻域半径r和M有较大的关系,而且它还对噪声不敏感,因为噪声点既不是核心点也不属于某一邻域,所以算法在进行划分时,会忽略掉噪声的数据,而且进行确立密度时,它是以样本间的距离进行确定,如果我们的数据量过大,样本维数过高,可能在计算距离时造成内存溢出。