我正在尝试使用 clusplot 来可视化 kmeans 聚类。 Reinventthewheel.csv是一个对称相似度矩阵(1087 行),其值为 [0,1]
。由于某种原因,clusplot 只会针对 n
的某些值生成 n
个簇的图。对于 n
的其他值,它返回以下错误:
library(cluster)
simmy = read.csv("reinventthewheel.csv", header=TRUE, row.names=1)
disty = dist(1-simmy)
kay19 <- kmeans(disty,19)$cluster
par(mfrow=c(3,2))
clusplot(disty, diss=TRUE, kay19, color=FALSE, shade=FALSE, lines=0, col.p=kay19, main="KMEANS", sub="19 assortments")
#(successfully plotted for n=19)
kay20 <- kmeans(disty,20)$cluster
clusplot(disty, diss=TRUE, kay20, color=FALSE, shade=FALSE, lines=0, col.p=kay20, main="KMEANS", sub="20 assortments")
Error in seq.default(-sqrt(yl2), sqrt(yl2), length = n.half) :
'from' cannot be NA, NaN or infinite
#(failed to plot for n=20)
kay21<-kmeans(disty,21)$cluster
clusplot(disty, diss=TRUE, kay21, color=FALSE, shade=FALSE, lines=0, col.p=kay21, main="KMEANS", sub="21 assortments")
Error in seq.default(-sqrt(yl2), sqrt(yl2), length = n.half) :
'from' cannot be NA, NaN or infinite
#(failed to plot for n=21)
kay22<-kmeans(disty,22)$cluster
clusplot(disty, diss=TRUE, kay22, color=FALSE, shade=FALSE, lines=0, col.p=kay22, main="KMEANS", sub="22 assortments")
#(successfully plotted for n=22)
我认为也许n=20
和n=21
正在生成空簇,但事实并非如此。每个簇至少有一个点。
在从同一矩阵中为任何 n
绘制分层聚类(使用 cuttree(hclust)
)时,我不会出现这些错误。关于可能导致此错误的原因有什么想法吗?提前致谢。
最佳答案
这里发生了几件事。
首先,您应该知道 kmeans(dist,n)
使用一种算法,该算法随机定义 n 个簇质心,然后移动它们,直到满足最小化标准遇见了。这通常会导致局部最小值,这反过来意味着如果您使用相同的 dist 和 n 重复运行 kmeans(dist,n)
,您可能会得到每次都有不同的簇。对于大量集群或分化程度较低的集群来说,这尤其成问题,这两种情况都适用于您的情况。
您可以在运行 kmeans(...)
之前使用 set.seed(x)
使该过程可重复,但这仍然不能保证“最佳”安排n 个簇。因此,当我使用您的数据运行代码时,clusplot(...)
对于 19、20 和 22 个集群可以正常工作,而对于 21 个集群则失败。这是因为我得到的集群与您不同。
其次,在某些情况下,该错误显然是由于计算每个簇的椭圆的算法失败造成的。默认值 clusplot(...,span=T) 使用最小体积椭圆体方法,该方法应该将每个簇包围在包含簇中所有点的最小椭圆中。显然,对于某些点的排列,该算法会失败。 span=F
基于簇中的点遵循二元正态分布的假设生成椭圆,并且椭圆基于每个簇中点的协方差矩阵。当我使用 span=F
运行您的代码时,没有收到任何错误。
后一种方法本质上是在每个簇的质心周围绘制置信带(我相信这些是 95% 的置信带,但我不确定)。虽然这会导致更大的椭圆,并且绘图不如最小体积方法那么漂亮,但在我看来,这是一种更好的表示数据的方法,因为它准确地描述了集群中存在大量重叠的事实:许多点可以很容易地属于多个簇。当我使用置信带方法时,我得到下面的图。最后的代码与您的代码几乎相同,但我将其包含在内是为了表明如果您运行该代码,您将获得相同的结果。
library(cluster)
simmy = read.csv("reinventthewheel.csv", header=TRUE, row.names=1)
disty = dist(1-simmy)
set.seed(1)
kay19 <- kmeans(disty,19)$cluster
kay20 <- kmeans(disty,20)$cluster
kay21<-kmeans(disty,21)$cluster
kay22<-kmeans(disty,22)$cluster
par(mfrow=c(2,2))
s=FALSE
clusplot(disty, diss=TRUE, kay19, color=FALSE, shade=FALSE, lines=0, col.p=kay19, main="KMEANS", sub="19 assortments",span=s)
clusplot(disty, diss=TRUE, kay20, color=FALSE, shade=FALSE, lines=0, col.p=kay20, main="KMEANS", sub="20 assortments",span=s)
clusplot(disty, diss=TRUE, kay21, color=FALSE, shade=FALSE, lines=0, col.p=kay21, main="KMEANS", sub="21 assortments",span=s)
clusplot(disty, diss=TRUE, kay22, color=FALSE, shade=FALSE, lines=0, col.p=kay22, main="KMEANS", sub="22 assortments",span=s)
关于r - 在 R 中绘制 kmeans 簇 : Fails for only some cluster counts,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23521758/