分层聚类(Hierarchical clustering)

简介

分层聚类算法试图建立一个聚类的层次结构,有两类:聚合型(agglomerative)和分裂型(divisive)。聚合法最初将每个数据点作为一个单独的聚类,然后迭代合并,直到最后的聚类中包含所有的数据点。它也被称为自下而上的方法。分裂聚类遵循自上而下的流程,从一个拥有所有数据点的单一聚类开始,迭代地将该聚类分割成更小的聚类,直到每个聚类包含一个数据点。

下图展示的便是聚合法的示意图。

ca0db3156179345058cf4570d7863ebd.png

  • 流程

  • 聚合分层聚类算法包括以下步骤:

  • 计算各聚类之间的距离(初始时,每个数据点作为一个单独的聚类)。

  • 根据距离函数,将相似的聚类合并成一个聚类。

  • 重复上述两步,直到所有的数据点被合并成最后一个聚类。

f9cb7f3dfe88eca799375ef2b6f63c7a.gif

  • 常用的距离函数:

  • 单联动(single-linkage): 一个类中的点和另一个类中的点的最小距离

7c3532ac1fb8e76d4da865cba27101a2.png

全联动(complete-linkage): 一个类中的点和另一个类中的点的最大距离

42f196ef624f41654792f3c1203d03fc.png

  • 平均联动(average-linkage): 一个类中的点和另一个类中的点的平均距离

  • Ward法(ward): 和平均类似,只不过计算的是两个类之间的平方和。

88eee2f6cc9facd70c536512f26900ec.png

质心(controid): 两类中质心之间的距离,对单个变量来说,就是变量的值

e1cb2afd03b7c756bf942c81cd52b7b6.png

聚类数目

  • 生成树形图之后,下一步便是决定多少个类别合适。可以考虑像Silhouette plot、Scree Plot,或一些指标如Gap stat, Dunn's index、Hubert's gamma等。

使用factoextra包直接画出WSS/silhouetee/gap stat。使用hclust的时候,factorextra包似乎会替你计算距离,因此输入数据为原始数据,而hclust函数需要自己算距离(参见fpc包自带的例子)。

p1=fviz_nbclust(df2cluster, hcut, method = "wss",hc_metric = "euclidean", hc_method = "ward.D2")
p2=fviz_nbclust(df2cluster, hcut, method = "silhouette",hc_metric = "euclidean", hc_method = "ward.D2") 
p3=fviz_nbclust(df2cluster, hcut, method = "gap_stat",hc_metric = "euclidean", hc_method = "ward.D2")

b44a341d077555242b862ff2ef3a8a9a.png

在决定好k值后,还可以画出相应的分类,比如k=5

hc.res <- eclust(df2cluster, "hclust", k = 5, hc_method = "ward.D2", graph = FALSE) 
p1=fviz_dend(hc.res, show_labels = FALSE, palette = "jco", as.ggplot = TRUE)
p2=fviz_cluster(hc.res)

c0745e2f8b13c376c6d72662068ca125.png

  • Dunn's index可以用fpc中的cluster.stats()计算,因为基于hclust,这里需要自己计算距离。

set.seed(20000)
  options(digits=3)
  face <- rFace(200,dMoNo=2,dNoEy=0,p=2)
  dface <- dist(face) # 自己计算 dist
  complete3 <- cutree(hclust(dface),3)
  cluster.stats(dface,complete3,
                alt.clustering=as.integer(attr(face,"grouping")))

顺便用这个例子验证一下factoextra的输入到底是不是原数据。

set.seed(20000)
options(digits=3)
face <- rFace(200,dMoNo=2,dNoEy=0,p=2)
dface <- dist(face) # 自己计算 dist
#输入为dface
res1=hclust(dface,method = "ward.D2")
p1=fviz_dend(res1, k=3, show_labels = FALSE, palette = "jco", as.ggplot = TRUE)+ggtitle('hclust输入为距离')


#输入为 face
res2 <- eclust(face, "hclust", hc_method = "ward.D2", graph = FALSE) 
p2=fviz_dend(res2, k=3, show_labels = FALSE, palette = "jco", as.ggplot = TRUE)+ggtitle('factoextra输入为原数据')
grid.arrange(p1,p2,ncol=1)

c167822220d114970a2bd162b14e6359.png

其它

优点

  • 不一定需要指定聚类的数量。

  • 像k-means一样,分层聚类算法很容易实现。

  • 它可以输出聚类树(dendrogram)的层次结构,这可以帮助决定聚类的数量。

缺点

  • 分层聚类的主要缺点是其时间复杂性。与其他算法相比,它的复杂度相对较高,为O(n² logn),n为数据点的数量。

  • 一个聚类被创建,成员数据点就不能被移动。(与此相对的是一批soft clustering算法)

  • 根据距离矩阵的选择,它可能对噪音和异常值很敏感。

hclust最常见的运用可能还是在各种heatmap中展示聚类的情况。

be55a63df258505b63bfbe985f2e5735.png

heatmap/pheatmap/aheatmap等自带聚类的作图工具都使用了hclust的聚类方法,比如aheatmap和pheatmap中的complete指的就是hclust中的complete-linkage

a64411b8ddfaca645556f70770f98587.png

参考

https://medium.com/geekculture/hierarchical-clustering-simply-explained-f86b9ed96db7

https://www.datacamp.com/tutorial/hierarchical-clustering-R

  • 5
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值