非层次聚类
往期文章层次聚类与聚类树、比较聚类与聚类簇划分介绍了层次聚类的使用,今天为大家介绍非层次聚类的使用。非层次聚类(non- hierarchical clustering)是对一组对象进行简单分组的方法,其分类依据是尽量使得组内对象之间比组间对象之间的相似度更高,在分析之前需要预设小组的数目。非层次聚类需要首先有个预设的结构,比如假设有k个类群,那么将所有对象任意分为k组,然后在这个基础上不断进行替换迭代,来达到最优化的分组结果。
k-中心点划分
k-means算法中选取的是距离均值,那么异常点对其的影响会非常大,很可能这种孤立的点就聚为一类,一个改进的方法就是围绕实际数据的中心点进行划分(partitioning aroundmedoids,PAM),也叫k-medoids clustering。其与k-means算法类似,从所有数据观测点寻找k个代表性的对象或形心点,来反应数据的主体结构,然后将所有观测点分配给每个形心点构建k个分类簇。不断迭代来寻找k个代表对象,来获得最佳的形心点来使得对象间的相异性总和最小。
k-medoids算法是k-means算法的变种,其不一样的地方在于聚类中心的选取。在k-means算法中将聚类中心选取为当前cluster中所有数据点的平均值,也即非真实的数据点;然而k-medoids算法中,将聚类中心也即中心点的选取限制在当前cluster所包含的数据点的集合中,从当前cluster中选取到其他所有点的距离之和最小的点作为中心点。k-means和k-medoids之间的差异就类似于一个数据样本的均值和中位数之间的差异。
cluster包中的pam()函数可以使用原始数据或者距离矩阵进行分析,因此十分方便,还可以通过轮廓宽度值确定最佳的分组数量,而fpc包中的pamk()函数可以自动计算最佳的分类簇数目,实例分析如下所示:
#读取数据
data=read.table(file="otu_table.txt", header=TRUE, check.names=FALSE)
rownames(data)=data[, 1]
data=as.matrix(data[, -1])
#将每个样品的物种数据进行总和标准化(即求相对丰度)
library(vegan)
data=decostand(data, MARGIN=2, "total")*100
otu=t(data)
#计算距离矩阵
otu_dist=vegdist(otu, method="bray", diag=TRUE, upper=TRUE, p=2)
#PAM聚类
library(fpc)
library(cluster)
#确定最佳聚类簇数目
pambest=pamk(otu_dist)
k=pambest$nc
otu_pam=pam(otu_dist, k)
mycol=c(99,81,503,562,76,96,495,52,619,453,71,134,448,548,655,574,36,544,89,120,131,596,147,576,58,429,386,122,87,404,466,124,463,552,147,45,30,54,84,256,100,652,31,610,477,150,50,588,621)
mycol=colors()[mycol]
clusplot(otu_pam, color=TRUE, labels=3, lines=0, cex=1, col.clus=mycol[1:k], col.p=otu_pam$clustering)clusplot()函数可以对聚类结果进行主成分分析并作图,结果如下所示:

根据pamk()函数计算结果最佳聚类簇数目为10,但主成分聚类图显示的聚类簇数目要小于10,可以看到不同算法的差异。我们也可以针对PAM聚类绘制轮廓宽度图,从而帮助挑选最佳聚类簇数目,如下所示:
#绘制轮廓宽度图
asw=numeric(nrow(otu))
for (i in 2:(length(asw)-1)) {
asw[i]=pam(otu_dist, i)$silinfo$avg.width
}
k.best=which.max(asw)
plot(1:length(asw), asw, type="h", main="Silhouette of PAM", lwd=2,
xlab="k(number of clusters", ylab="average silhouette")结果如下所示:

当k=22时取得最高的轮廓宽度,这与事实是相符的,因为我们所用数据的66个样品采自22个样品点,每个点3个平行样。但总体来看,轮廓宽度值很高,因此不一定挑选k=22,这里只是为pamk()函数判断结果作参考。
不同算法的侧重不同,因此结果会有一些差异。这些算法都可以作为我们的工具库,我们在实际研究中可以选择适合自己数据的算法。
END