16--层次聚类分析

层次聚类分析

在层次聚类中,起初每一个实例或观测值属于一类。聚类就是每一次把两类聚成新的一类,直到所有的类聚成单个类为止,算法如下:

(1) 定义每个观测值(行或单元)为一类;

(2) 计算每类和其他各类的距离;

(3) 把距离最短的两类合并成一类,这样类的个数就减少一个;

(4) 重复步骤(2)和步骤(3),直到包含所有观测值的类合并成单个的类为止。

层次聚类方法

16--层次聚类分析 

单联动聚类方法倾向于发现细长的、雪茄型的类。它也通常展示一种链式的现象,即不相似的观测值分到一类中,因为它们和它们的中间值很相像。全联动聚类倾向于发现大致相等的直径紧凑类。它对异常值很敏感。平均联动提供了以上两种方法的折中。相对来说,它不像链式,而且对异常值没有那么敏感。它倾向于把方差小的类聚合。

Ward法倾向于把有少量观测值的类聚合到一起,并且倾向于产生与观测值个数大致相等的类。它对异常值也是敏感的。质心法是一种很受欢迎的方法,因为其中类距离的定义比较简单、易于理解。

层次聚类方法可以用hclust()函数来实现,格式是hclust(d, method=),其中d是通过dist()函数产生的距离矩阵,并且方法包括 "single"、"complete"、"average"、"centroid"和"ward"。

(1)营养数据的平均联动聚类:

data(nutrient, package="flexclust")       

row.names(nutrient) <- tolower(row.names(nutrient))       #将行名改为小写(个人习惯)

nutrient.scaled <- scale(nutrient)      #标准化为均值为0、方差为1

d <- dist(nutrient.scaled)     #27种食物之间的距离采用欧几里得距离,默认为欧几里得距离

fit.average <- hclust(d, method="average")    # hclust()做层次聚类,应用的方法是平均联动

plot(fit.average, hang=-1, cex=.8, main="Average Linkage Clustering")

#plot()函数中的hang命令展示观测值的标签(让它们在挂在0下面)

 16--层次聚类分析

结果分析:树状图应该从下往上读,它展示了这些条目如何被结合成类。每个观测值起初自成一类,然后相距最近的两类(beef braised和smoked ham)合并。其次,pork roast和pork simmered合并,chicken canned和tuna canned合并。再次,beef braised/smoked ham这一类和pork roast/pork simmered这一类合并(这个类目前包含四种食品)。合并继续进行下去,直到所有的观测值合并成一类。高度刻度代表了该高度类之间合并的判定值。对于平均联动来说,标准是一类中的点和其他类中的点的距离平均值。

 

NbClust包提供了众多的指数来确定在一个聚类分析里类的最佳数目。不能保证这些指标得出的结果都一致。事实上,它们可能不一样。但是结果可用来作为选择聚类个数K值的一个参考。NbClust()函数的输入包括需要做聚类的矩阵或是数据框,使用的距离测度和聚类方法,并考虑最小和最大聚类的个数来进行聚类。它返回每一个聚类指数,同时输出建议聚类的最佳数目。下面的代码清单使用该方法处理营养数据的平均联动聚类。

(2)选择聚类的个数

install.packages("NbClust")

library(NbClust)

devAskNewPage(ask=TRUE)

nc <- NbClust(nutrient.scaled, distance="euclidean", min.nc=2, max.nc=15, method="average")

 16--层次聚类分析

table(nc$Best.n[1,])       #看分组的支持数

 16--层次聚类分析

结果分析:这里,四个评判准则赞同聚类个数为2,四个判定准则赞同聚类个数为3,等等。

barplot(table(nc$Best.n[1,]))  #画图

 16--层次聚类分析

结果分析:横坐标是分组数,纵坐标是支持数,(举例:建议分成2组的,有4个支持),可以试着用“投票”个数最多的聚类个数(2、3、5和15)并选择其中一个使得解释最有

意义。下面的代码清单展示了五类聚类的方案。

clusters<-cutree(fit.average,k=5)  #分成5组

table(clusters)        #分配情况

 16--层次聚类分析

结果分析:第一类有7个观测值,第二类有16个观测值,等等。

aggregate(nutrient,by=list(cluster=clusters),median)       #原始度量

#描述聚类,aggregate()函数用来获取每类的中位数

 16--层次聚类分析

结果分析:总共是5类,每一类都有一个明显的特征,可以看数值的大小

aggregate(as.data.frame(nutrient.scaled), by=list(cluster=clusters), median)    #标准度量

 16--层次聚类分析 

plot(fit.average, hang=-1, cex=.8,

     main="Average Linkage Clustering\n5 Cluster Solution")     #显示绘图结果

 16--层次聚类分析

rect.hclust(fit.average, k=5)     #rect.hclust()函数用来叠加五类的解决方案

 16--层次聚类分析

结果分析:sardines canned形成自己的类,因为钙比其他食物组要高得多。beef heart也是单独成类,是因为富含蛋白质和铁。clams类是低蛋白和高铁的。从beef roast到pork simmered的类中,所有项目都是高能量和高脂肪的。最后,最大的类(从mackerel canned到bluefish baked)含有相对较低的铁。

上一篇:[2021.8集训Day10/JZOJ.3410]【GDOI2014模拟】Tree


下一篇:Python3 标准库概览