PH525x series - Clustering and h

2020-01-06  本文已影响0人  3between7

写在前面的话

emmmmm,得有小半个月没有写学习笔记了,最近真是多事之秋,先是我养的猫咪得了尿闭,后是我的姥爷去世,还有工资一直拖欠不发。这其间五味杂陈自不必不多说,总之直到最近才找回了以前的生活节奏。按照进度,接下来要学习机器学习的相关章节了,今天的笔记是关于聚类与热图的。

聚类

书中对层次聚类的描述言简意赅:“With the distance between each pair of samples computed,...Each sample is assigned to its own group and then the algorithm continues iteratively, joining the two most similar clusters at each step, and continuing until there is just one group

简单的说,就是先计算所有样本之间的距离,然后距离最近的两个样本合并为一类(当做一个新的样本对待),再计算所有样本之间的距离并合并,这样反复迭代直到最后所有样本合并为一类停止。

这一过程涉及两个关键问题:(1)样本之间的距离如何计算?(2)归为一类的样本与其他样本或一类样本之间的距离如何计算?

首先,层次聚类是使用欧氏距离来计算样本之间的距离的(以二维数据为例):

D = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}

至于两个组合数据点间的距离如何计算则有3种方式:
(1)以两个组合之间最近的两个样本之间的距离作为两个组合之间的距离,也就是Single Linkage
(2)以两个组合之间最远的两个样本之间的距离作为两个组合之间的距离,即Complete Linkage
(3)先计算两个组合数据点中的每个点与其他所有数据点的距离,然后以所有距离的均值作为两个组合之间的距离,即Average Linkage

显然最后一种方法更为合理一些,上面我描述的其实应该叫做“自下而上”的层次聚类,“自上而下”就和这一过程相反,先是把所有样本视为一类,然后不断排除异己,直到每一个样本单独被分为一类。

在R中,我们可以使用hclust()函数进行层次聚类分析:

library(tissuesGeneExpression)
library(rafalib)
data(tissuesGeneExpression)
#第一步先计算样本之间的距离
d <- dist( t(e) )
#聚类
mypar()
hc <- hclust(d)
#绘图
myplclust(hc, labels=tissue, lab.col=as.fumeric(tissue), cex=0.5)
202001061714.png

如果我们想从上图中知道两个簇之间的距离,仅需要找到那两簇样本被分开的节点,该节点对应的高度就是距离。有一个问题就是,层次聚类它只能画个系统发育树,并不能指定最后被分成几簇。所以,如果想划分样本的话,还需要“cut the tree”,比如说我们在height等于120处横着来一刀:

myplclust(hc, labels=tissue, lab.col=as.fumeric(tissue),cex=0.5)
abline(h=120)
202001061725.png
hclusters <- cutree(hc,h=120)
table(true=tissue,cluster=hclusters)

#             cluster
#true           1  2  3  4  5  6  7  8  9 10 11 12 13 14
#  cerebellum   0  0  0  0 31  0  0  0  2  0  0  5  0  0
#  colon        0  0  0  0  0  0 34  0  0  0  0  0  0  0
#  endometrium  0  0  0  0  0  0  0  0  0  0 15  0  0  0
#  hippocampus  0  0 12 19  0  0  0  0  0  0  0  0  0  0
#  kidney       9 18  0  0  0 10  0  0  2  0  0  0  0  0
#  liver        0  0  0  0  0  0  0 24  0  2  0  0  0  0
#  placenta     0  0  0  0  0  0  0  0  0  0  0  0  2  4

cutree还可以指定cluster的数目进行分组:

hclusters <- cutree(hc,k=8)
table(true=tissue,cluster=hclusters)

#             cluster
#true           1  2  3  4  5  6  7  8
#  cerebellum   0  0 31  0  0  2  5  0
#  colon        0  0  0 34  0  0  0  0
#  endometrium 15  0  0  0  0  0  0  0
#  hippocampus  0 12 19  0  0  0  0  0
#  kidney      37  0  0  0  0  2  0  0
#  liver        0  0  0  0 24  2  0  0
#  placenta     0  0  0  0  0  0  0  6

这个聚类方法关键词是k,就是你首先要选定k个样本点作为k个簇的初始中心。然后计算每一个样本点与那k个中心点的距离,把它归入距离最小的中心所在的簇。等到所有的样本点归类完毕,重新计算k个簇的中心;重复以上过程直至样本点归入的簇不再变动。

在R中可以用kmeans()函数实现k-means聚类:

set.seed(1)
km <- kmeans(t(e),centers=7)
mds <-  cmdscale(d)
mypar(1,2)
plot(mds[,1],mds[,2])
plot(mds[,1],mds[,2],col=km$cluster,pch=16)
202001061751.png

可以看到,k-means的聚类效果还是不错的,而且这一结果与层次聚类的结果很相似:

table(true=tissue,cluster=km$cluster)

#             cluster
#true           1  2  3  4  5  6  7
#  cerebellum   0  0  0  5  2  0 31
#  colon        0 34  0  0  0  0  0
#  endometrium 15  0  0  0  0  0  0
#  hippocampus  0  0  0 31  0  0  0
#  kidney       7  0 30  0  2  0  0
#  liver        0  0  0  0  2 24  0
#  placenta     0  6  0  0  0  0  0

热图

在这一趴,作者就是举例介绍了下绘制热图的R函数heatmap.2(),说是这一函数个性化的参数会比较多些:

##加载所需要的包
library(RColorBrewer)
library(rafalib)
library(gplots)
library(genefilter)

#挑选方差最大的前40个基因画热图
rv <- rowVars(e)
idx <- order(-rv)[1:40]
#设置颜色
hmcol <- colorRampPalette(brewer.pal(9,"GnBu"))(100)
cols <- palette(brewer.pal(8,"Dark2"))[as.fumeric(tissue)]
#画图
heatmap.2(e[idx,],labCol=tissue,
                    trace="none",
                    ColSideColors=cols,
                    col=hmcol)
202001071013.png
上一篇下一篇

猜你喜欢

热点阅读