dbscan 订阅
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法。与划分和层次聚类方法不同,它将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域划分为簇,并可在噪声的空间数据库中发现任意形状的聚类。 展开全文
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法。与划分和层次聚类方法不同,它将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域划分为簇,并可在噪声的空间数据库中发现任意形状的聚类。
信息
外文名
Density-Based Spatial Clustering of Applications with Noise [1]
简    称
DBSCAN
定    义
密度相连的点的最大集合
中文名
聚类算法
性    质
有代表性的基于密度的聚类算法
涉及知识
Ε邻域、核心对象、直接密度可达、密度可达、密度相连
DBSCAN概念
DBSCAN中的几个定义:Ε邻域:给定对象半径为Ε内的区域称为该对象的Ε邻域;核心对象:如果给定对象Ε邻域内的样本点数大于等于MinPts,则称该对象为核心对象;直接密度可达:对于样本集合D,如果样本点q在p的Ε邻域内,并且p为核心对象,那么对象q从对象p直接密度可达。密度可达:对于样本集合D,给定一串样本点p1,p2….pn,p= p1,q= pn,假如对象pi从pi-1直接密度可达,那么对象q从对象p密度可达。密度相连:存在样本集合D中的一点o,如果对象o到对象p和对象q都是密度可达的,那么p和q密度相联。可以发现,密度可达是直接密度可达的传递闭包,并且这种关系是非对称的。密度相连是对称关系。DBSCAN目的是找到密度相连对象的最大集合。Eg: 假设半径Ε=3,MinPts=3,点p的E邻域中有点{m,p,p1,p2,o}, 点m的E邻域中有点{m,q,p,m1,m2},点q的E邻域中有点{q,m},点o的E邻域中有点{o,p,s},点s的E邻域中有点{o,s,s1}.那么核心对象有p,m,o,s(q不是核心对象,因为它对应的E邻域中点数量等于2,小于MinPts=3);点m从点p直接密度可达,因为m在p的E邻域内,并且p为核心对象;点q从点p密度可达,因为点q从点m直接密度可达,并且点m从点p直接密度可达;点q到点s密度相连,因为点q从点p密度可达,并且s从点p密度可达。
收起全文
精华内容
下载资源
问答
  • DBSCAN

    2021-05-11 14:56:41
    DBSCAN
  • dbscan

    2021-03-29 14:13:16
    dbscan(密度聚类) 什么是聚类 聚类是无监督学习的一个小分支,其本质就是将样本通过亲近程度对其进行分类,你可能会有疑问?分多少类别?亲近程度如何衡量? 分多少类 至于分多少类,有的是自动学习得到,比如...

    dbscan(密度聚类)

    什么是聚类

    聚类是无监督学习的一个小分支,其本质就是将样本通过亲近程度对其进行分类,你可能会有疑问?分多少类别?亲近程度如何衡量?

    分多少类

    至于分多少类,有的是自动学习得到,比如DBSCAN等,有的是手动指定,比如K-means等。后续的代码中会有体现

    亲近关系的衡量指标

    至于用什么来衡量亲近程度?对于有序属性的样本,可以使用闵可夫斯基距离、欧几里得距离、曼哈顿距离来描述,对于无序属性样本,可使用VDM,下面简单介绍一个闵可夫斯基距离。
    闵可夫斯基距离公式
    dmk(xi,xj)=(u=1nxiuxjup)1pd_{mk}(x_{i},x_{j})=\left ( \sum_{u=1}^{n} \left | x_{iu} -x_{ju} \right | ^{p} \right ) ^{\frac{1}{p} }

    其中
    xix_{i}: 第i个样本;
    xjx_{j}: 第j个样本;
    xiux_{iu}: 第i个样本的第u个特征;
    xjux_{ju}: 第j个样本的第u个特征;

    当p=2时,就是欧几里得距离公式,当p=1时,就是曼哈顿距离,在实际应用中,通常都是采用欧几里得距离或是曼哈顿距离。
    最后再多一点解释,关于什么是无序样本和有序样本,无序样本,其实可以理解为就是不能直接测量出数据的样本,比如一个样本的特征并不能用数字表示{性格,家庭住址,婚否}。有序样本,可以直观理解为特征都是数字,比如以坐标作为一个样本,其中x,y就是其特征,都是数字,有数字自然可以计算距离。

    DBSCAN(密度聚类)

    DBSCAN是无监督学习的一种算法,利用给定领域和最小领域样本数,最终将样本分为多个类。

    在这里插入图片描述

    与K-means区别

    不用像K-means一样,需要给定分类数和迭代次数,而是需要指定两个参数:(ϵ,MinPts)\left ( \epsilon ,MinPts \right )
    分类目的:根据图中所示,可以通俗的说,就是找到一个中心点,在以ϵ\epsilon为半径画圆,如果在这个圆内的点数至少有MinPts时候,就表示一个类分类完成。否则这个中心点不合格,分割失败,要重新寻找中心点。

    算法流程

    1.设置(ϵ,MinPts)\left ( \epsilon ,MinPts \right ) 参数
    2.遍历样本集,以这个点为中心,如果其他样本有多个与中心的距离小于ϵ\epsilon,且这样的样本个数不少于MinPts,则这个样本就是第一个中心点,停止遍历。
    3.以选出的样本为中心,遍历除此之外的整个样本集合(注意,这里的遍历和第二步的遍历不一样,第二步如果一开始就找到中心点,其实不用完全遍历),找出所有与中心距离小于ϵ\epsilon的样本,将此归为一类。
    4.讲分好类的样本从整体样本集合中减去,然后重复2、3步,直到待分类样本集合为空位置。分类结束。

    具体举例

    假设待分类样本集合为D=x1x2x3x4x5x6x7x8x9x10x11x12x_{1}、x_{2}、x_{3}、x_{4}、x_{5}、x_{6}、x_{7}、x_{8}、x_{9}、x_{10}、x_{11}、x_{12}
    1.设定(ϵ,MinPts)\left ( \epsilon ,MinPts \right )为(0.8,2),表示半径最大为0.8,分类中,每个类最少2个样本。
    2.遍历样本集合D,首先取出x1x_{1},计算与其他样本的距离,判断小于0.8的样本个数是否不少于2,加入满足条件,x1x_{1}就是中心点,停止遍历。
    3.遍历样本集合D,以x1x_{1}为中心,假如与x6x4x10x12x_{6}、x_{4}、x_{10}、x_{12}距离小于0.8.则为一类C1C_{1}={x1x6x4x10x12x_{1}、x_{6}、x_{4}、x_{10}、x_{12}}。
    4.将分好类的样本从集合中减去,D=x2x3x5x7x8x9x11x_{2}、x_{3}、x_{5}、x_{7}、x_{8}、x_{9}、x_{11}。重复第2部,找到新的中心点,重复第3步,这样第二个类就分好了,重复2、3步,直到集合D为0.

    DBSCAN程序示例代码

    
    import matplotlib.pyplot as plt
    import matplotlib as mpl
    import scipy.io
    from sklearn.cluster import DBSCAN
    
    def loaddata():
       data = scipy.io.loadmat('cluster_data.mat')
       return data['X']
    
    
    X = loaddata()
    #参数1:就是文中的$\epsilon$
    #参数2:就是文中的MinPts
    #参数3:亲密度衡量方式,也就是距离计算公式
    model = DBSCAN(eps=0.5, min_samples=5, metric='euclidean')
    model.fit(X)
    print('每个样本所属的簇:',model.labels_)
    
    cm_dark = mpl.colors.ListedColormap(['g','r','b','c'])
    plt.scatter(X[:, 0], X[:, 1], c=model.labels_, cmap=cm_dark, s=20)
    plt.show()
    
    

    补充

    核心对象:就是我们选出来的中心,满足的要求上面已经介绍过。
    密度直达:核心对象与领域内的每个点都是密度直达,可以理解为,在这个圆内的点和中心都是密度直达,其他的不叫密度直达。
    密度可达:在同一个领域内的所有点,两个点可以通过中心相连,这样就是密度可达,所以可以理解为,这个圆内除了中心外的两个点都是密度可达。
    密度相连:相比于密度可达,区别在于,点之间是在不同领域,不同领域的点可以通过多个领域的核心对象点将其相连,也就是不同园内的点,可以通过圆心最终相连。这就是密度可达。

    展开全文
  • DBSCAN-源码

    2021-03-06 19:11:17
    DBSCAN
  • DBSCAN聚类算法三部分: 1、DBSCAN原理、流程、参数设置、优缺点以及算法; 2、matlab代码实现; 3、C++代码实现及与matlab实例结果比较。 摘要:介绍DBSCAN原理、流程、参数设置、优缺点以及算法的matlab和C++代码...

    DBSCAN聚类算法三部分:

    1、        DBSCAN原理、流程、参数设置、优缺点以及算法;

    http://blog.csdn.net/zhouxianen1987/article/details/68945844

    2、        matlab代码实现; 

    blog:http://blog.csdn.net/zhouxianen1987/article/details/68946169

    codehttp://download.csdn.net/detail/zhouxianen1987/9789230

    3、        C++代码实现及与matlab实例结果比较。

    blog:http://blog.csdn.net/zhouxianen1987/article/details/68946278

           codehttp://download.csdn.net/detail/zhouxianen1987/9789231


    DBSCAN(Density-based spatial clustering ofapplications with noise)Martin Ester, Hans-PeterKriegel等人于1996年提出的一种基于密度的空间的数据聚类方法,该算法是最常用的一种聚类方法[1,2]。该算法将具有足够密度区域作为距离中心,不断生长该区域,算法基于一个事实:一个聚类可以由其中的任何核心对象唯一确定[4]。该算法利用基于密度的聚类的概念,即要求聚类空间中的一定区域内所包含对象(点或其他空间对象)的数目不小于某一给定阈值。该方法能在具有噪声的空间数据库中发现任意形状的簇,可将密度足够大的相邻区域连接,能有效处理异常数据,主要用于对空间数据的聚类,优缺点总结如下[3,4]:

    优点

    1)聚类速度快且能够有效处理噪声点和发现任意形状的空间聚类;

    2)与K-MEANS比较起来,不需要输入要划分的聚类个数;

    3)聚类簇的形状没有偏倚;

    4)可以在需要时输入过滤噪声的参数。

    缺点:

    1)当数据量增大时,要求较大的内存支持I/O消耗也很大;

    2)当空间聚类的密度不均匀、聚类间距差相差很大时,聚类质量较差,因为这种情况下参数MinPtsEps选取困难。

    3)算法聚类效果依赖与距离公式选取,实际应用中常用欧式距离,对于高维数据,存在维数灾难

    基本概念[5]如下基本概念在[6]中有更为详细说明介绍。

    1Eps邻域:给定对象半径Eps内的邻域称为该对象的Eps邻域;

    2)核心点(core point):如果对象的Eps邻域至少包含最小数目MinPts的对象,则称该对象为核心对象;

    3)边界点(edge point):边界点不是核心点,但落在某个核心点的邻域内;

    4)噪音点(outlier point):既不是核心点,也不是边界点的任何点;

    5)直接密度可达(directly density-reachable):给定一个对象集合D,如果pqEps邻域内,而q是一个核心对象,则称对象p从对象q出发时是直接密度可达的;

    6)密度可达(density-reachable):如果存在一个对象链  p1, …,pi,.., pn,满足p1 = p pn = qpi是从pi+1关于EpsMinPts直接密度可达的,则对象p是从对象q关于EpsMinPts密度可达的;

    7)密度相连(density-connected):如果存在对象OD,使对象pq都是从O关于EpsMinPts密度可达的,那么对象pq是关于EpsMinPts密度相连的。

    8)类(cluster:设非空集合,若满足:

    a,且密度可达,那么
    b密度相连。
    则称构成一个类簇

    有关核心点、边界点、噪音点以及直接密度可达、密度可达和密度相连解释如图1[1]

    1红色为核心点,黄色为边界点,蓝色为噪音点,minPts = 4Eps是图中圆的半径大小有关直接密度可达”和“密度可达”定义实例如图2所示[5]其中,Eps用一个相应的半径表示,设MinPts=3,请分析Q,M,P,S,O,R5个样本点之间的关系。

    2   “直接密度可达”和“密度可达”概念示意描述。根据前文基本概念的描述知道:由于有标记的各点­MPOREps近邻均包含3个以上的点,因此它们都是核对象;是从P“直接密度可达”;而Q则是从­M“直接密度可达”;基于上述结果,Q是从P“密度可达”;但PQ无法“密度可达”(非对称)。类似地,SRO是“密度可达”的;ORS均是“密度相连”(对称)的。

     

    DBSCAN算法原理[5]

    1DBSCAN通过检查数据集中每点的Eps邻域来搜索簇,如果点pEps邻域包含的点多于MinPts个,则创建一个以p为核心对象的簇;

    2)然后,DBSCAN迭代地聚集从这些核心对象直接密度可达的对象,这个过程可能涉及一些密度可达簇的合并;

    3)当没有新的点添加到任何簇时,该过程结束。

     

    有关算法的伪代码wiki百科中给出了,[5]用中文描述了其流程:

    DBSCAN算法伪代码描述:

    输入:数据集D,给定点在邻域内成为核心对象的最小邻域点数:MinPts,邻域半径:Eps   

    输出:簇集合

    (1) 首先将数据集D中的所有对象标记为未处理状态
    (2) for(数据集D中每个对象p) do
    (3)    if (p已经归入某个簇或标记为噪声) then
    (4)         continue;
    (5)    else
    (6)         检查对象p的Eps邻域 NEps(p) ;
    (7)         if (NEps(p)包含的对象数小于MinPts) then
    (8)                  标记对象p为边界点或噪声点;
    (9)         else
    (10)                 标记对象p为核心点,并建立新簇C, 并将p邻域内所有点加入C
    (11)                 for (NEps(p)中所有尚未被处理的对象q)  do
    (12)                       检查其Eps邻域NEps(q),若NEps(q)包含至少MinPts个对象,则将NEps(q)中未归入任何一个簇的对象加入C;
    (13)                 end for
    (14)        end if
    (15)    end if
    (16) end for

    wiki百科中代码描述:

    DBSCAN(D, eps, MinPts) {
       C = 0
       foreach point P in dataset D {
          ifP is visited
            continue next point
         mark P as visited
          NeighborPts = regionQuery(P, eps)
          ifsizeof(NeighborPts) < MinPts
            mark P as NOISE
         else {
            C = next cluster
            expandCluster(P, NeighborPts, C, eps, MinPts)
          }
       }
    }
     
    expandCluster(P, NeighborPts, C, eps, MinPts) {
       add Pto cluster C
       foreach point P' in NeighborPts {
          ifP' is not visited {
            mark P' as visited
            NeighborPts' = regionQuery(P', eps)
            if sizeof(NeighborPts') >= MinPts
               NeighborPts = NeighborPts joined with NeighborPts'
          }
          ifP' is not yet member of any cluster
            add P' to cluster C
       }
    }
     
    regionQuery(P, eps)
       returnall points within P's eps-neighborhood (including P)

     

    时间复杂度

    1DBSCAN的基本时间复杂度是 O(N*找出Eps领域中的点所需要的时间), N是点的个数。最坏情况下时间复杂度是O(N2)

    2)在低维空间数据中,有一些数据结构如KD树,使得可以有效的检索特定点给定距离内的所有点,时间复杂度可以降低到O(NlogN)

    空间复杂度:低维和高维数据中,其空间都是O(N),对于每个点它只需要维持少量数据,即簇标号和每个点的标识(核心点或边界点或噪音点)

     

    参数设置DBSCAN共包括3个输入数据:数据集D,给定点在邻域内成为核心对象的最小邻域点数:MinPts,邻域半径:Eps,其中EpsMinPts需要根据具体应用人为设定。

    (1)  Eps的值可以使用绘制k-距离曲线(k-distance graph)方法得当,在k-距离曲线图明显拐点位置为对应较好的参数。若参数设置过小,大部分数据不能聚类;若参数设置过大,多个簇和大部分对象会归并到同一个簇中。

    K-距离:K距离的定义在DBSCAN算法原文中给出了详细解说,给定K邻域参数k,对于数据中的每个点,计算对应的第k个最近邻域距离,并将数据集所有点对应的最近邻域距离按照降序方式排序,称这幅图为排序的k距离图,选择该图中第一个谷值点位置对应的k距离值设定为Eps。一般将k值设为4。原文如下[2]



    (2)  MinPts选取有一个指导性的原则(a rule of thumb),MinPts≥dim+1,其中dim表示待聚类数据的维度。MinPts设置为1是不合理的,因为设置为1,则每个独立点都是一个簇,MinPts≤2时,与层次距离最近邻域结果相同,因此,MinPts必须选择大于等于3的值。若该值选取过小,则稀疏簇中结果由于密度小于MinPts,从而被认为是边界点儿不被用于在类的进一步扩展;若该值过大,则密度较大的两个邻近簇可能被合并为同一簇。因此,该值是否设置适当会对聚类结果造成较大影响。

     

    参考资料:

    [1] https://en.wikipedia.org/wiki/DBSCAN

    [2]  Ester,Martin; Kriegel, Hans-Peter; Sander,Jörg; Xu, Xiaowei (1996). Simoudis, Evangelos; Han, Jiawei; Fayyad, Usama M.,eds. Adensity-based algorithm for discovering clusters in large spatial databaseswith noise. Proceedings of the Second International Conference on KnowledgeDiscovery and Data Mining (KDD-96). AAAI Press.pp. 226–231.CiteSeerX 10.1.1.121.9220. ISBN 1-57735-004-9.

    [3] 各种聚类算法的比较 

     http://blog.163.com/qianshch@126/blog/static/48972522201092254141315/

    [4] http://www.cnblogs.com/chaosimple/p/3164775.html

    [5] https://wenku.baidu.com/view/ce3e324aa8956bec0975e3d5.html

    [6]http://blog.csdn.net/itplus/article/details/10088625

    [7] http://www.tuicool.com/articles/euAZneu

    [8] http://cn.mathworks.com/matlabcentral/fileexchange/52905-dbscan-clustering-algorithm

    [9] http://blog.csdn.net/snnxb/article/details/29880387

    [10] 聚类算法-DBSCAN-C++实现,http://blog.csdn.net/k76853/article/details/50440182

    [11] DBSCAN聚类算法C++实现,http://blog.csdn.net/u011367448/article/details/18549823

    [12] DBSCAN 算法介绍以及C++实现,http://blog.csdn.net/u011557212/article/details/53203323

    [13] https://github.com/siddharth-agrawal/DBSCAN

    [14] http://download.csdn.net/download/piaominnan/8480767

    展开全文
  • labels = np.array(pcd.cluster_dbscan(eps=4, min_points=100, print_progress=True)) max_label = labels.max() print(f"point cloud has {max_label + 1} clusters") colors = plt.get_cmap("tab20")(labels / ...
  • DBSCAN算法

    2017-05-06 22:01:24
    DBSCAN算法
  • DBSCAN_demo 数据挖掘DBSCAN算法
  • 三大聚类K-means、dbscan以及agnes的简单原理介绍以及简单实现

    数据集
    提取码:hgsr

    1.K-means聚类

    这个前面已经做过了,具体见:机器学习之K_means(附简单手写代码)
    代码:

    import numpy as np
    import matplotlib.pyplot as plt
    
    #np.random.seed(300)
    x=np.random.rand(200)*15    #产生要聚类的数据点,(0,15)之间
    y=np.random.rand(200)*15
    
    center_x=[]    #存放聚类中心坐标
    center_y=[]
    result_x=[]    #存放每次迭代后每一小类的坐标
    result_y=[]
    
    number_cluster=4   #簇数
    time=50   #迭代次数
    
    color=['red','blue','black','orange']
    
    for i in range(number_cluster):  # 随机生成中心
        result_x.append([])      #顺便初始化存放聚类结果的列表
        result_y.append([])
        x1 = np.random.choice(x)  #为了避免出现聚类后有的簇一个点也没有,
        y1 = np.random.choice(y)  #干脆就以某一个数据点为中心
        if x1 not in center_x and y1 not in center_y:
            center_x.append(x1)
            center_y.append(y1)
    
    plt.scatter(x,y)  #画出数据图
    plt.title('init plot')
    plt.show()
    
    def K_means():
        for t in range(time):
            for i in range(len(x)):
                distance = []   #存放每个点到各中心的距离
                for j in range(len(center_x)):
                    k = (center_x[j] - x[i]) ** 2 + (center_y[j] - y[i]) ** 2  #距离
                    distance.append([k])
                result_x[distance.index(min(distance))].append(x[i])  #聚类
                result_y[distance.index(min(distance))].append(y[i])
            plt.title('iterations:'+str(t+1))
            for i in range(number_cluster):
                plt.scatter(result_x[i], result_y[i], c=color[i])
            plt.show()
    
            # 更新位置
            center_x.clear()
            center_y.clear()
            for i in range(number_cluster):
                ave_x = np.mean(result_x[i])
                ave_y = np.mean(result_y[i])
                center_x.append(ave_x)
                center_y.append(ave_y)
    
    
    if __name__=='__main__':
        K_means()
    
    

    在这里插入图片描述

    2.dbscan聚类

    初始设定两个值:minPts以及半径r
    一些基本概念:

    • 核心对象:若一个点的r邻域内点的个数大于等于minPts,我们就称该点为一个核心对象
    • ε\varepsilon-领域的距离阈值:r
    • 直接密度可达:若某点p在核心点q的邻域内,则称p-q直接可达
    • 密度可达:若有一个点序列:q0,q1,q2,…,qk,对序列里任意两个相邻的点都是直接可达的,则称从q0到qk密度可达

    基本流程:

    1. 任意选择一个未被访问的点p,并将该点标记为已访问
    2. 如果p的邻域内点的个数大于mminPts(核心对象),则初始化一个簇C,将p以及p领域内的点加入到C中
    3. 遍历C中每个点,如果有未被访问的,将其标记为已访问。如果该点也是核心对象,则同样将该点邻域内的点加入到C中
    4. 重复步骤3直到C中不再存在没被访问的核心对象,将簇C加入到一个集合final中
    5. 重复步骤1234直到没有核心点未被标记,剩余的点标记为噪声点。
    6. 输出final与噪声点

    代码:

    import matplotlib.pyplot as plt
    
    minPts = 5   #最小个数
    epsilon = 1.0  #半径
    
    color = ['red', 'black', 'blue', 'orange']
    visited = []
    C = []  #保存最终的聚类结果
    noise = []  #噪声点
    
    x = []
    y = []
    data = open('聚类数据集/dataset.txt')
    for line in data.readlines():
        x.append(float(line.strip().split('\t')[0]))
        y.append(float(line.strip().split('\t')[1]))
    
    for i in range(len(x)):    #初始化标记数组
        visited.append(False)
    
    def judge():         #判断是否还存在核心点未被标记
        for i in range(len(x)):
            if visited[i]:
                continue
            cnt, lis = countObject(x, y, i)
            if cnt >= minPts:
                return True
        return False
    
    def select():    #选择一个没被标记的点
        for i in range(len(visited)):
            if not visited[i]:
                return i
        return -1
    
    def countObject(x, y, p):   #计算点p邻域的内点的个数
        cnt = 0
        lis = []
        for i in range(len(x)):
            if i == p:
                continue
            if (x[i] - x[p]) ** 2 +(y[i] - y[p]) ** 2 <= epsilon ** 2:
                cnt += 1
                lis.append(i)
        return cnt, lis
    
    def check(c):
        for i in c:
            if visited[i]:
                continue
            cnt, lis = countObject(x,y , i)
            if cnt >= minPts:
                return True
        return False
    
    def dbscan():
        while judge():     #判断是否还存在核心点未被标记
            p = select()  #选择一个没被访问的点
            visited[p] = True
            cnt, lis = countObject(x, y, p)
            if cnt >= minPts:
                c = []
                c.append(p)
                for i in lis:
                    c.append(i)
                while(check(c)):   #至少有一个点没被访问且该点领域内至少minPts个点
                    for i in c:
                        if not visited[i]:
                            visited[i] = True
                            cnt1, lis1 = countObject(x, y, i)
                            if cnt >= minPts:
                                for j in lis1:
                                    c.append(j)
                C.append(c)
        for i in range(len(visited)):
            if not visited[i]:
                noise.append(i)
    
        return C
    
    
    if __name__ == '__main__':
        cluster = dbscan()
        X = []
        Y = []
        for i in noise:
            X.append(x[i])
            Y.append(y[i])
        plt.scatter(X, Y, c='m', marker='D')  # 噪声点
        plt.legend(['noise'])
    
        for i in range(len(cluster)):
            X = []
            Y = []
            for j in cluster[i]:
                X.append(x[j])
                Y.append(y[j])
            plt.scatter(X, Y, c=color[i], alpha=1, s=50)
            plt.title('dbscan')
            
        plt.show()
    

    在这里插入图片描述

    3.agnes

    agnes是一种采用自底向上聚合策略的层次聚类算法。思路也很简单:

    1. 最开始每一个点都是一个单独的簇
    2. 算出所有簇之间的两两距离,选择距离最短的两个簇进行合并
    3. 重复步骤2直到簇的个数减小到我们指定的数目

    一个问题:怎么计算两个簇之间的距离?其实就是计算两个簇之间所有点的两两距离,最后取平均值。
    代码:

    import matplotlib.pyplot as plt
    import numpy as np
    
    cluster_Num = 4
    color = ['red', 'black', 'blue', 'orange']
    C = []
    x = []
    y = []
    data = open('聚类数据集/dataset.txt')
    for line in data.readlines():
        x.append(float(line.strip().split('\t')[0]))
        y.append(float(line.strip().split('\t')[1]))
    
    for i in range(len(x)):
        C.append([i])
    
    
    
    def distance(Ci, Cj):    #计算两个簇之间的距离
        dis = []
        for i in Ci:
            for j in Cj:
                dis.append(np.sqrt((x[i] - x[j]) ** 2 + (y[i] - y[j]) ** 2))
        dis = list(set(dis))
        return np.mean(dis)   #平均距离
    
    def find_Two_cluster():
        temp = []
        for i in range(len(C)):
            for j in range(i+1, len(C)):
                dis = distance(C[i], C[j])
                temp.append([i, j, dis])
    
        temp = sorted(temp, key=lambda x:x[2])
        return temp[0][0], temp[0][1]
    
    
    def agnes():
        global C
        while len(C) > cluster_Num:
            i, j =find_Two_cluster()
            merge = C[i] + C[j]
            C = [C[t] for t in range(len(C)) if t != i and t != j]
            C.append(merge)
    
        for i in range(len(C)):
            X = []
            Y = []
            for j in range(len(C[i])):
                X.append(x[C[i][j]])
                Y.append(y[C[i][j]])
            plt.scatter(X, Y, c=color[i])
    
        plt.legend(['C1', 'C2', 'C3', 'C4'])
        plt.title('agnes')
    
        plt.show()
    
    
    if __name__ == '__main__':
        agnes()
    
    
    
    
    

    在这里插入图片描述

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,169
精华内容 1,267
关键字:

dbscan