kmeans()的结果因运行而异

时间:2018-09-25 20:57:44

标签: r cluster-analysis k-means

enter image description here

我试图进行几次kmeans运行,以查看totss获得的不同值。但是,当我运行以下代码时,我得到的准确结果是50次(n = 50)。

n= 50
k=1
for (i in c(1:n)){

   set.seed(as.numeric(runif(1))) #random seed

   a <- kmeans(na.omit(data[,c(8,22,23,28)]), centers=2)
   print(a$iter)
   print(a$totss)
   print(a$size)
   print(a$centers)

   k=k+1
   remove(a)
}

结果

*totss      *size1   *size2

64366.21   14080   13061

64366.21   14080   13061

64366.21   14080   13061

64366.21   14080   13061
...

知道为什么会这样吗?

图片:我删除了set.seed()东西,并打印了a$iter(迭代次数)。

2 个答案:

答案 0 :(得分:4)

set.seed(runif(1))总是给您set.seed(0)。您可以尝试使用set.seed(i)

您还可以在循环外仅使用一个set.seed


  

我将runif(1)更改为runif(1) * 100,但每次运行仍然得到相同的输出。

     

我添加了set.seed(),因为如果我将其删除,则该循环将为我提供所有迭代相同的结果。

     

我理解您的意思,但是问题是出了点问题,因为在每次运行/迭代中我得到的结果都是相同的。

谁告诉你kmeans总是给出随机结果?这取决于您的数据。以下示例明确地包含两个簇,因此kmeans不会表现出随机性。

set.seed(0)
X <- rbind(matrix(rnorm(100), 50), matrix(rnorm(100, 10), 50))
plot(X)

## 50 run
cl <- replicate(50, kmeans(X, 2), FALSE)

## size[1]
sapply(cl, "[[", c(7, 1))
# [1] 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
#[26] 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50

## size[2]
sapply(cl, "[[", c(7, 2))
# [1] 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
#[26] 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50

## iter
sapply(cl, "[[", 8)
# [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
#[39] 1 1 1 1 1 1 1 1 1 1 1 1

两个聚类的中心是不变的,直到标记为止。有时将图中左下的群集视为第一个群集,而有时将右上的群集视为第一个群集。

## center
ctr <- lapply(cl, "[[", 2)
unique(ctr)
#[[1]]
#        [,1]        [,2]
#1 0.02393097  0.02140593    ## lower left cluster is the 1st cluster
#2 9.78910937 10.11978752
#
#[[2]]
#        [,1]        [,2]
#1 9.78910937 10.11978752    ## upper right cluster is the 1st cluster
#2 0.02393097  0.02140593

如果要查看不确定性,请尝试一些“模糊”数据:

X <- matrix(runif(200), 100)
plot(X)

如果您从该数据集中请求2个聚类,则kmeans可能会在每次运行中给出不同的结果。如果要求3个群集,则结果更加不确定。


备注

请勿在每次运行时比较totss,因为它是固定的。比较对中心位置敏感的withinsstot.withinss

答案 1 :(得分:0)

数据太极端了,那么可能只有一个最优值。

在显示的数据部分中,第一列是常数(=无关紧要),最后一列的大小太低而无足轻重。另外两个只有两个值。因此,几乎可以肯定找到了这个微不足道的二进制拆分。

所以问题出在你的数据上。