其他聚类算法

聚类2

上篇文章介绍了聚类算法中基本的k均值聚类算法,然而还有很多种其他的聚类算法

  • 密度聚类(DBSCAN)

    这种方法的聚类不是以方差最小为衡量标准,而是遵循一个原则,“兄弟的兄弟也是兄弟”,也就是加入A与B距离很近,B与C距离很近,就算A与C距离较远,ABC也是属于同一个簇。这里定义

    核心对象:若 x j x_j xj ϵ − \epsilon - ϵ邻域至少包含 M i n P t s MinPts MinPts个样本,即 ∣ N ϵ ( x j ) ∣ ≥ M i n P t s |N_{\epsilon}(x_j)|\geq MinPts Nϵ(xj)MinPts,则 x j x_j xj是一个核心对象

    算法步骤:

    1. 找出数据集中所有的核心对象构成集合 H H H
    2. 随机在 H H H选取一个核心对象 x j x_j xj,并加入队列 Q Q Q中,初始化簇集合 Γ = ∅ \Gamma=\emptyset Γ=
    3. 从队列 Q Q Q中取出队首元素$ q , 如 果 ,如果 q 是 核 心 对 象 , 首 先 将 是核心对象,首先将 q 从 从 H 中 去 除 , 其 次 将 中去除,其次将 q 的 的 \epsilon - 邻 域 里 的 数 据 邻域里的数据 N_{\epsilon}(q) 加 入 加入 Q , 并 将 该 数 据 并 入 集 合 ,并将该数据并入集合 \Gamma 中 , 当 然 中,当然 \Gamma$中的元素需互异
    4. 若队列 Q Q Q不空,则重复步骤3,若队列 Q Q Q空了,则将 Γ \Gamma Γ生成簇 C k C_k Ck,并重复步骤2,直至 H H H为空
    5. 最终没有归入任何簇的数据视为噪声样本

    有点像从特定点开始的深度优先搜索

    密度聚类对噪声点不敏感,并且可以形成不同的形状的簇

    from numpy import *
    import matplotlib.pyplot as plt
    
    def loadDataSet(fileName):
        dataSet = []
        fr = open(fileName)
        for line in fr.readlines():
            curLine = line.strip().split('\t')
            fltLine = map(float,curLine)
            dataSet.append(list(fltLine))
        return mat(dataSet)
    
    def dist(vecA,vecB):
        return sqrt(sum(power(vecA-vecB,2)))
    
    def DBSCAN(dataSet,k,epsilon,MinPts):
        H=[]; k=1; C=[] #H核心对象序列,C储存簇内的点
        G = set([tuple(i) for i in dataSet.tolist()])
        for data in dataSet: #步骤1
            if len([i for i in dataSet  if dist(data,i) < epsilon]) >= MinPts:
                H.append(tuple(data.tolist()[0]))#找出所有核心序列 步骤1
        while len(H) > 0:
            Gold = G 
            o = H[random.randint(0,len(H))] #步骤2
            temp = set([]); temp.add(o)
            G = G - temp #1 同下的2,这个操作是为了避免在队列中加入之前已经遍历过的点
            Q = []; Q.append(tuple(o)) #步骤2
            while len(Q) > 0:
                q = Q[0]  #步骤3
                Nq = [i.tolist()[0] for i in dataSet if dist(i,q) < epsilon]
                if len(Nq) >= MinPts: #如果是核心对象
                    H.remove(q) #在核心序列取出该点
                    S = G & set([tuple(i) for i in Nq]) #S的点是没有遍历过的点
                    Q += list(S)
                    G = G - S #2 
                Q.remove(q) #步骤3
            k = k + 1 
            Ck = list(Gold-G)
            C.append(Ck)
        return C
    
  • 层次聚类

    层次聚类有”自底向上“的聚合策略和“自顶向下”的分拆策略。我们来看看自底向上的聚合策略。就是一开始每个样本属于一个簇,每次找出距离最近的簇并合并这两个簇,待最终的簇数量为k。这里什么是簇的距离呢?

    定义两个簇的最短距离 d m i n ( C i , C j ) = m i n x ∈ C i , z ∈ C j d i s t ( x , z ) d_{min}(C_i,C_j)=min_{x\in C_i,z\in C_j}dist(x,z) dmin(Ci,Cj)=minxCi,zCjdist(x,z),即两个簇之间的最近的样本的距离

    算法步骤:

    1. 每个样本归为各自一个簇 C j = C_j= Cj={ x j x_j xj}
    2. 计算簇距离矩阵 M M M M ( i , j ) = d m i n ( C i , C j ) M(i,j)=d_{min}(C_i,C_j) M(i,j)=dmin(Ci,Cj),每个元素为第i个簇与第j个簇的最短距离
    3. 找出距离最近的两个簇 C a C_a Ca C b C_b Cb,合并两个簇 C a = C a ∪ C b C_a=C_a\cup C_b Ca=CaCb,并将位于b后的簇的编号-1
    4. 更新距离矩阵,即删除第b行和第b列,并重新计算其他簇到 C a C_a Ca的距离
    5. 重复步骤3,直至最终的簇的数量符合要求

    最终会形成一种层次结构
    在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值