使用K Means和R对聚类点进行排序

时间:2012-04-09 14:58:37

标签: r cluster-analysis k-means

我在R中使用kmeans聚集了一组数据(包含4个维度的5000个点)。

我想按照到群集中心的距离来命令每个群集中的点。

很简单,数据看起来像这样(我使用子集来测试各种方法):

id  Ans Acc Que Kudos
1   100 100 100 100
2   85  83  80  75
3   69  65  30  29
4   41  45  30  22 
5   10  12  18  16
6   10  13  10  9
7   10  16  16  19
8   65  68  100 100
9   36  30  35  29
10  36  30  26  22

首先,我使用以下方法将数据集聚类为2个聚类:

(result <- kmeans(data, 2))

这将返回具有以下methods: cluster, centers etc.

的kmeans对象

但我无法弄清楚如何比较每个点并生成有序列表。

其次,我尝试了另一个SO用户here

建议的序列化方法

我使用这些命令:

clus <- kmeans(scale(x, scale = FALSE), centers = 3, iter.max = 50, nstart = 10)
mns <- sapply(split(x, clus$cluster), function(x) mean(unlist(x)))
result <- dat[order(order(mns)[clus$cluster]), ]

这似乎产生了一个有序列表但是如果我将它绑定到带标签的簇(使用以下cbind命令):

result <- cbind(x[order(order(mns)[clus$cluster]), ],clus$cluster)

我得到以下结果,似乎没有正确排序:

id  Ans Acc Que Kudos   clus
1   3   69  65  30  29  1
2   4   41  45  30  22  1
3   5   10  12  18  16  2
4   6   10  13  10  9   2
5   7   10  16  16  19  2
6   9   36  30  35  29  2
7   10  36  30  26  22  2
8   1   100 100 100 100 1
9   2   85  83  80  75  2
10  8   65  68  100 100 2

我不想无缘无故地编写命令,但要理解这种方法是如何工作的。如果有人可以帮助或传播一些信息,那将是非常好的。

EDIT :::::::::::

由于可以轻松地绘制聚类,我认为有一种更简单的方法来获得点和中心之间的距离并对其进行排序。

上述簇的中心(当使用k = 2时)如下。但我不知道如何与每个点进行比较。

     Ans    Accep     Que      Kudos
1 83.33333 83.66667 93.33333 91.66667
2 30.28571 30.14286 23.57143 20.85714 

NB ::::::::

我不需要使用顶级kmeans,但我想指定群集的数量并从这些群集中检索有序的点列表。

1 个答案:

答案 0 :(得分:6)

以下示例使用?kmeans中的第一个示例执行您的要求。它可能不是非常有效,但是可以建立起来。

#Taken straight from ?kmeans
x <- rbind(matrix(rnorm(100, sd = 0.3), ncol = 2),
           matrix(rnorm(100, mean = 1, sd = 0.3), ncol = 2))
colnames(x) <- c("x", "y")
cl <- kmeans(x, 2)

x <- cbind(x,cl = cl$cluster)

#Function to apply to each cluster to 
# do the ordering
orderCluster <- function(i,data,centers){
    #Extract cluster and center
dt <- data[data[,3] == i,]
ct <- centers[i,]

    #Calculate distances
dt <- cbind(dt,dist = apply((dt[,1:2] - ct)^2,1,sum))
    #Sort
dt[order(dt[,4]),]
}

do.call(rbind,lapply(sort(unique(cl$cluster)),orderCluster,data = x,centers = cl$centers))