【机器学习】聚类【Ⅴ】密度聚类与层次聚类
主要来自周志华《机器学习》一书,数学推导主要来自简书博主“形式运算”的原创博客,包含自己的理解。
有任何的书写错误、排版错误、概念错误等,希望大家包含指正。由于字数限制,分成五篇博客。
【机器学习】聚类【Ⅰ】基础知识与距离度量
【机器学习】聚类【Ⅱ】原型聚类经典算法
【机器学习】聚类【Ⅲ】高斯混合模型讲解
【机器学习】聚类【Ⅳ】高斯混合模型数学推导
【机器学习】聚类【Ⅴ】密度聚类与层次聚类
5 密度聚类
密度聚类亦称“基于密度的聚类”(density-based clustering),此类算法假设聚类结构能通过样本分布的紧密程度确定。通常情形下,密度聚类算法从样本密度的角度来考察样本之间的可连接性,并基于可连接样本不断扩展聚类簇以获得最终的聚类结果。
DBSCAN (全称“Density-Based spatial Clustering of Applications with Noise”)是一种著名的密度聚类算法,它基于一组“邻域”(neighborhood)参数(ϵ,MinPts\epsilon,MinPtsϵ,MinPts)来刻画样本分布的紧密程度。给定数据集 D={x1,x2,⋅⋅⋅,xm}D= \{\pmb x_1, \pmb x_2,···,\pmb x_m\}D={xx1,xx2,⋅⋅⋅,xxm},定义下面这几个概念:
ϵ\epsilonϵ-邻域:对 xj∈D\pmb x_j ∈ Dxxj∈D,其 ϵ\epsilonϵ-邻域包含样本集 DDD 中与 xj\pmb x_jxxj 的距离不大于 ϵ\epsilonϵ 的样本,即 Nϵ(xj)={xi∈D∣disted(xi,xj)≤ϵ}N_\epsilon(\pmb x_j)= \{\pmb x_i∈ D \mid {\rm dist}_{\rm ed}(\pmb x_i, \pmb x_j)\le \epsilon\}Nϵ(xxj)={xxi∈D∣disted(xxi,xxj)≤ϵ};
disted(⋅,⋅){\rm dist}_{\rm ed}(·, ·)disted(⋅,⋅) 表示欧拉距离。当然,也可以使用其他距离进行度量。
核心对象(core object):若 xj\pmb x_jxxj 的 ϵ\epsilonϵ-邻域至少包含 MinPtsMinPtsMinPts 个样本,即 ∣Nϵ(xj)∣≥MinPts|N_\epsilon(\pmb x_j)|\ge MinPts∣Nϵ(xxj)∣≥MinPts,则 xj\pmb x_jxxj 是一个核心对象;
密度直达(directly density-reachable):若 xj\pmb x_jxxj 位于 xi\pmb x_ixxi 的 ϵ\epsilonϵ-邻域中,且 xi\pmb x_ixxi 是核心对象,则称 xj\pmb x_jxxj 由 xi\pmb x_ixxi 密度直达;
密度直达关系通常不满足对称性。
密度可达(density-reachable):对 xi\pmb x_ixxi 与 xj\pmb x_jxxj,若存在样本序列 p1,p2,⋅⋅⋅,pn\pmb p_1,\pmb p_2,···, \pmb p_npp1,pp2,⋅⋅⋅,ppn,其中 p1=xi\pmb p_1= \pmb x_ipp1=xxi,pn=xj\pmb p_n= \pmb x_jppn=xxj 且 pi+1\pmb p_{i+1}ppi+1 由 pi\pmb p_ippi 密度直达,则称 xj\pmb x_jxxj 由 xi\pmb x_ixxi 密度可达;
密度可达关系满足直递性,但不满足对称性。
密度相连(density-connected):对 xi\pmb x_ixxi 与 xj\pmb x_jxxj,若存在 xk\pmb x_kxxk 使得 xi\pmb x_ixxi 与 xj\pmb x_jxxj 均由 xk\pmb x_kxxk 密度可达,则称 xi\pmb x_ixxi 与 xj\pmb x_jxxj 密度相连。
密度相连关系满足对称性。
图 101010 给出了上述概念的直观显示。
图 10 DBSCAN 定义的基本概念(MinPts = 3):虚线显示出ε-邻域, x1 是核心对象,x2 由密度直达,x3 由 x1 密度可达, x3 与 x4 密度相连。
基于这些概念,DBSCAN 将“簇”定义为:由密度可达关系导出的最大的密度相连样本集合。形式化地说,给定邻域参数(ϵ,MinPts\epsilon,MinPtsϵ,MinPts),簇 C⊆DC\subseteq DC⊆D 是满足以下性质的非空样本子集:
- 连接性(connectivity): xi∈C\pmb x_i \in Cxxi∈C,xj∈C⇒xi\pmb x_j\in C \Rightarrow \pmb x_ixxj∈C⇒xxi 与 xj\pmb x_jxxj 密度相连
- 最大性(maximality): x∈C\pmb x\in Cxx∈C, xj\pmb x_jxxj 由 xi\pmb x_ixxi 密度可达 ⇒xj∈C\Rightarrow \pmb x_j\in C⇒xxj∈C
那么,如何从数据集 DDD 中找出满足以上性质的聚类簇呢?实际上,若 x\pmb xxx 为核心对象,由 x\pmb xxx 密度可达的所有样本组成的集合记为 X={x′∈D∣x′由 x密度可达}X =\{\pmb x'\in D \mid \pmb x'\space由\space\pmb x\space密度可达\}X={xx′∈D∣xx′ 由 xx 密度可达},则不难证明 XXX 即为满足连接性与最大性的簇。
DDD 中不属于任何簇的样本被认为是噪声(noise)或异常(anomaly)样本。
于是,DBSCAN 算法先任选数据集中的一个核心对象为“种子”(seed),再由此出发确定相应的聚类簇,算法描述如算法 444 所示。在第 1∼71\sim71∼7 行中,算法先根据给定的邻域参数(ϵ,MinPts\epsilon,MinPtsϵ,MinPts)找出所有核心对象;然后在第 10∼2410\sim2410∼24 行中,以任一核心对象为出发点,找出由其密度可达的样本生成聚类簇,直到所有核心对象均被访问过为止。
输入:样本集 D={x1,x2,,⋅⋅⋅,xm};邻域参数 (ϵ,MinPts);过程:\begin{array}{ll} \textbf{输入:}&\space样本集\space D = \{\pmb x_1,\pmb x_2,,···,\pmb x_m\}\space ;&&&&&&&&&&&\\ &\space 邻域参数\space(\epsilon,MinPts)\space ;\\ \textbf{过程:} \end{array} 输入:过程: 样本集 D={xx1,xx2,,⋅⋅⋅,xxm} ; 邻域参数 (ϵ,MinPts) ;
1:初始化核心对象集合:Ω=∅2:forj=1,2,⋅⋅⋅,mdo3:确定样本 xj的ϵ−邻域 Nϵ(xj);4:if∣Nϵ(xj)∣≥MinPtsthen5:将样本 xj加入核心对象集合:Ω=Ω⋃{xj}6:endif7:endfor8:初始化聚类簇数:k=09:初始化未访问样本集合:Γ=D10:whileΩ≠∅do11:记录当前未访问样本集合:Γold=Γ;12:随机选取一个核心对象 o∈Ω,初始化队列 Q=<o>;13:Γ=Γ∖{o};14:whileQ≠∅do15:取出队列 Q中的首个样本 q;16:if∣Nϵ(q)∣≥MinPtsthen17:令 Δ=Nϵ(q)⋂Γ;18:将 Δ中的样本加入队列 Q;19:Γ=Γ∖Δ;20:endif21:endwhile22:k=k+1,生成聚类簇 Ck=Γold∖Γ;23:Ω=Ω∖Ck24:endwhile\begin{array}{rl} 1:&初始化核心对象集合:\Omega=\varnothing\\ % 2:&\textbf{for}\space j=1,2,···,m\space \textbf{do} \\ % 3:&\space\space\space\space 确定样本\space \pmb x_j\space 的\epsilon-邻域\space N_{\epsilon}(\pmb x_j)\space;\\ % 4:&\space\space\space\space \textbf{if}\space |N_{\epsilon}(\pmb x_j)|\ge MinPts\space\textbf{then} \\ % 5:&\space\space\space\space\space\space\space\space 将样本\space \pmb x_j\space加入核心对象集合:\Omega=\Omega\bigcup \{\pmb x_j\}\\ % 6:&\space\space\space\space \textbf{end}\space\textbf{if} \\ % 7:&\textbf{end}\space \textbf{for}\\ % 8:&初始化聚类簇数:k=0 \\ % 9:&初始化未访问样本集合:\varGamma= D\\ % 10:&\textbf{while}\space \Omega\ne\varnothing \space \textbf{do}\\ % 11:&\space\space\space\space 记录当前未访问样本集合:{ \varGamma}_{\rm old}= { \varGamma}\space; \\ % 12:&\space\space\space\space随机选取一个核心对象\space \pmb o\in\Omega,初始化队列\space Q=<\pmb o>\space;\\ % 13:&\space\space\space\space \varGamma=\varGamma \setminus \{\pmb o\}\space; \\ % 14:&\space\space\space\space \textbf{while}\space Q\ne \varnothing\space \textbf{do} \\ % 15:&\space\space\space\space\space\space\space\space取出队列\space Q\space中的首个样本\space \pmb q\space ;\\ % 16:&\space\space\space\space\space\space\space\space \textbf{if}\space |N_{\epsilon}(\pmb q)|\ge MinPts\space\textbf{then}\\ % 17:&\space\space\space\space\space\space\space\space\space\space\space\space 令 \space \Delta=N_{\epsilon}(\pmb q)\bigcap\varGamma\space;\\ % 18:&\space\space\space\space\space\space\space\space\space\space\space\space 将\space \Delta\space中的样本加入队列\space Q\space ;\\ % 19:&\space\space\space\space\space\space\space\space\space\space\space\space \varGamma=\varGamma \setminus\Delta\space;\\ % 20:&\space\space\space\space \space\space\space\space \textbf{end}\space\textbf{if} \\ % 21:&\space\space\space\space \textbf{end}\space\textbf{while} \\ % 22:&\space\space\space\space k=k +1,生成聚类簇\space C_k = \varGamma_{\rm old} \setminus \ \varGamma\space; \\ % 23:&\space\space\space\space \Omega=\Omega \setminus C_k\\ % 24:& \textbf{end}\space\textbf{while} % \end{array} 1:2:3:4:5:6:7:8:9:10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:初始化核心对象集合:Ω=∅for j=1,2,⋅⋅⋅,m do 确定样本 xxj 的ϵ−邻域 Nϵ(xxj) ; if ∣Nϵ(xxj)∣≥MinPts then 将样本 xxj 加入核心对象集合:Ω=Ω⋃{xxj} end ifend for初始化聚类簇数:k=0初始化未访问样本集合:Γ=Dwhile Ω=∅ do 记录当前未访问样本集合:Γold=Γ ; 随机选取一个核心对象 oo∈Ω,初始化队列 Q=<oo> ; Γ=Γ∖{oo} ; while Q=∅ do 取出队列 Q 中的首个样本 qq ; if ∣Nϵ(qq)∣≥MinPts then 令 Δ=Nϵ(qq)⋂Γ ; 将 Δ 中的样本加入队列 Q ; Γ=Γ∖Δ ; end if end while k=k+1,生成聚类簇 Ck=Γold∖ Γ ; Ω=Ω∖Ckend while
输出:簇划分 C={C1,C2,⋅⋅⋅,Ck}\begin{array}{l} \textbf{输出:}\space 簇划分 \space \mathcal C=\{C_1,C_2,···,C_k\} &&&&&&&&&&&&& \end{array} 输出: 簇划分 C={C1,C2,⋅⋅⋅,Ck}
算法 4 DBSCAN 算法
算法思想非常简单,但是看上面算法流程却有些复杂。
语言描述为,确定若干个核心对象,每个核心对象都向外扩展,将扩展到的划分到一个簇中,如果能从簇扩展到另一个簇,那么两个簇合并为一个簇,簇中的样本也可以继续向外扩展。所谓”扩展“,就是以某个样本为圆心,以 ϵ\epsilonϵ 为半径画圆,圆内样本数不少于 MinPtsMinPtsMinPts ,则认为圆内的样本可由圆心样本扩展得到。(有点”广度优先搜索“的感觉了)
以表 111 西瓜数据集为例,假定邻域参数(ϵ,MinPts\epsilon,MinPtsϵ,MinPts)设置为 ϵ=0.11\epsilon =0.11ϵ=0.11,MinPts=5MinPts = 5MinPts=5 。DBSCAN 算法先找出各样本的 ϵ\epsilonϵ-邻域并确定核心对象集合:Ω={x3,x5,x6,x8,x9,x13,x14,x18,x19,x24,x25,x28,x29}\Omega= \{\pmb x_3, \pmb x_5, \pmb x_6, \pmb x_8, \pmb x_9, \pmb x_{13},\pmb x_{14},\pmb x_{18}, \pmb x_{19},\pmb x_{24}, \pmb x_{25}, \pmb x_{28}, \pmb x_{29}\}Ω={xx3,xx5,xx6,xx8,xx9,xx13,xx14,xx18,xx19,xx24,xx25,xx28,xx29} 。然后,从 Ω\OmegaΩ 中随机选取一个核心对象作为种子,找出由它密度可达的所有样本,这就构成了第一个聚类簇。不失一般性,假定核心对象 x8\pmb x_8xx8 被选中作为种子,则 DBSCAN 生成的第一个聚类簇为
C1={x6,x7,x8,x10,x12,x18,x19,x20,x23}C_1=\{\pmb x_6,\pmb x_7,\pmb x_8,\pmb x_{10},\pmb x_{12},\pmb x_{18},\pmb x_{19},\pmb x_{20},\pmb x_{23}\} C1={xx6,xx7,xx8,xx10,xx12,xx18,xx19,xx20,xx23}
然后,DBSCAN 将 C1C_1C1 中包含的核心对象从 Ω\OmegaΩ 中去除:Ω=Ω\C1={x3,x5,x9,x13,x14,x24,x25,x28,x29}\Omega =\Omega \verb|\| C_1=\{\pmb x_3,\pmb x_5,\pmb x_9,\pmb x_{13},\pmb x_{14},\pmb x_{24},\pmb x_{25},\pmb x_{28},\pmb x_{29}\}Ω=Ω\C1={xx3,xx5,xx9,xx13,xx14,xx24,xx25,xx28,xx29} 。再从更新后的集合 Ω\OmegaΩ 中随机选取一个核心对象作为种子来生成下一个聚类簇。上述过程不断重复,直至为空。图 111111 显示出 DBSCAN 先后生成聚类簇的情况。C1C_1C1 之后生成的聚类簇为
C2={x3,x4,x5,x9,x13,x14,x16,x17,x21}C3={x1,x2,x22,x26,x29}C4={x24,x25,x27,x28,x30}\begin{align} C_2&= \{\pmb x_3, \pmb x_4, \pmb x_5 , \pmb x_9, \pmb x_{13},\pmb x_{14},\pmb x_{16},\pmb x_{17}, \pmb x_{21}\} \notag\\ C_3&= \{\pmb x_1, \pmb x_2,\pmb x_{22},\pmb x_{26}, \pmb x_{29}\} \notag \\ C_4&=\{\pmb x_{24},\pmb x_{25},\pmb x_{27},\pmb x_{28}, \pmb x_{30} \} \notag \\ \end{align} C2C3C4={xx3,xx4,xx5,xx9,xx13,xx14,xx16,xx17,xx21}={xx1,xx2,xx22,xx26,xx29}={xx24,xx25,xx27,xx28,xx30}
图 11 DBSCAN 算法 (ε=0.11,MinPts=5) 生成聚类簇的先后情况,核心对象、非核心对象、噪声样本分别用“●”“○”“*”表示,红色虚线显示出簇划分。
初始参数选择:
样本个数阈值 MinPtsMinPtsMinPts :
一般设置为样本的属性维度 +1+1+1 或者维度 ×2×2×2 即可。当然,这并不绝对。
邻域距离阈值 ϵ\epsilonϵ :
规定 dikd_{ik}dik 表示其他样本与第 iii 个样本距离第 kkk 最近的距离,即将 dist(xi,xj)(1≤j≤m,j≠i){\rm dist}(\pmb x_i,\pmb x_j)\space (1\le j \le m,j\ne i)dist(xxi,xxj) (1≤j≤m,j=i) 从小到大排序后的第 kkk 个值。将 dik(1≤i≤m)d_{ik}\space(1\le i\le m)dik (1≤i≤m) 从大到小排序,排序后的序列记为 {d1k∗,d2k∗,⋅⋅⋅,dnk∗}\{d_{1k}^*,d_{2k}^*, ···,d_{nk}^*\}{d1k∗,d2k∗,⋅⋅⋅,dnk∗} ,找到发生突变 dik∗d_{ik}^*dik∗ 作为邻域距离阈值 ϵ\epsilonϵ 。体现在图像上,以索引值为横坐标,dik∗(1≤i≤m)d_{ik}^*\space(1\le i \le m)dik∗ (1≤i≤m) 为纵坐标绘制曲线,观察找到突变点。可以尝试不同的突变点对应的纵坐标作为 ϵ\epsilonϵ ,观察性能是否提升。
kkk-means 聚类与 DBSCAN 聚类的区别:
- 均值聚类 kkk-means 是基于划分的聚类, DBSCAN 是基于密度的聚类。
- kkk-means 需要指定聚类簇数 kkk,并且且初始聚类中心对聚类影响很大。kkk-means 把任何点都归到了某一个类,对异常点比较敏感。DBSCAN 能剔除噪声,需要指定邻域距离阈值 ϵ\epsilonϵ 和样本个数阈值 MinPtsMinPtsMinPts,可以自动确定簇个数。
- kkk-means 和 DBSCAN 都是将每个对象指派到单个簇的划分聚类算法,但是 kkk-means 一般聚类所有对象,而 DBSCAN 丢弃被它识别为噪声的对象。
- kkk-means 很难处理非球形的簇和不同大小的簇。DBSCAN 可以处理不同大小或形状的簇,并且不太受噪声和离群点的影响。当簇具有很不相同的密度时,两种算法的性能都很差。
- DBSCAN 多次运行产生相同的结果,而 kkk-means 会因为初始化质心的不同,产生不同的结果。
- kkk-means 可以用于稀疏的高维数据,如文档数据。DBSCAN 通常在这类数据上的性能很差,因为对于高维数据,传统的欧几里得密度定义不能很好处理它们。
6 层次聚类
层次聚类(hierarchical clustering)试图在不同层次对数据集进行划分,从而形成树形的聚类结构。数据集的划分可采用“自底向上”的聚合策略,也可采用“自顶向下”的分拆策略。通过采用“自底向上”的聚合策略,而采用“自顶向下”的拆分策略场景非常少,因此仅略讲“自顶向下”策略。
AGNES (全称“AGglomerative NESting”)是一种采用自底向上聚合策略的层次聚类算法。它先将数据集中的每个样本看作一个初始聚类簇,然后在算法运行的每一步中找出距离最近的两个聚类簇进行合并,该过程不断重复,直至达到预设的聚类簇个数。这里的关键是如何计算聚类簇之间的距离。实际上,每个簇是一个样本集合,因此,只需采用关于集合的某种距离即可。例如,给定聚类簇 CiC_iCi 与 CjC_jCj,可通过下面的式子来计算距离:
最小距离:dmin(Ci,Cj)=minx∈Ci,z∈Cjdist(x,z)最大距离:dmax(Ci,Cj)=maxx∈Ci,z∈Cjdist(x,z)平均距离:davg(Ci,Cj)=1∣Ci∣∣Cj∣∑x∈Ci∑z∈Cjdist(x,z)\begin{align} 最小距离&:d_{\rm min}(C_i,C_j)=\min_{\pmb x\in C_i,\pmb z\in C_j}{\rm dist} (\pmb x, \pmb z) \notag\\ 最大距离&:d_{\rm max}(C_i,C_j)=\max_{\pmb x\in C_i,\pmb z\in C_j}{\rm dist} (\pmb x, \pmb z)\notag\\ 平均距离&:d_{\rm avg}(C_i,C_j)=\frac{1}{|C_i||C_j|}\sum_{\pmb x\in C_i}\sum_{\pmb z\in C_j} {\rm dist}(\pmb x,\pmb z)\notag \end{align} 最小距离最大距离平均距离:dmin(Ci,Cj)=xx∈Ci,zz∈Cjmindist(xx,zz):dmax(Ci,Cj)=xx∈Ci,zz∈Cjmaxdist(xx,zz):davg(Ci,Cj)=∣Ci∣∣Cj∣1xx∈Ci∑zz∈Cj∑dist(xx,zz)
集合间的距离计算常采用豪斯多夫距离(Hausdorff distance)。
豪斯多夫距离是描述两组点集之间相似程度的一种量度,它是两个点集之间距离的一种定义形式。给定两个集合 CiC_iCi 和 CjC_jCj
dhd(Ci,Cj)=max(h(Ci,Cj),h(Cj,Ci)){d}_{\rm hd}(C_i,C_j)=\max\left(h(C_i,C_j), h(C_j,C_i)\right) dhd(Ci,Cj)=max(h(Ci,Cj),h(Cj,Ci))
其中
h(Ci,Cj)=maxx∈Ciminz∈Cjdist(x,z)h(C_i,C_j)=\max_{\pmb x\in C_i}\min_{\pmb z\in C_j} {\rm dist}(\pmb x, \pmb z) h(Ci,Cj)=xx∈Cimaxzz∈Cjmindist(xx,zz)
语言描述为,对于集合 CiC_iCi 中的每个样本,找到与之距离最近的 CjC_jCj 中的样本,取全部距离的最大值,即 h(Ci,Cj)h(C_i,C_j)h(Ci,Cj);类似地,对于集合 CjC_jCj 中的每个样本,找到与之距离最近的 CiC_iCi 中的样本,取全部距离的最大值,即 h(Cj,Ci)h(C_j,C_i)h(Cj,Ci);取两个最大值的较大者作为豪斯多夫距离。
显然,最小距离由两个簇的最近样本决定,最大距离由两个簇的最远样木决定,而平均距离则由两个簇的所有样本共同决定。当聚类簇距离由 dmind_{\rm min}dmin、dmaxd_{\rm max}dmax 或 davgd_{\rm avg}davg 计算时,AGNES 算法被相应地称为“单链接”(single-linkage)、“全链接”(complete-linkage)或“均链接”(average-linkage)算法。
AGNES 算法描述如算法 555 所示。在第 1∼91\sim91∼9 行,算法先对仅含一个样本的初始聚类簇和相应的距离矩阵进行初始化;然后在第 11∼2311\sim2311∼23 行,AGNES 不断合并距离最近的聚类簇,并对合并得到的聚类簇的距离矩阵进行更新:上述过程不断重复,直至达到预设的聚类簇数。
输入:样本集 D={x1,x2,,⋅⋅⋅,xm};聚类簇距离度量函数 d;聚类簇数 k;过程:\begin{array}{ll} \textbf{输入:}&\space样本集\space D = \{\pmb x_1,\pmb x_2,,···,\pmb x_m\}\space ;&&&&\\ &\space 聚类簇距离度量函数 \space d\space ;\\ &\space 聚类簇数 \space k\space ;\\ \textbf{过程:} \end{array} 输入:过程: 样本集 D={xx1,xx2,,⋅⋅⋅,xxm} ; 聚类簇距离度量函数 d ; 聚类簇数 k ;
1:forj=1,2,⋅⋅⋅,mdo2:Cj={xj}3:endfor4:forj=1,2,⋅⋅⋅,mdo5:forj=1,2,⋅⋅⋅,mdo6:M(i,j)=d(Ci,Cj);7:M(j,i)=M(i,j)8:endfor9:endfor10:设置当前聚类簇个数:q=m11:whileq>kdo12:找出距离最近的两个聚类簇 Ci∗和 Cj∗;13:合并 Ci∗和 Cj∗:Ci∗=Ci∗⋃Cj∗;14:forj=j∗+1,j∗+2,⋅⋅⋅,qdo15:将聚类簇 Cj重编号为 Cj−116:endfor17:删除距离矩阵 M的第 j∗行与第 j∗列 ;18:forj=1,2,⋅⋅⋅,q−1do19:M(i∗,j)=d(Ci∗,Cj);20:M(i,j∗)=M(i∗,j)21:endfor22:q=q−123:endwhile\begin{array}{rl} 1:&\textbf{for}\space j=1,2,···,m\space \textbf{do} \\ % 2:&\space\space\space\space C_j=\{\pmb x_j\}\\ % 3:&\textbf{end}\space \textbf{for} \\ % 4:&\textbf{for}\space j=1,2,···,m\space \textbf{do} \\ % 5:&\space\space\space\space \textbf{for}\space j=1,2,···,m\space \textbf{do} \\ % 6:&\space\space\space\space\space\space\space\space M(i,j)=d(C_i,C_j)\space;\\ % 7:&\space\space \space\space\space\space\space\space M(j,i)=M(i,j)\\ % 8:&\space\space \space\space\textbf{end}\space \textbf{for}\\ % 9:&\textbf{end}\space \textbf{for}\\ % 10:&设置当前聚类簇个数:q=m\\ % 11:&\textbf{while} \space q>k \space \textbf{do}\\ % 12:&\space\space\space\space 找出距离最近的两个聚类簇 \space C_{i^*}\space 和 \space C_{j^*}\space ;\\ % 13:&\space\space\space\space 合并 \space C_{i^*}\space 和 \space C_{j^*}: \space C_{i^*} = C_{i^*}\bigcup C_{j^*} \space; \\ % 14:&\space\space\space\space \textbf{for}\space j=j^*+1,j^*+2,···,q\space \textbf{do} \\ % 15:&\space\space\space\space\space\space\space\space 将聚类簇\space C_j\space 重编号为\space C_{j-1}\\ % 16:&\space\space\space\space\textbf{end}\space \textbf{for}\\ % 17:&\space\space\space\space删除距离矩阵\space M \space 的第\space j^*\space 行与第\space j^*\space列\space ;\\ % 18:&\space\space\space\space\textbf{for}\space j=1,2,···,q-1\space \textbf{do} \\ % 19:&\space\space\space\space\space\space\space\space M(i^*,j)=d(C_{i^*},C_j)\space;\\ % 20:&\space\space\space\space\space\space\space\space M(i,j^*)=M(i^*,j)\\ % 21:&\space\space\space\space\textbf{end}\space \textbf{for}\\ % 22:&\space\space\space\space q=q-1\\ % 23:&\textbf{end}\space \textbf{while} \end{array} 1:2:3:4:5:6:7:8:9:10:11:12:13:14:15:16:17:18:19:20:21:22:23:for j=1,2,⋅⋅⋅,m do Cj={xxj}end forfor j=1,2,⋅⋅⋅,m do for j=1,2,⋅⋅⋅,m do M(i,j)=d(Ci,Cj) ; M(j,i)=M(i,j) end forend for设置当前聚类簇个数:q=mwhile q>k do 找出距离最近的两个聚类簇 Ci∗ 和 Cj∗ ; 合并 Ci∗ 和 Cj∗: Ci∗=Ci∗⋃Cj∗ ; for j=j∗+1,j∗+2,⋅⋅⋅,q do 将聚类簇 Cj 重编号为 Cj−1 end for 删除距离矩阵 M 的第 j∗ 行与第 j∗ 列 ; for j=1,2,⋅⋅⋅,q−1 do M(i∗,j)=d(Ci∗,Cj) ; M(i,j∗)=M(i∗,j) end for q=q−1end while
输出:簇划分 C={C1,C2,⋅⋅⋅,Ck}\begin{array}{l} \textbf{输出:}\space 簇划分 \space \mathcal C=\{C_1,C_2,···,C_k\} &&&&&& \end{array} 输出: 簇划分 C={C1,C2,⋅⋅⋅,Ck}
算法 5 AGNES 算法
以表 111 西瓜数据集为例,令 AGNES 算法一直执行到所有样本出现在同一个簇中,即 k=1k = 1k=1,则可得到图 121212 所示的“树状图”(dendrogram),其中每层链接一组聚类簇。
图 12 西瓜数据集上 AGNES 算法生成的树状图 (采用dmax)。横轴对应于样本编号,纵轴对应于聚类簇距离。
在树状图的特定层次上进行分割,则可得到相应的簇划分结果。例如,以图 121212 中所示虚线分割树状图,将得到包含 777 个聚类簇的结果:
C1={x1,x26,x29}C2={x2,x3,x4,x21,x22}C3={x23,x24,x25,x27,x28,x30}C4={x5,x7}C5={x9,x13,x14,x16,x17}C6={x6,x8,x10,x15,x18,x19,x20}C7={x11,x12}\begin{align} C_1&=\{\pmb x_1, \pmb x_{26},\pmb x_{29}\}\notag\\ C_2&=\{\pmb x_2, \pmb x_3, \pmb x_4, \pmb x_{21}, \pmb x_{22}\}\notag\\ C_3&=\{\pmb x_{23},\pmb x_{24}, \pmb x_{25}, \pmb x_{27}, \pmb x_{28}, \pmb x_{30}\}\notag\\ C_4&=\{\pmb x_5, \pmb x_7\}\notag\\ C_5&=\{\pmb x_9, \pmb x_{13},\pmb x_{14}, \pmb x_{16}, \pmb x_{17}\}\notag\\ C_6&=\{\pmb x_6, \pmb x_8, \pmb x_{10}, \pmb x_{15}, \pmb x_{18}, \pmb x_{19}, \pmb x_{20}\}\notag\\ C_7&=\{\pmb x_{11}, \pmb x_{12}\}\notag \end{align} C1C2C3C4C5C6C7={xx1,xx26,xx29}={xx2,xx3,xx4,xx21,xx22}={xx23,xx24,xx25,xx27,xx28,xx30}={xx5,xx7}={xx9,xx13,xx14,xx16,xx17}={xx6,xx8,xx10,xx15,xx18,xx19,xx20}={xx11,xx12}
将分割层逐步提升,则可得到聚类簇逐渐减少的聚类结果。例如图 131313 显示出了从图 121212 中产生 777 至 444 个聚类簇的划分结果。
图 13 西瓜数据集上 AGNES 算法 (采用dmax) 在不同聚类簇数 (k=7,6,5,4) 时的簇划分结果。样本点用“●”表示,红色虚线显示出簇划分。
"自顶向下"的拆分策略算法流程大致如算法 666 所示。
输入:样本集 D={x1,x2,⋅⋅⋅,xm};聚类簇数 k.过程:\begin{array}{ll} \textbf{输入:}&\space样本集\space D = \{\pmb x_1,\pmb x_2,···,\pmb x_m\}\space ;&&&&&&&&\\ &\space 聚类簇数\space k\space.\\ \textbf{过程:} \end{array} 输入:过程: 样本集 D={xx1,xx2,⋅⋅⋅,xxm} ; 聚类簇数 k .
1:将所有的数据作为一个簇,视为层次树根节点2:当前簇数 k∗=13:whilek∗≠kdo4:d∗=0;5:fori=1,2,⋅⋅⋅,k∗do6:找出簇 Ci中距离最远的两个样本 x和 z;6:d=dist(x,z);7:ifd>d∗then8:l∗=i,d∗=d,x∗=x,z∗=z;9:endif10:endfor11:删除簇 l∗12:fori=l∗+1,l∗+2,⋅⋅⋅,k∗do13:将聚类簇 Ci重编号为 Ci−114:endfor15:将样本 x和 z分别划分到新簇 Ck∗和 Ck∗+1中16:forxj∈Cl∗do17:分别计算 xj与 x和 z的距离,记为 djx和 djz;18:ifdjx>djzthen19:将样本 xj重新划分到簇 Ck∗+1;20:else21:将样本 xj重新划分到簇 Ck∗;22:endif23:endfor24:k∗=k∗+1;25:endwhile\begin{array}{rl} 1:&将所有的数据作为一个簇,视为层次树根节点\\ % 2:&当前簇数\space k^*=1 \\ % 3:&\textbf{while}\space k^*\ne k\space \textbf{do}\\ % 4:&\space\space\space\space d^*=0\space; \\ % 5:&\space\space\space\space \textbf{for}\space i=1,2,···,k^* \space \textbf{do}\\ % 6:&\space\space\space\space\space\space\space\space 找出簇\space C_i \space中距离最远的两个样本\space\pmb x\space 和\space \pmb z\space ; \\ % 6:&\space\space \space\space\space\space \space\space d={\rm dist}(\pmb x, \pmb z)\space; \\ % 7:&\space\space \space\space\space\space \space\space \textbf{if}\space d \gt d^* \space \textbf{then}\\ % 8:&\space\space \space\space\space\space \space\space\space\space \space\space l^*=i,d^*=d ,\pmb x^*=\pmb x,\pmb z^*=\pmb z \space; \\ % 9:&\space\space \space\space\space\space \space\space \textbf{end}\space \textbf{if}\\ % 10:&\space\space\space\space \textbf{end}\space \textbf{for}\\ % 11:&\space\space \space\space 删除簇 \space l^* \\ % 12:&\space\space\space\space \textbf{for}\space i=l^*+1,l^*+2,···,k^* \space \textbf{do}\\ % 13:&\space\space\space\space\space\space\space\space 将聚类簇\space C_i\space 重编号为\space C_{i-1}\\ % 14:&\space\space\space\space\textbf{end} \space \textbf{for} \\ % 15:&\space\space\space\space 将样本 \space \pmb x \space 和 \space \pmb z \space 分别划分到新簇\space C_{k^*} \space 和 \space C_{k^*+1} \space 中 \\ % 16:&\space\space\space\space \textbf{for}\space \pmb x_j \in C_{l^*} \space\textbf{do}\\ % 17:&\space\space\space\space \space\space\space\space 分别计算 \space \pmb x_j \space 与\space \pmb x \space 和 \space\pmb z \space的距离,记为\space d_{jx} \space 和 \space d_{jz} \space ;\\ % 18:&\space\space\space\space \space\space\space\space \textbf{if}\space d_{jx} \gt d_{jz} \space \textbf{then}\\ % 19:&\space\space\space\space \space\space\space\space \space\space\space\space 将样本 \space \pmb x_j \space重新划分到 簇\space C_{k^*+1} \space; \\ % 20:&\space\space\space\space \space\space\space\space \textbf{else}\\ % 21:&\space\space\space\space \space\space\space\space \space\space\space\space将样本 \space \pmb x_j \space重新划分到 簇\space C_{k^*} \space;\\ % 22:&\space\space\space\space \space\space\space\space \textbf{end}\space \textbf{if} \\ % 23:&\space\space\space\space\textbf{end}\space \textbf{for}\\ % 24:&\space\space\space\space k^*=k^*+1\space ;\\ % 25:& \textbf{end} \space \textbf{while} \\ \end{array} 1:2:3:4:5:6:6:7:8:9:10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:将所有的数据作为一个簇,视为层次树根节点当前簇数 k∗=1while k∗=k do d∗=0 ; for i=1,2,⋅⋅⋅,k∗ do 找出簇 Ci 中距离最远的两个样本 xx 和 zz ; d=dist(xx,zz) ; if d>d∗ then l∗=i,d∗=d,xx∗=xx,zz∗=zz ; end if end for 删除簇 l∗ for i=l∗+1,l∗+2,⋅⋅⋅,k∗ do 将聚类簇 Ci 重编号为 Ci−1 end for 将样本 xx 和 zz 分别划分到新簇 Ck∗ 和 Ck∗+1 中 for xxj∈Cl∗ do 分别计算 xxj 与 xx 和 zz 的距离,记为 djx 和 djz ; if djx>djz then 将样本 xxj 重新划分到簇 Ck∗+1 ; else 将样本 xxj 重新划分到簇 Ck∗ ; end if end for k∗=k∗+1 ;end while
输出:簇划分 C={C1,C2,⋅⋅⋅,Ck}\begin{array}{l} \textbf{输出:}\space 簇划分\space \mathcal{C}=\{C_1,C_2,···,C_k\} &&&&&&&&&&& \end{array} 输出: 簇划分 C={C1,C2,⋅⋅⋅,Ck}
算法 6 基于"自顶向下"拆分策略的层次聚类算法
REF
[1] 机器学习 - 周志华著
[2] 青岛大学计算机科学技术学院孙仁诚《大数据分析方法》教案
[3] 向量无穷范数为什么是分量绝对值最大者? - 博客园
[4] 向量2-范数三角不等式证明 - CSDN博客
[5] 机器学习:聚类-闵科夫斯基距离和无序属性的VDM距离计算 - CSDN博客
[6] 标准化和归一化 超全详解 - CSDN博客
[7] 标准化和归一化,请勿混为一谈,透彻理解数据变换 - CSDN博客
[8] k-modes聚类算法介绍 - CSDN博客
[9] 聚类分析之k-prototype算法解析 - CSDN博客
[10] CLUSTERING LARGE DATA SETS WITH MIXED NUMERIC AND CATEGORICAL VALUES*
[11] 数据挖掘——PAM(K-Medoids)聚类算法学习 -CSDN博客
[12] K-中心点算法(PAM)- CSDN博客
[13] 多元高斯分布(The Multivariate normal distribution)- 博客园
[14] 为什么高斯混合分布这么常用?- 知乎
[15] 彻底理解中心极限定理——最重要的统计定理之一
[16] 马同学
[17] 优化、参数估计与机器学习的关系_三七、的博客-CSDN博客
[18] 高斯混合模型的终极理解 - CSDN博客
[19] 一文详解高斯混合模型原理 - 知乎
[20] 机器学习笔记 - 什么是高斯混合模型(GMM)?- CSDN博客
[21] 高斯混合模型GMM - 简书
[22] 二次型求导 - CSDN博客
[23] 详解DBSCAN聚类 - CSDN博客
[24] 机器学习 聚类篇——DBSCAN的参数选择及其应用于离群值检测 - CSDN博客
[25] 【数据聚类】第四章第一节3:DBSCAN性能分析、优缺点和参数选择方法 - CSDN博客
[26] 机器学习 之k-means和DBSCAN的区别 - 走看看
[27] hausdorff distance 豪斯多夫距离 - 灰信网
[28] 【数据聚类】第六章第一节:层次聚类算法概述、聚合和分裂方法 - CSDN博客
[29] 分层聚类算法(Hierarchical clustering) - 博客园
【机器学习】聚类【Ⅴ】密度聚类与层次聚类相关推荐
- 机器学习算法(十二):聚类(2)层次聚类 Hierarchical Clustering
目录 1 层次聚类 1.1 层次聚类的原理 1.2 两个组合数据点间的距离: 2 自底向上的合并算法 2.1 AGNES算法 (AGglomerative NESting) 2.1.1 原理 2.1. ...
- 机器学习笔记(九)聚类算法Birch和层次聚类Hierarchical clustering
本篇文章我们继续介绍另一种聚类算法--Birch模型,相对于K-means和DBSCAN,Birch的应用并没有那么广泛,不过它也有一些独特的优势,Birch算法比较适合于数据量大,类别数K也比较多的 ...
- 聚类(三)—— 层次聚类
主要内容 聚类分析概述 K-Means聚类 层次聚类 基于密度的聚类 其他聚类方法 聚类评估 小结 三.层次聚类 算法原理 层次聚类 (Hierarchical Clustering)就是按照某种方法 ...
- 聚类(Clustering):hierarchical clustering 层次聚类及其应用
聚类(Clustering):hierarchical clustering 层次聚类及其应用 clustering实现: from numpy import * import math #基于mat ...
- 机器学习算法之 K-means、层次聚类,谱聚类
k-means 和层次聚类都属于划分聚类,实际中最常用的是k-means,k-means效果不好的情况下才会采用其他聚类 K-means算法 K-means算法,也称为K-平均或者K-均值,是一种使用 ...
- 机器学习技术-层次聚类算法(组平均)-综合层次聚类方法(BIRCH、CURE)
基于层次的聚类方法,是对给定的数据进行层次的分解,直到某种条件满足为止.首先将数据点组成一颗聚类树,根据层次,自底向上或是自顶向下分解.层次的方法可以分为凝聚的方法和分裂的方法. 凝聚的方法,也称为自 ...
- python层次聚类_python中做层次聚类,使用scipy.cluster.hierarchy.fclusterdata方法 | 学步园...
python机器学习包里面的cluster提供了很多聚类 但是没有看明白ward_tree的返回值代表了什么含义,遂决定寻找别的实现方式. 经过查找,发现scipy.cluster.hierarchy ...
- 关于聚类算法Kmeans/K-mediods/层次聚类/OPTICS较为详细的介绍
K-means算法 将一群物理对象或者抽象对象的划分成相似的对象类的过程.其中类簇是数据对象的集合,在类簇中所有的对象都彼此相似,而类簇与类簇之间的对象是彼此相异. 聚类除了可以用于数据分割(data ...
- java层次聚类_python实现一个层次聚类方法
层次聚类(Hierarchical Clustering) 一.概念 层次聚类不需要指定聚类的数目,首先它是将数据中的每个实例看作一个类,然后将最相似的两个类合并,该过程迭代计算只到剩下一个类为止,类 ...
- 分裂层次聚类matlab实现,凝聚层次聚类算法matlab源码
<凝聚层次聚类算法matlab源码>由会员分享,可在线阅读,更多相关<凝聚层次聚类算法matlab源码(3页珍藏版)>请在人人文库网上搜索. 1.共享一个在数据挖掘课程中作为示 ...
最新文章
- block为什么用copy以及如何解决循环引用
- 移除VS解决方案和TFS服务器的关系
- $(function() {})是干什么的及作用
- MongoDB- 简单操作命令
- 精通Android开发 1
- vscode 预览图片 插件_真的动手写的VSCode的插件(图片浏览)之1
- mysql数据库+ssh框架_SSH框架+Mysql数据库开发java web会员积分消费管理系统
- Linux USB 驱动开发实例(二)—— USB 鼠标驱动注解及测试
- codeforces 158A-C语言解题报告
- android开发适配深色模式,手机不支持深色模式,如何用软件解决深色模式的问题?(附有系统全局深色模式实现方法...
- python 定义变量_python-003-变量
- [译]使用Webpack提高Vue.js应用程序的4种方式
- 对于超平面的理解[转载]
- Java集合存放有序不重复的对象
- java 扫描jar包_java 扫描指定包(包括jar包)
- 2.5.1 命令与参数
- InfoPath基础应用教程-2 表单中的规则(1)
- 开放世界游戏中的大地图背后有哪些实现技术
- 2.1HTML网页之table标签B
- pcb二次钻孔_pcb钻孔的注意事项
热门文章
- HTML Component Library for Delphi
- L 版 -360stack安全大学部署文档
- 成就你一生的100个哲理61-70
- Mac下使用XMPP即时通讯【2】:安装XMPP和Spark
- 最新spark,hive,flink,kafka,hadoop,zookeeper,flume,java,maven,Apache历史版本大全下载
- mencoder合并视频
- 事实证明,戴尔私有化是明智之举
- 我的敏捷思想成长之旅
- 【教程】详解VS2010安装流程
- android armeabi和x86,Android下不同CPU類型:armeabi和armeabi-v7a以及mips和x86