层次聚类分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
层次聚类分析
层次聚类分析
在层次聚类中,起初每⼀个实例或观测值属于⼀类。
聚类就是每⼀次把两类聚成新的⼀类,直到所有的类聚成单个类为⽌,算法如下:
(1) 定义每个观测值(⾏或单元)为⼀类;
(2) 计算每类和其他各类的距离;
(3) 把距离最短的两类合并成⼀类,这样类的个数就减少⼀个;
(4) 重复步骤(2)和步骤(3),直到包含所有观测值的类合并成单个的类为⽌。
层次聚类⽅法
单联动聚类⽅法倾向于发现细长的、雪茄型的类。
它也通常展⽰⼀种链式的现象,即不相似的观测值分到⼀类中,因为它们和它们的中间值很相像。
全联动聚类倾向于发现⼤致相等的直径紧凑类。
它对异常值很敏感。
平均联动提供了以上两种⽅法的折中。
相对来说,它不像链式,⽽且对异常值没有那么敏感。
它倾向于把⽅差⼩的类聚合。
Ward法倾向于把有少量观测值的类聚合到⼀起,并且倾向于产⽣与观测值个数⼤致相等的类。
它对异常值也是敏感的。
质⼼法是⼀种很受欢迎的⽅法,因为其中类距离的定义⽐较简单、易于理解。
层次聚类⽅法可以⽤hclust()函数来实现,格式是hclust(d, method=),其中d是通过dist()函数产⽣的距离矩阵,并且⽅法包括"single"、"complete"、"average"、"centroid"和"ward"。
(1)营养数据的平均联动聚类:
data(nutrient, package="flexclust")
s(nutrient) <- tolower(s(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下⾯)
结果分析:树状图应该从下往上读,它展⽰了这些条⽬如何被结合成类。
每个观测值起初⾃成⼀类,然后相距最近的两类(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")
table(nc$Best.n[1,]) #看分组的⽀持数
结果分析:这⾥,四个评判准则赞同聚类个数为2,四个判定准则赞同聚类个数为3,等等。
barplot(table(nc$Best.n[1,])) #画图
结果分析:横坐标是分组数,纵坐标是⽀持数,(举例:建议分成2组的,有4个⽀持),可以试着⽤“投票”个数最多的聚类个数
(2、3、5和15)并选择其中⼀个使得解释最有
意义。
下⾯的代码清单展⽰了五类聚类的⽅案。
clusters<-cutree(fit.average,k=5) #分成5组
table(clusters) #分配情况
结果分析:第⼀类有7个观测值,第⼆类有16个观测值,等等。
aggregate(nutrient,by=list(cluster=clusters),median) #原始度量
#描述聚类,aggregate()函数⽤来获取每类的中位数
结果分析:总共是5类,每⼀类都有⼀个明显的特征,可以看数值的⼤⼩
aggregate(as.data.frame(nutrient.scaled), by=list(cluster=clusters), median) #标准度量
plot(fit.average, hang=-1, cex=.8,
main="Average Linkage Clustering\n5 Cluster Solution") #显⽰绘图结果
rect.hclust(fit.average, k=5) #rect.hclust()函数⽤来叠加五类的解决⽅案
结果分析:sardines canned形成⾃⼰的类,因为钙⽐其他⾷物组要⾼得多。
beef heart也是单独成类,是因为富含蛋⽩质和铁。
clams类是低蛋⽩和⾼铁的。
从beef roast到pork simmered的类中,所有项⽬都是⾼能量和⾼脂肪的。
最后,最⼤的类(从mackerel canned到bluefish
baked)含有相对较低的铁。