r - 在 R 中绘制 kmeans 簇 : Fails for only some cluster counts

标签 r cluster-analysis k-means

我正在尝试使用 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=20n=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/

相关文章:

matrix - K 均值是否用于对具有许多零值的数据进行聚类?

java - 如何计算重构误差?

r - 我可以重命名 R 中的关键字吗?

java - 有没有一种在度量空间中聚类的方法?

r - 如何合并两个表,然后使用 data.table 一步制表计数

scala - 如何查看应用 K-Means 算法后添加到集群中的数据点?

javascript - 如何编写分组算法,通过具有 3 个或更多相似属性对数据集中的项目进行分组

c++ - 如何在 C++ 中使用 OpenCV 检测多个对象?

r - 如何使用单个向量创建具有多列的矩阵

r - dplyr::mutate:- 新列 = 两个逗号分隔列表列之间的差异