99-非监督学习之hclust分层聚类

> library(pacman)
> p_load(dplyr, ggplot2)

k-means 输出为扁平的聚类结果,分层(层次)聚类输出为树状的聚类结果,当数据为多层级结构时适用。
层次聚类(hierarchical clustering)基于簇间的相似度在不同层次上分析数据,从而形成树形的聚类结构,分层级树状图更能展示数据的层级结构,其算法主要为 聚集式 和 分裂式。
聚集式分层聚类:假设每个样本点都是单独的簇类,然后在算法运行的每一次迭代中找出相似度较高的簇类进行合并,该过程不断重复,直到达到预设的簇类个数K或只有一个簇类。该算法具有更广泛的应用。
将各行单独形成一个聚类;
计算各聚类间的距离;
合并相似聚类;
重复步骤 2、3 直至所有行形成一个聚类。

分裂式分层聚类:
与聚集式相反,分裂式初始化所有行在一个聚类后,然后递归分割。
可以简单理解为:每层采用k-means (k=2)。

1 数据准备

> data(GvHD, package = "mclust")
> gvhd <- as_tibble(GvHD.control)
> str(gvhd)
## tibble [6,809 × 4] (S3: tbl_df/tbl/data.frame)
##  $ CD4 : num [1:6809] 199 294 85 19 35 376 97 200 422 391 ...
##  $ CD8b: num [1:6809] 420 311 79 1 29 346 329 342 433 390 ...
##  $ CD3 : num [1:6809] 132 241 14 141 6 138 527 145 163 147 ...
##  $ CD8 : num [1:6809] 226 164 218 130 135 176 406 189 47 190 ...
> DataExplorer::profile_missing(gvhd)
## # A tibble: 4 x 3
##   feature num_missing pct_missing
##   <fct>         <int>       <dbl>
## 1 CD4               0           0
## 2 CD8b              0           0
## 3 CD3               0           0
## 4 CD8               0           0

2 聚类间的距离

hclust(d, method = "complete", members = NULL)

d:指定用于系统聚类的数据集样本间的距离矩阵,可以利用函数dist()计算得到;
method:类与类之间的距离;
"single":最短距离法,一个类中的点和另一个类中的点的最小距离
"complete":最长距离法,一个类中的点和另一个类中的点的最大距离
"median":中间距离法,一个类中的点和另一个类中的点的平均距离
"average":类平均法,两类每对观测间的平均距离
"centroid":重心法,两类重心之间的距离
"mcquitty":相似分析法
"ward":离差平方和法,基于方差分析思想,如果分类合理,则同类样品间离差平方和应当较小,类与类间离差平方和应当较大。"ward.D", "ward.D2"
members:取值为NULL或长度为d的向量,用于指定每个待聚类的小类别是由几个样本点组成的。

3 实例

> # 标准化
> gvhd.scale <- scale(gvhd)
> gvhd.dist <- dist(gvhd.scale, method = "manhattan")
> gvhd.hclust <- hclust(gvhd.dist, method = "ward.D2")
> 
> # 树状图
> # hang 等于数值,表示标签与末端树杈之间的距离,若是负数,则表示标签对齐
> # labels 表示标签,默认是NULL,表示变量原有名称。labels=F表示不显示标签
> plot(gvhd.hclust, col = "#487AA1", col.main = "#45ADA8", col.lab = "#7C8071",
+      col.axis = "#F38630", lwd = 3, lty = 1, sub = "", 
+      axes = FALSE, hang = -1, labels = F)
> axis(side = 2, at = seq(0, 8000, 2000), col = "#F38630",
+      lwd = 2, labels = FALSE)
树状图
> # 圆形图
> ggtree::ggtree(ape::as.phylo(gvhd.hclust),
+                linetype = "dashed",
+                layout = "circular")
圆形图

4 剪枝

cutree()函数用于将hcluster()的输出结果进行剪枝,最终得到指定类别的聚类结果,书写格式为:

> cutree(tree, k = NULL, h = NULL)

参数介绍:
tree:指定函数hcluster()的聚类结果;
k:一个整数或向量,用于指定聚类的数目;
h:数字标量或向量,用于指定需要剪枝的树的高度。

> gvhd.cut <- cutree(gvhd.hclust, k = 3)
> table(gvhd.cut)
## gvhd.cut
##    1    2    3 
## 4301 1356 1152

5 可视化

> # cmdscale()函数降到2维
> temp <- cmdscale(gvhd.dist, k = 2)
> 
> tibble(x = temp[, 1],
+        y = temp[, 2],
+        class = as.factor(gvhd.cut)) %>% 
+   ggplot(aes(x, y, col = class)) +
+   geom_point() +
+   stat_ellipse(level = 0.95) +
+   theme_bw() +
+   theme(legend.position = "top")
二维可视化

四维降至二维,所以图形看起来有重叠。

5 练习

用欧氏距离来创建距离矩阵,重复聚类过程,绘制树状图,并与案例比较。

> gvhd.dist2 <- dist(gvhd.scale, method = "euclidean")
> gvhd.hclust2 <- hclust(gvhd.dist, method = "ward.D2")
> cut2 <- cutree(gvhd.hclust2, k = 3)
> 
> plot(gvhd.hclust2, col = "#487AA1", col.main = "#45ADA8", col.lab = "#7C8071",
+      col.axis = "#F38630", lwd = 3, lty = 1, sub = "", 
+      axes = FALSE, hang = -1, labels = F)
> # 展示剪枝为7类的效果
> rect.hclust(gvhd.hclust2, k = 7)
> axis(side = 2, at = seq(0, 8000, 2000), col = "#F38630",
+      lwd = 2, labels = FALSE)
欧氏距离树状图

跟使用曼哈顿距离相比,几乎看不出差别。

# 将剪枝的分类加入数据框
gvhd2 <- mutate(gvhd, hcluster = as.factor(cut2))
ggpairs(gvhd2, aes(col = hcluster), upper = list(continuous = "density"),
        lower = list(continuous = wrap("points", size = 0.5)))
剪枝后可视化

从图上看,可能聚为4类更合适。

7 分层聚类的优缺点

优点:
1.能得到多层结果,容易解释。
2.实现比较简单。

缺点:
1.不能自然地处理分类变量。
2.不能选择最佳的聚类数量。
3.对不同尺度的数据敏感。
4.不能用于预测新数据。
5.大型数据集的计算成本很高。
6.对离群值敏感。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352