确定与群集中心最近的x,y点是什么

时间:2018-02-26 06:48:02

标签: r

我有随机群集的以下数据:

iris$cluster = sample(0:1, nrow(iris), replace=TRUE)

现在我使用以下代码计算两个集群的中心:

centers=iris %>% 
 group_by(cluster) %>% 
 summarise_at(vars(matches("Sepal")), mean)

现在我想为数据集中的每一行计算它们是否更接近中心的集群1的中心 因此,基本上中心0的欧氏距离与第1,2,3行等的1相比......

关于什么是最有效的做法的任何想法是R?

1 个答案:

答案 0 :(得分:1)

根据问题的维度,一种方法是创建每行中心的排列,然后找到每行的最小值

library(data.table)
library(microbenchmark)

#create data
DT <- setDT(copy(iris))
set.seed(0L)
cols <- grep("^Sepal", names(DT), value=TRUE)
centers <- DT[, lapply(.SD, mean), 
    by=.("cluster"=sample(0:1, nrow(iris), replace=TRUE)), 
    .SDcols=cols]
setnames(centers, cols, paste0("mean_", cols))

CJ.dft <- function(...) {
    Reduce(f=function(x, y) cbind(x[rep(1:nrow(x), times=nrow(y)),], y[rep(1:nrow(y), each=nrow(x)),]),
        x=list(...)[-1],
        init=..1)
} #CJ.dft

crossJoinMtd <- function() {
    #cross join data with centers
    ans <- CJ.dft(DT[, rn:=.I], centers)

    #find the closest cluster
    ans[,
        .(ClosestCluster=cluster[which.min((Sepal.Length - mean_Sepal.Length)^2 + (Sepal.Width - mean_Sepal.Width)^2)]), 
        by=.(rn)]
}

样本用法:

crossJoinMtd()
#      rn ClosestCluster
#  1:   1              1
#  2:   2              0
#  3:   3              0
#  4:   4              0
#  5:   5              1
# ---                   
#146: 146              1
#147: 147              0
#148: 148              1
#149: 149              1
#150: 150              0

一些时间:

microbenchmark(crossJoinMtd(),
    times=100L)

# Unit: milliseconds
#           expr    min      lq     mean  median      uq     max neval
# crossJoinMtd() 2.7325 3.03085 3.558447 3.26885 3.58805 14.6075   100

如果OP可以提供有关簇或维度数量的更多详细信息,则可以进一步优化。