2016-12-23 13 views
0

Я успешно выполнил разделение по окружности с помощью функции pam (пакет кластеров в R), и теперь я хотел бы использовать результаты для атрибуции новых наблюдений ранее определенные кластеры/медоиды.PAM Clustering - использовать результаты в другом наборе данных

Другой способ поставить проблемы является, учитывая к кластеры/medoids, которые были найдены в РАМ функции , которая ближе к дополнительному наблюдению, которое не было в исходном наборе данных?

x<-matrix(c(1,1.2,0.9,2.3,2,1.8, 
      3.2,4,3.1,3.9,3,4.4),6,2) 
x 
    [,1] [,2] 
[1,] 1.0 3.2 
[2,] 1.2 4.0 
[3,] 0.9 3.1 
[4,] 2.3 3.9 
[5,] 2.0 3.0 
[6,] 1.8 4.4 
pam(x,2) 

Наблюдение 1, 3 и 5, и 2, 4 и 6 сгруппированы вместе и наблюдение 1 и 6 является medoids:

Medoids: 
    ID   
[1,] 1 1.0 3.2 
[2,] 6 1.8 4.4 
Clustering vector: 
[1] 1 2 1 2 1 2 

В настоящее время, к которому кластеру/медоид у должен быть отнесен /связан с?

y<-c(1.5,4.5) 

О, и в случае, если у вас есть несколько решений, время вычисления имеет значение в большом наборе данных, который у меня есть.

+1

Вы можете рассчитать расстояние от медианы у и которые когда-либо расстояние меньше. Y будет принадлежать этому кластеру. –

+0

Вам не нужна библиотека для вычислений 'which.min' и расстояния. ** Просто напишите эту * одну строку * кода самостоятельно! ** –

ответ

2

Попробуйте для K кластеров в целом:

k <- 2 # pam with k clusters 
res <- pam(x,k) 

y <- c(1.5,4.5) # new point 

# get the cluster centroid to which the new point is to be assigned to 
# break ties by taking the first medoid in case there are multiple ones 

# non-vectorized function 
get.cluster1 <- function(res, y) which.min(sapply(1:k, function(i) sum((res$medoids[i,]-y)^2))) 

# vectorized function, much faster 
get.cluster2 <- function(res, y) which.min(colSums((t(res$medoids)-y)^2)) 

get.cluster1(res, y) 
#[1] 2 
get.cluster2(res, y) 
#[1] 2 

# comparing the two implementations (the vectorized function takes much les s time) 
library(microbenchmark) 
microbenchmark(get.cluster1(res, y), get.cluster2(res, y)) 

#Unit: microseconds 
#     expr min  lq  mean median  uq  max neval cld 
# get.cluster1(res, y) 31.219 32.075 34.89718 32.930 33.358 135.995 100 b 
# get.cluster2(res, y) 17.107 17.962 19.12527 18.817 19.245 41.483 100 a 

Расширение для произвольной функции расстояния:

# distance function 
euclidean.func <- function(x, y) sqrt(sum((x-y)^2)) 
manhattan.func <- function(x, y) sum(abs(x-y)) 

get.cluster3 <- function(res, y, dist.func=euclidean.func) which.min(sapply(1:k, function(i) dist.func(res$medoids[i,], y))) 
get.cluster3(res, y) # use Euclidean as default 
#[1] 2 
get.cluster3(res, y, manhattan.func) # use Manhattan distance 
#[1] 2 
+0

Обратите внимание, что этот код является только евклидовым расстоянием - но вы не использовали бы пэм с эвклидовым расстоянием. –

+0

@ Anony-Mousse мы можем использовать любую функцию расстояния для замены евклидова. –