考虑到中心的顺序,在 kmean 结果中重新标记样本

Relabel samples in kmean results considering the order of centers

我正在使用 kmeans 对我的数据进行聚类,对于生成的结果我有一个计划。

我想根据有序中心重新标记样本。考虑以下示例:

a = c("a","b","c","d","e","F","i","j","k","l","m","n")
b = c(1,2,3,20,21,21,40,41,42,4,23,50)

mydata = data.frame(id=a,amount=b)
result = kmeans(mydata$amount,3,nstart=10)

这是结果:

clus$cluster 
2 2 2 3 3 3 1 1 1 2 3 1

clus$centers
1 43.25
2  2.50
3 21.25


mydata = data.frame(mydata,label =clus$cluster)
mydata
    id amount  label
1   a      1        2
2   b      2        2
3   c      3        2
4   d     20        3
5   e     21        3
6   F     21        3
7   i     40        1
8   j     41        1
9   k     42        1
10  l      4        2
11  m     23        3
12  n     50        1

我正在寻找的是对中心进行排序并相应地生成标签:

1  2.50
2  21.25
3  43.25

并标记要前往的样本:

1 1 1 2 2 2 3 3 3 1 2 3 

结果应该是:

    id amount  label
1   a      1        1
2   b      2        1
3   c      3        1
4   d     20        2
5   e     21        2
6   F     21        2
7   i     40        3
8   j     41        3
9   k     42        3
10  l      4        1
11  m     23        2
12  n     50        3

我认为可以这样做,对中心进行排序,并且对于每个样本,将样本与中心的最小距离的索引作为该集群的标签。

还有其他方法可以让 R 自动完成吗?

一个想法是通过将您的中心与排序的中心相匹配来创建一个命名向量。然后将向量与 mydata$label 匹配并替换为向量的名称,即

i1 <- setNames(match(sort(result$centers), result$centers), rownames(result$centers))

as.numeric(names(i1)[match(mydata$label, i1)])
# [1] 1 1 1 2 2 2 3 3 3 1 2 3

你可以使用for循环,如果你不介意循环

cls <- result$cluster
for (i in 1 : length(result$cluster)) 
     result$cluster[cls == order(result$centers)[i]] <- i

result$cluster
#[1] 1 1 1 2 2 2 3 3 3 1 2 3