精华内容
下载资源
问答
  • SA-DBSCAN:一种自适应基于密度聚类算法.pdf
  • 结合基于划分的聚类算法基于密度聚类算法的优点,提出了基于密度聚类算法DBCKNN。算法利用了k近邻和离群度等概念,能够迅速确定数据集中每类的中心及其类半径,在保证聚类效果的基础上提高了聚类效率。
  • 基于密度聚类算法

    2018-05-07 14:08:22
    分析论文Clustering by fast search and find of density peaksd,整理局部密度聚类分析方法,对故障检测方向的学者提供帮助,重点分析该算法的有效性,如何用密度实现数据的聚类算法的步骤流程,注意事项,以及...
  • 主要介绍了Python基于聚类算法实现密度聚类(DBSCAN)计算,结合实例形式分析了聚类算法的相关概念、原理及使用聚类算法进行密度聚类计算的相关操作技巧,需要的朋友可以参考下
  • 基于密度聚类算法的照片分类技术.pdf
  • 基于密度聚类算法的轨道结构故障诊断研究.pdf
  • 基于密度聚类算法的规则计量罐容量测量方法.pdf
  • 基于密度聚类算法的校园人群聚集和移动规律分析.pdf
  • python实现基于密度的DBscan和K-means聚类算法,根据青蛙的叫声所提取的 MFCC 特征,给不同科属的青蛙聚类。包括数据集和代码。
  • 基于密度聚类算法DBSCAN的MATLAB 代码,可直接运行,聚类效果很好。提供月牙形数据的mat文件
  • 基于网格的聚类算法

    2021-01-27 15:10:58
    聚类算法很多,包括基于划分的聚类算法(如:kmeans),基于层次的聚类算法(如:BIRCH),基于密度聚类算法(如:DBScan),基于网格的聚类算法等等。基于划分和层次聚类方法都无法发现非凸面形状的簇,真正能...
  • 基于密度聚类算法的改进

    千次阅读 2016-07-28 22:45:44
    使用基于密度聚类算法,进行高维特征的聚类分析,从高维数据中提取出类似的有用信息,从而简化了特征数量,并且去除了部分冗余信息。 在聚类算法中,有这样几种算法: 划分的算法, K-Means 层次的方法, CURE 基于密度的...

    基于密度算法的改进

    本篇博客来自我的github小项目,如果对您有帮助,希望您前去点星 !

    使用基于密度的聚类算法,进行高维特征的聚类分析,从高维数据中提取出类似的有用信息,从而简化了特征数量,并且去除了部分冗余信息。
    在聚类算法中,有这样几种算法:

    • 划分的算法, K-Means
    • 层次的方法, CURE
    • 基于密度的算法, DBSCAN,DPCA(Desity Peaks Clusering Algorithm)
    • 基于网格的算法, CLIQUE
    • 基于模型的算法, 主要是一些概率的算法

    由Alex Rodriguez和Alessandro Laio发表的《Clustering by fast search and find of density peaks》的主要思想是寻找被低密度区域分离的高密度区域。
    基于这样的一种假设:
    对于一个数据集,聚类中心被一些低局部密度的数据点包围,而且这些低局部密度的点距离其他有高局部密度的点的距离都比较大。

    如何定义局部密度?

    找到与某个数据点之间的距离小于截断距离的数据点的数量

    如何寻找与高密度之间的距离?

    • 找到所有比第i个数据点局部密度都打的数据点中,与第i个数据点之间的距离最小的值;
    • 而对于有最大密度的数据点,通常取 σi=maxj(dij) ;

    如何确定聚类中心、外点?

    • DPCA中将那些具有较大距离 σi ,且同时具有较大局部密度的 ρi 的点定义为聚类中心。
    • 同时具有较高的距离,但是密度却较小的数据点称为异常点。
    • 根据论文中的决策图和乘积曲线去寻找潜在的聚类中心
      • 一条线中,去掉为零的部分,然后取出指定的前百分之几的数据即可
      • 将数据按照层次聚类,将曲线分层,找到可能的聚类中心

    Requirements

    1. g++-4.7以上版本
    2. 内存最好够大,因为至少要存储任意两个向量之间的距离
    3. 使用libopm进行算法的并行化,提高运行效率
    ## 程序运行的框架 算法的执行流程
    算法的执行框架

    程序运行展示

    ### 测试数据的分布 - 样本数据的展示
    原始测试数据的分布
    • 按照论文中的方法去寻找聚类中心
      按照论文中寻找聚类中心的结果图

    References

    1. Clustering by fast search and find of density peaks
    2. Science论文”Clustering by fast search and find of density peaks”学习笔记
    3. 发表在 Science 上的一种新聚类算法
    4. 超级赞的文章,写的很好!
    5. 论文中的机器学习算法——基于密度峰值的聚类算法
    6. Clustering datasets
    展开全文
  • 本节内容:本节内容是根据上学期所上的模式识别课程的作业整理而来,第一道题目是Kmeans聚类算法,数据集是Iris(鸢尾花的数据集),分类数k是3,数据维数是4。 关于聚类  聚类算法是这样的一种算法:给定样本数据...
  • Alex提出的基于局部密度的聚类算法是一种快速、有效的聚类方法,但该方法通过手工选取确定聚类个数和聚类中心。为此,对原算法进行改进,在初步选取候选聚类中心的基础上,使用基于密度连通的算法优化选取聚类中心,...
  • DBSCAN 是一种经典的基于密度聚类算法,能够自动确定簇的数量,对任意形状的簇都能有效处理。SA2DBSCAN 聚类算法,通过分析数据集统计特性来自动确定Eps 和minPts 参数
  • 基于DBSCAN密度聚类算法的高速公路交通流异常数据检测.pdf
  • 请引用为; Emre Güngör,Ahmet Özmen,使用高斯核的基于距离和密度聚类算法,In Expert Systems with Applications,第 69 卷,2017 年,第 10-20 页,ISSN 0957-4174, ... ...
  • 基于密度的聚类是聚类算法中的一种,其主要优点是可以发现任意形状的簇,但处理大数据集时效果不佳,为此提出了一种改进的算法M-DBSCAN,保留了基于密度聚类算法的优点,同时克服了以往算法不能处理大数据集的缺点。...
  • 一种基于密度峰值聚类的图像分割算法.pdf
  • 基于质心的聚类算法即K-Means聚类,聚集聚类和基于密度的空间聚类实现。 要求 Python 3.6及更高版本 科学工具学习 麻木 科学的 matplotlib 信息 通过智能融合完成的K-Means聚类可以加快处理速度,并多次运行以获得...
  • C++实现密度聚类算法

    2014-06-01 12:44:26
    用C++实现DBSCAN 密度聚类算法 ;调试通过
  • 上一篇博客提到 K-kmeans 算法存在好几个缺陷,其中之一就是该算法无法聚类哪些非凸的数据集,也就是说...通常情况下,密度聚类从样本密度的角度出来,来考查样本之间的可连接性,并基于可连接样本不断扩展聚类簇,...

          上一篇博客提到 K-kmeans 算法存在好几个缺陷,其中之一就是该算法无法聚类哪些非凸的数据集,也就是说,K-means 聚类的形状一般只能是球状的,不能推广到任意的形状。本文介绍一种基于密度的聚类方法,可以聚类任意的形状。

          基于密度的聚类是根据样本的密度分布来进行聚类。通常情况下,密度聚类从样本密度的角度出来,来考查样本之间的可连接性,并基于可连接样本不断扩展聚类簇,以获得最终的聚类结果。其中最著名的算法就是 DBSCAN 算法

    DBSCAN 算法有两个参数:半径 eps 和密度阈值 MinPts,具体步骤为:

    1、以每一个数据点 xi 为圆心,以 eps 为半径画一个圆圈。这个圆圈被称为 xi 的 eps 邻域

    2、对这个圆圈内包含的点进行计数。如果一个圆圈里面的点的数目超过了密度阈值 MinPts,那么将该圆圈的圆心记为核心点,又称核心对象。如果某个点的 eps 邻域内点的个数小于密度阈值但是落在核心点的邻域内,则称该点为边界点。既不是核心点也不是边界点的点,就是噪声点。

    3、核心点 xi 的 eps 邻域内的所有的点,都是 xi 的直接密度直达。如果 xj 由 xi 密度直达,xk 由 xj 密度直达。。。xn 由 xk 密度直达,那么,xn 由 xi 密度可达。这个性质说明了由密度直达的传递性,可以推导出密度可达。

    4、如果对于 xk,使 xi 和 xj 都可以由 xk 密度可达,那么,就称 xi 和 xj 密度相连。将密度相连的点连接在一起,就形成了我们的聚类簇。

     

          用更通俗易懂的话描述就是如果一个点的 eps 邻域内的点的总数小于阈值,那么该点就是低密度点。如果大于阈值,就是低密度点。如果一个高密度点在另外一个高密度点的邻域内,就直接把这两个高密度点相连,这是核心点。如果一个低密度点在高密度点的邻域内,就将低密度点连在距离它最近的高密度点上,这是边界点。不在任何高密度点的 eps  邻域内的低密度点,就是异常点。

          周志华《机器学习》书上给的伪代码如下。

     

    公式性有点强,用语义表达算法的伪码如下:

    1、根据 eps 邻域和密度阈值 MinPts ,判断一个点是核心点、边界点或者离群点。并将离群点删除

     

    2、如果核心点之间的距离小于 MinPts ,就将两个核心点连接在一起。这样就形成了若干组簇

     

    3、将边界点分配到距离它最近的核心点范围内

     

    4、形成最终的聚类结果

    DBSCAN 算法评价及改进

    DBSCAN优点:

    1、对噪声不敏感。这是因为该算法能够较好地判断离群点,并且即使错判离群点,对最终的聚类结果也没什么影响

    2、能发现任意形状的簇。这是因为DBSCAN 是靠不断连接邻域呢高密度点来发现簇的,只需要定义邻域大小和密度阈值,因此可以发现不同形状,不同大小的簇

     

    DBSCAN 缺点:

    1、对两个参数的设置敏感,即圈的半径 eps 、阈值 MinPts。

    2、DBSCAN 使用固定的参数识别聚类。显然,当聚类的稀疏程度不同,聚类效果也有很大不同。即数据密度不均匀时,很难使用该算法

    3、如果数据样本集越大,收敛时间越长。此时可以使用 KD 树优化

     

    Python  代码:

    
    from sklearn.datasets.samples_generator import make_circles
    import matplotlib.pyplot as plt
     
    import time
    from sklearn.cluster import KMeans
     
    from sklearn.cluster import DBSCAN
     
    X,y_true = make_circles(n_samples=1000,noise=0.15) #这是一个圆环形状的
     
    plt.scatter(X[:,0],X[:,1],c=y_true)
    plt.show()
     
    
    #DBSCAN 算法
    t0 = time.time()
    dbscan = DBSCAN(eps=.1,min_samples=6).fit(X)  # 该算法对应的两个参数
    t = time.time()-t0
    plt.scatter(X[:, 0], X[:, 1], c=dbscan.labels_)
    plt.title('time : %f'%t)
    plt.show()

    初始数据点分布是这样的:

    密度阈值均取 6,eps 分别为 0.01,0.05,0.2,0.8时的聚类效果

     

    来来来,你再看看 K-means 的聚类效果,对于非凸的数据聚类效果就是这个样子。。。

    du

     

    拓展阅读:

    1、为了解决 DBSCAN 很难聚类不同密度的簇,目前已经有很多新的方法被发明出来,比如OPTICS(Ordering points to identify the clustering structure)将邻域点按照密度大小进行排序,再用可视化的方法来发现不同密度的簇

    2、2014年Science杂志刊登了一种基于密度峰值的算法DP(Clustering by fast search and find of density peaks),也是采用可视化的方法来帮助查找不同密度的簇。其思想为每个簇都有个最大密度点为簇中心,每个簇中心都吸引并连接其周围密度较低的点,且不同的簇中心点都相对较远。为实现这个思想,它首先计算每个点的密度大小(也是数多少点在邻域eps-neigbourhood内),然后再计算每个点到其最近的且比它密度高的点的距离。这样对每个点我们都有两个属性值,一个是其本身密度值,一个是其到比它密度高的最近点的距离值。对这两个属性我们可以生成一个2维图表(决策图),那么在右上角的几个点就可以代表不同的簇的中心了,即密度高且离其他簇中心较远。然后我们可以把其他的点逐步连接到离其最近的且比它密度高的点,直到最后连到某个簇中心点为止。这样所有共享一个簇中心的点都属于一个簇,而离其他点较远且密度很低的点就是异常点了。由于这个方法是基于相对距离和相对密度来连接点的,所以其可以发现不同密度的簇。DP的缺陷就在于每个簇必须有个最大密度点作为簇中心点,如果一个簇的密度分布均与或者一个簇有多个密度高的点,其就会把某些簇分开成几个子簇。另外DP需要用户指定有多少个簇,在实际操作的时候需要不断尝试调整。

     

    话说,一个聚类算法就可以发 Science 了吗????哪位大佬帮我解释下

    展开全文
  • 密度聚类中的DBSCAN代码,根据周志华的《机器学习》中的伪代码编写,直接调用就可以使用,内部有注释
  • 基于密度聚类算法(如:DBSCAN)

    万次阅读 2018-07-09 12:54:12
    由于聚类是无监督学习方法,不同的聚类方法基于不同的假设和数据类型,比如...聚类算法很多,包括基于划分的聚类算法(如:k-means),基于层次的聚类算法(如:BIRCH),基于密度聚类算法(如:DBSCAN),基于...

    由于聚类是无监督学习方法,不同的聚类方法基于不同的假设和数据类型,比如基于。由于数据通常可以以不同的角度进行归类,因此没有万能的通用聚类算法,并且每一种聚类算法都有其局限性和偏见性。也就是说某种聚类算法可能在市场数据上效果很棒,但是在基因数据上就无能为力了。

    聚类算法很多,包括基于划分的聚类算法(如:k-means),基于层次的聚类算法(如:BIRCH),基于密度的聚类算法(如:DBSCAN),基于网格的聚类算法( 如:STING )等等。本文将介绍聚类中一种最常用的方法——基于密度的聚类方法(density-based clustering)。

    2、DBSCAN原理及其实现

    相比其他的聚类方法,基于密度的聚类方法可以在有噪音的数据中发现各种形状和各种大小的簇。DBSCAN(Ester, 1996)是该类方法中最典型的代表算法之一(DBSCAN获得2014 SIGKDD Test of Time Award)。其核心思想就是先发现密度较高的点,然后把相近的高密度点逐步都连成一片,进而生成各种簇。算法实现上就是,对每个数据点为圆心,以eps为半径画个圈(称为邻域eps-neigbourhood),然后数有多少个点在这个圈内,这个数就是该点密度值。然后我们可以选取一个密度阈值MinPts,如圈内点数小于MinPts的圆心点为低密度的点,而大于或等于MinPts的圆心点高密度的点(称为核心点Core point)。如果有一个高密度的点在另一个高密度的点的圈内,我们就把这两个点连接起来,这样我们可以把好多点不断地串联出来。之后,如果有低密度的点也在高密度的点的圈内,把它也连到最近的高密度点上,称之为边界点。这样所有能连到一起的点就成一了个簇,而不在任何高密度点的圈内的低密度点就是异常点。下图展示了DBSCAN的工作原理。

    这里写图片描述
    当设置MinPts=4的时候,红点为高密度点,蓝点为异常点,黄点为边界点。红黄点串成一起成了一个簇。

    由于DBSCAN是靠不断连接邻域内高密度点来发现簇的,只需要定义邻域大小和密度阈值,因此可以发现不同形状,不同大小的簇。下图展示了一个二维空间的DBSCAN聚类结果。

    这里写图片描述
    DBSCAN可以发现2个弧形的簇

    DBSCAN算法伪码表达如下:

    这里写图片描述

    DBSCAN实现伪码(来源: Han 2011)

    3、发现不同密度的簇

    由于DBSCAN使用的是全局的密度阈值MinPts, 因此只能发现密度不少于MinPts的点组成的簇,即很难发现不同密度的簇。其成功与失败的情况举例如下:

    这里写图片描述

    左图有三个簇,一个全局密度阈值可以把三个簇分开。但是在右图中,一个阈值无法把三个簇分开,过高的阈值会把C3全部变成异常点,过低的阈值会把C1和C2合并起来。(来源: http://www.sciencedirect.com/science/article/pii/S0031320316301571

    为了解决其发现不同密度的簇,目前已经有很多新的方法被发明出来,比如OPTICS(Ordering points to identify the clustering structure)将邻域点按照密度大小进行排序,再用可视化的方法来发现不同密度的簇,如下图所示。OPTICS必须由其他的算法在可视化的图上查找“山谷”来发现簇,因此其性能直接受这些算法的约束。

    这里写图片描述
    OPTICS将数据以密度的形式排序并展示,不同的山谷就是不同密度大小的簇。(来源: https://en.wikipedia.org/wiki/OPTICS_algorithm

    另外SNN采用一种基于KNN(最近邻)来算相似度的方法来改进DBSCAN。对于每个点,我们在空间内找出离其最近的k个点(称为k近邻点)。两个点之间相似度就是数这两个点共享了多少个k近邻点。如果这两个点没有共享k近邻点或者这两个点都不是对方的k近邻点,那么这两个点相似度就是0。然后我们把DBSCAN里面的距离公式替换成SNN相似度,重新算每个点的邻域和密度,就可以发现不同密度的簇了。SNN的核心就是,把原始的密度计算替换成基于每对点之间共享的邻域的范围,而忽略其真实的密度分布。SNN的缺点就是必须定义最近邻个数k, 而且其性能对k的大小很敏感。下图展示了SNN计算相似度的方法。



    这里写图片描述

    i 点和 j 点共享4个近邻点,所以它们相似度为4


    2014年Science杂志刊登了一种基于密度峰值的算法DP(Clustering by fast search and find of density peaks),也是采用可视化的方法来帮助查找不同密度的簇。其思想为每个簇都有个最大密度点为簇中心,每个簇中心都吸引并连接其周围密度较低的点,且不同的簇中心点都相对较远。为实现这个思想,它首先计算每个点的密度大小(也是数多少点在邻域eps-neigbourhood内),然后再计算每个点到其最近的且比它密度高的点的距离。这样对每个点我们都有两个属性值,一个是其本身密度值,一个是其到比它密度高的最近点的距离值。对这两个属性我们可以生成一个2维图表(决策图),那么在右上角的几个点就可以代表不同的簇的中心了,即密度高且离其他簇中心较远。然后我们可以把其他的点逐步连接到离其最近的且比它密度高的点,直到最后连到某个簇中心点为止。这样所有共享一个簇中心的点都属于一个簇,而离其他点较远且密度很低的点就是异常点了。由于这个方法是基于相对距离和相对密度来连接点的,所以其可以发现不同密度的簇。DP的缺陷就在于每个簇必须有个最大密度点作为簇中心点,如果一个簇的密度分布均与或者一个簇有多个密度高的点,其就会把某些簇分开成几个子簇。另外DP需要用户指定有多少个簇,在实际操作的时候需要不断尝试调整。下图展示了一个DP生成的决策图。



    这里写图片描述

    左图为5个簇的分布,右图为DP生成的决策图,其右上角5个点就是左图五个簇的中心点。(来源: http://science.sciencemag.org/content/344/6191/1492


    除此之外,还可以用密度比估计(Density-ratio estimation)来克服DBSCAN无法发现不同密度簇的缺陷。密度比的核心思想就是对每个点,计算其密度与其邻域密度的比率,然后用密度比计算替换DBSCAN的密度计算来发现核心点Core point,而其他过程和DBSCAN不变。这样一来,每个局部高密度点就会被选出来作为核心点,从而发现不同密度的簇。基于这个思想,我们还可以把原始数据按其密度分布进行标准化(ReScale),即把密度高的区域进行扩张,密度低的区域继续收缩。这样以来,不同密度的簇就可以变成密度相近的簇了,我们再在标准化后的数据上直接跑DBSCAN就搞定了。这种方法需要用户设置邻域范围来计算密度比,下图展示了标准化前后的数据分布对比。

    这里写图片描述
    不同密度的簇在(ReScale)标准化后,变成密度相近的簇,进而DBSCAN可以用全局阈值发现不同的簇

    4、讨论

    基于密度的聚类是一种非常直观的聚类方法,即把临近的密度高的区域练成一片形成簇。该方法可以找到各种大小各种形状的簇,并且具有一定的抗噪音特性。在日常应用中,可以用不同的索引方法或用基于网格的方法来加速密度估计,提高聚类的速度。基于密度的聚类也可以用在流数据和分布式数据中,关于其他方向的应用,详见(Aggarwal 2013).

    5、源码下载 (Matlab)

    DP: https://au.mathworks.com/matlabcentral/fileexchange/53922-densityclust

    DBSCAN, SNN, OPTICS 和 Density-ratio: https://sourceforge.net/projects/density-ratio/

    展开全文
  • 密度聚类算法dbscan是基于周志华老师《机器学习》介绍编程的,经检验效率较高
  • 聚类分析:基于密度聚类的DBSCAN算法

    万次阅读 多人点赞 2018-05-15 10:09:15
    对于簇形状不规则的数据,像k-means(聚类分析: k-means算法)这种基于划分的方法就不再适用了,因为划分方法(包括层次聚类算法)都是用于发现“球状簇”的。比如下面两个图中,Fig.1所示的数据分布用k-means作聚类...

    对于簇形状不规则的数据,像k-means(聚类分析: k-means算法)这种基于划分的方法就不再适用了,因为划分方法(包括层次聚类算法)都是用于发现“球状簇”的。比如下面两个图中,Fig.1所示的数据分布用k-means作聚类是没有问题的,但是对于Fig.2就不行了,会把大量的噪声或者离群点也包含在簇中。


    解决这种任意簇形状的聚类问题,就要采用一种与划分聚类或者层次聚类不同的聚类方法——基于密度聚类。对于基于密度的聚类,最常用的算法就是本文要说的DBSCAN(Density-Based Spatial Clustering of Application with Noise),简单直译过来就是“具有噪声应用的基于密度的空间聚类”。

    概念介绍

    在讲解DBSCAN具体的工作原理之前,先介绍关于这个算法的一些专门定义的概念。

    • 核心对象:一个数据点可被称为核心对象,如果以这个数据点为球心,以长度 ϵ ϵ 为半径的超球面区域内,至少有 MinPts M i n P t s 个数据点。为了后面叙述简单,我将这个核心对象称为 (ϵ,MinPts) ( ϵ , M i n P t s ) -核心对象,将它的这个球面区域称为核心对象的 ϵ ϵ -邻域。

    • 直接密度可达:对于 (ϵ,MinPts) ( ϵ , M i n P t s ) -核心对象 O1 O 1 和对象 O2 O 2 ,我们说 O2 O 2 是从 O1 O 1 直接密度可达的,如果 O2 O 2 O1 O 1 ϵ ϵ -邻域内。注意,这里只要求 O1 O 1 是核心对象,而 O2 O 2 可以是任意对象(数据点)。也就是说,定义“A从B(或从B到A)直接密度可达”中,作为出发点的 B B 一定得是核心对象。

    • 密度可达:从核心对象O1到对象 On O n (这里同样不要求 On O n 是核心对象)是密度可达的,如果存在一组对象链 {O1,O2,,On} { O 1 , O 2 , … , O n } ,其中 Oi O i Oi+1 O i + 1 都是关于 (ϵ,MinPts) ( ϵ , M i n P t s ) 直接密度可达的。实际上,从这个定义我们不难看出, {O1,O2,,On1} { O 1 , O 2 , … , O n − 1 } 都必须是核心对象。

    • 密度相连:两个对象 O1,O2 O 1 , O 2 (注意,这里不要求是核心对象)是密度相连的,如果存在一个对象 p p ,使得p O1 O 1 p p O2都是密度可达的。这个定义是对称的,即 O1 O 1 O2 O 2 是密度相连的,则 O2 O 2 O1 O 1 也是密度相连的。

    上面4个定义中,后两个容易混淆。其实可以这样想,所谓密度可达,是说可以“一条道”走过去;而所谓密度相连,是说可以找到一个中间点,从这个中间点出发,可以分别“一条道”走到两边。

    关于密度相连的理解是整个DBSCAN算法的核心,他实际代表的意义可以这样理解:对于任意形状的簇来说,一定存在这样一个点,使得组成这个簇的点都能从这个点出发,通过一条“稠密”的路径到达。换句话说,簇中的点一定是相互密度相连的。

    还有两个区别于“核心对象”的概念,那就是“噪声对象”和“边缘对象”。在用DBSCAN对数据做聚类分析时,“噪声对象”也是一个非常重要的结果。所以,最好的算法是在给出聚好的类之外,也给出噪声点。为了让整个算法看起来清晰,我在讲解算法步骤之前,先给出“噪声对象”和“边缘对象”的定义。

    • 噪声对象:不是核心对象,且也不在任何一个核心对象的 ϵ ϵ -邻域内;
    • 边缘对象:顾名思义是类的边缘点,它不是核心对象,但在某一个核心对象的 ϵ ϵ -邻域内;

    总之,对于数据集中的任意一个点,它要么是核心对象,要么是噪声对象,要么是边缘对象。

    算法思路

    现在我们来思考怎样解决非球状簇的聚类问题。直观上来想象,既然是要找任意形状的簇,那么最直接的办法是先找到一个核心对象,再找到与这个核心对象密度相连的所有点,这些点将构成这个簇。比如下图中,假设当前我们要找的簇是外层的圆圈,很显然,内层圆上的点与外层圆圈上的点肯定不是密度相连的,而且其他的离群点与外层这个圆圈的点也不是密度相连的。所以,只要我们选择合适的参数,就一定可以通过簇中的任意一个核心对象,拓展找到所有的簇中所有的点(当然,这些点都是密度相连的)。


    具体算法的工作原理可以这样来设计:

    初始化阶段,给所有数据点赋一个unvisited的属性,表示这个数据点未被访问;

    1.在所有属性为unvisited的点集中,随机找一个点 p p ,标记为visited

    2.检查它是否为核心对象,若不是,标记p为噪声点,再重新开始寻找(像第1步中那样);若是,则执行后面的步骤;

    注1:前两部的目的在于找到一个核心对象,作为一个新簇的初始(第一个)对象。
    注2:2步中标记为噪声的点不一定真的是噪声点,它也有可能是边缘点,所以如果要得到准确的噪声集合,需要在后面做进一步筛选。

    既然找到了第一个核心对象,接下来的步骤就是创建第一个类了(记为 C C ):

    3.建立一个候选集Candidates,初始时, Candidates C a n d i d a t e s 中只有一个元素,那就是上一步找到的核心对象;

    4.对于 Candidates C a n d i d a t e s 中的每一个对象(记为 p p ),做以下操作:
    (1) 若p还未被聚到任意一个类,则加入类 C C
    (2) 若p是核心对象,则将它的 ϵ ϵ -邻域内的,除了当前类 C C 的点之外的点(也就是CandidatesC)加入 Candidates C a n d i d a t e s
    (3) 若 p p 在噪声集合内,将它从噪声集合移除(因为肯定不是噪声);
    (4) 若p的属性是unvisited,则标记为visited

    注:(3)(4)两步属于常规操作,无需多想,重点在于(1)(2)步。因为 Candidates C a n d i d a t e s 中的每一个对象要么是核心对象,要么是核心对象的 ϵ ϵ -邻域内的点,所以肯定和其核心对象是直接密度可达的,进而可以知道 Candidates C a n d i d a t e s 中的这些点都是密度相连的。所以当 p p 还不属于任何类时,我们可以毫不犹豫地将p加入类 C C ;(2)步中需要注意的是,因为当前类C的点已经分析过了,所以不用再次加入 Candidates C a n d i d a t e s 了,否则会导致一个死循环。

    5.循环执行第4步,直到 Candidates C a n d i d a t e s 中找不到核心对象为止,这说明当前这个类已经被找完全了。

    6.返回第1步,开始找下一个簇。直到所有的点都变成visited.

    代码实现

    下面,我将给出实现代码。首先,为了验证代码的正确性,我造了一个数据集(没办法,找资料的能力差,实在在网上找不到特别合适的),这个数据集的图像画出来如下图所示:


    具体的数据集我保存了一个csv文件,在文章最后给出的我的github主页里,名字叫”data.csv”。然后根据上面算法的工作原理,给出实现代码。

    首先是建一个数据对象的类,方便写后面的算法:

    import numpy as np
    
    
    class DataPoint(object):
        def __init__(self, coordinates):
            """
            :param coordinates: the ndarray object
            """
            self.coordinates = coordinates
            self.neighborhood = set()
    
        def isCore(self, db, radius, minPts):
            """
    
            :param db: the database whose elements are DataPoint objects.
            :param radius: the radius of a point's neighborhood
            :param minPts:
            :return:
            """
            for i in db:
                if np.linalg.norm(self.coordinates - i.coordinates) <= radius:
                    self.neighborhood.add(i)
    
            if len(self.neighborhood) >= minPts:
                return True
            return False
    

    然后给出聚类算法:

    def dbscan(db, radius, minPts):
        """
    
        :param db:
        :param radius:
        :param minPts:
        :return:
        """
        visited = set()
        noise = set()
        results = []
    
        while len(visited) < len(db):
    
            core = None
            C = set()
    
            # find the core point
            temp = set()
            for point in db - visited:
                temp.add(point)
                if point.isCore(db - {point}, radius, minPts):
                    core = point
                    break
                else:
                    noise.add(point)
            visited.update(temp)
    
            # can't find any core point, i.e., the cluster process should be terminated
            if not core:
                break
    
            # construct the new cluster C
            flag = True
            candidates = {core}
    
            # flag denotes whether there is at least one core point in candidates
            while flag:
    
                flag = False
                tempCandidates = set()
                for member in candidates:
    
                    # remove the boundary points in noise
                    if member in noise:
                        noise.remove(member)
    
                    # label the cur as visited
                    if member not in visited:
                        visited.add(member)
    
                    # if cur not belongs to other clusters, add it in the cluster C
                    belongToOtherCluster = False
                    for cluster in results:
                        if member in cluster:
                            belongToOtherCluster = True
                            break
                    if not belongToOtherCluster:
                        C.add(member)
    
                    # if cur is core, add its neighborhood in tempCandidates
                    if member.isCore(db - {member}, radius, minPts):
                        tempCandidates.update(member.neighborhood - C)
                        flag = True
                candidates = set() | tempCandidates
            results.append(C)
        return results

    根据我的数据点,我调整参数 (ϵ,MinPts) ( ϵ , M i n P t s ) (0.2,3) ( 0.2 , 3 ) ,最后清晰地得到两个类,作图如下:


    完整的实现代码,包括如何生成数据集,DBSCAN算法,还有作图的函数都在我的github主页里:DBSCAN,欢迎大家参考挑错。

    展开全文
  • 基于密度聚类的HMM协作频谱预测算法.pdf
  • 首先介绍传统距离计算方法在聚类应用中的不足,并针对这点提出一种基于权重向量的相对距离计算方法。在应用DBSCAN算法的基础上,融入相对距离的计算及k-d树的范围查找的应用。该算法不仅能得到很好的聚类效果,而且...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,975
精华内容 5,990
关键字:

基于密度的聚类算法