层次聚类:确定最佳聚类数并统计描述聚类

13
我需要一些关于R中确定最佳聚类数的方法的建议,以及使用不同统计标准描述聚类的方法。我对R是新手,只有基本的聚类分析统计基础知识。
1. 确定聚类数的方法: 文献中常用的方法之一是所谓的“拐点准则”,该方法比较不同聚类解的平方差和(SSD)。因此,将SSD绘制在分析中的聚类数量上,并通过识别图表中的“拐点”来确定最佳聚类数(例如:这里:https://en.wikipedia.org/wiki/File:DataClustering_ElbowCriterion.JPG)。这种方法是获取主观印象的第一步。因此,我想在R中实现它。网络上关于这个的信息很少。这里有一个很好的例子:http://www.mattpeeples.net/kmeans.html,作者还进行了有趣的迭代方法,看看拐点是否在聚类过程的多次重复后保持稳定(尽管它是针对划分聚类方法而不是层次聚类)。 文献中的其他方法包括所谓的“停止规则”。MILLIGAN和COOPER在他们的论文“An examination of procedures for determining the number of clusters in a data set”(可在此处获取:http://link.springer.com/article/10.1007%2FBF02294245)中比较了30种这样的停止规则,发现Calinski和Harabasz的停止规则在蒙特卡罗评估中提供了最佳结果。在R中实现它的信息甚至更少。 因此,如果有人曾经实施过这个或其他停止规则(或其他方法),一些建议将非常有帮助。
2. 描述聚类的统计学方法: 为了描述聚类,我考虑使用平均值和某种方差准则。我的数据是关于农业土地利用的,显示每个市镇不同作物的产量数据。我的目标是在数据集中找到相似的土地利用模式。
    #Clusteranalysis agriculture

    #Load data
    agriculture <-read.table ("C:\\Users\\etc...", header=T,sep=";")
    attach(agriculture)

    #Define Dataframe to work with
    df<-data.frame(agriculture)

    #Define a Subset of objects to first test the script
    a<-df[1,]
    b<-df[2,]
    c<-df[3,]
    d<-df[4,]
    e<-df[5,]
    f<-df[6,]
    g<-df[7,]
    h<-df[8,]
    i<-df[9,]
    j<-df[10,]
    k<-df[11,]
    #Bind the objects
    aTOk<-rbind(a,b,c,d,e,f,g,h,i,j,k)

    #Calculate euclidian distances including only the columns 4 to 24
    dist.euklid<-dist(aTOk[,4:24],method="euclidean",diag=TRUE,upper=FALSE, p=2)
    print(dist.euklid)

    #Cluster with Ward
    cluster.ward<-hclust(dist.euklid,method="ward")

    #Plot the dendogramm. define Labels with labels=df$Geocode didn't work
    plot(cluster.ward, hang = -0.01, cex = 0.7)

    #here are missing methods to determine the optimal number of clusters

    #Calculate different solutions with different number of clusters
    n.cluster<-sapply(2:5, function(n.cluster)table(cutree(cluster.ward,n.cluster)))
    n.cluster

    #Show the objects within clusters for the three cluster solution
    three.cluster<-cutree(cluster.ward,3)
    sapply(unique(three.cluster), function(g)aTOk$Geocode[three.cluster==g])

    #Calculate some statistics to describe the clusters
    three.cluster.median<-aggregate(aTOk[,4:24],list(three.cluster),median)
    three.cluster.median
    three.cluster.min<-aggregate(aTOk[,4:24],list(three.cluster),min)
    three.cluster.min
    three.cluster.max<-aggregate(aTOk[,4:24],list(three.cluster),max)
    three.cluster.max
    #Summary statistics for one variable
    three.cluster.summary<-aggregate(aTOk[,4],list(three.cluster),summary)
    three.cluster.summary

    detach(agriculture)

参考来源:


你可能想看一下Borcard、Gillet和Legendre的《Numerical Ecology with R》这本书,其中有一个很好的聚类分析章节:http://www.springer.com/statistics/life+sciences,+medicine+%26+health/book/978-1-4419-7975-9 - Drew Steen
2
我刚从我们的图书馆订购了一本这本书,我会看看它。谢谢你的建议!我必须承认,我发现有很多关于如何执行聚类分析的手册,而只有很少关于如何处理结果,这让我感到相当奇怪 :/ - Joschi
在我看来,这是因为知道如何执行 CA 的人比理解结果的人要多得多!如果你喜欢这本书,你可能也想看看 Legendre 和 Legendre Numerical Ecology,它不是特定于 R 的,但非常通用和权威。 - Drew Steen
1
@Drew Steen,再次感谢您提供的文献建议。我刚刚收到这本书,它提供了很多有趣的方法来深入研究聚类分析并绘制差异图。在我学习过程中,我会尝试发布解决方案。 - Joschi
1
我已经在其他地方回答了上述第一部分的问题:https://dev59.com/WGUp5IYBdhLWcg3wS2LP#15376462 - Ben
4个回答

9
如您所提及的,"elbow criterion" 是针对 k-means 的。而且,簇均值显然与 k-means 相关,并且不适用于链接聚类(尤其是不适用于单链接聚类,请参见单链接效应)。
然而,您的问题标题提到了 分层聚类,您的代码也提到了。
请注意,"elbow criterion" 并未选择最佳聚类数。它选择最佳的 k-means 聚类 数量。如果您使用不同的聚类方法,可能需要不同数量的聚类。 没有绝对最佳聚类方法。因此,也没有绝对最佳的聚类数。k-means 有一个经验法则,可以在聚类数和最小化目标函数之间做出权衡(因为增加聚类数始终可以改善目标函数)。但这主要是为了弥补 k-means 的缺陷。它并不是客观的。
聚类分析本身不是客观的任务。聚类可能在数学上很好,但却毫无用处。聚类可能在数学上得分更差,但可能为您提供无法通过数学方法衡量的数据洞察力。

谢谢您的回答。我认为它突出了聚类分析中的一些重要观点。我完全同意您的看法,即不存在客观最佳聚类方法。聚类方法在很大程度上是主观的,事实上,我并没有寻找一种客观的方法来解释聚类方法的结果。我一直在寻找一种强大的方法来确定层次聚类中最能代表我的数据结构的最佳聚类数。我认为这是聚类分析中棘手的问题,因为正如您所提到的,总会有一群... - Joschi
除了经验解释外,还可以使用一些统计指标来确定基于簇内同质性和簇间异质性的好簇数。基于 SSD 的“拐点准则”不一定与 k-means 算法相关。Ward-Clustering 也是基于最小化簇内 SSD(不同之处在于这个任务是以分层方式执行的)。因此,在 SSD 中的拐点可以指示出一个良好的同质簇数,其中簇内 SSD 仍然较低,而簇间 SSD 较高。 - Joschi
对于层次聚类,常见的方法是查看树状图。仅固定目标聚类数并不能让你选择不同深度进行切割。在这里,视觉检查会有很大帮助。 - Has QUIT--Anony-Mousse
如果我理解正确的话,那么查看树状图并将 SSDs 绘制成聚类数是相同的,不是吗?但是查看我的树状图的问题在于,我有很多对象,我的树状图太拥挤了,什么也看不见。也许你有一个建议如何以更高的分辨率绘制它(我对 R 还很陌生,所以我卡在这些基本问题上了)?也许将树状图和 SSDs 对聚类数量进行绘制会很有趣... - Joschi
2
只看树状图的顶部部分。关键是要看是否存在明显的阈值。如果树状图在顶部没有大的步骤,那么它就不重要。SSD无法捕捉到这一点,因为它只测试一个特定的水平切割,而不是是否有充分的理由选择这个切割。 - Has QUIT--Anony-Mousse

7

这是一个很晚的回答,可能对提问者没有用了 - 但对其他人可能有用。请查看NbClust包。它包含26个指数,可以给出推荐的聚类数量(您还可以选择聚类类型)。您可以以这样的方式运行它,以便获得所有指数的结果,然后您基本上可以按大多数指数推荐的聚类数量进行操作。是的,我认为基本统计数据是描述聚类的最佳方法。


1

谢谢你的建议和链接!你在R中做过类似的事吗? - Joschi
在进行分割时,我处理的是48个点的时间序列,因此R-NN曲线方法不符合我的需求,因为降低维度会消除我试图突出显示的差异。但我可能仍然可以帮助你。我一定有一个比我发布的简单文档(包括一些脚本)详细得多的文档。我找到它后会尽快回来。 - Michele

0

K均值聚类对数据的规模非常敏感,例如对于一个人的年龄和薪水,如果没有进行归一化处理,K均值聚类会认为薪水比年龄更重要,这是不希望看到的。因此,在应用聚类算法之前,最好的做法是将数据的规模进行归一化处理,使它们达到相同的水平,然后再应用聚类算法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接