Прежде всего, я новичок в R (я начал вчера).
У меня есть две группы точек, data
и centers
, первая с размером n
и втораяразмером K
(например, n = 3823
и K = 10
), и для каждого i
в первом наборе мне нужно найти j
во втором с минимальным расстоянием.
Моя идея проста: для каждого i
, пусть dist[j]
будет расстояние между i
и j
, мне нужно всего лишь использовать which.min(dist)
, чтобы найти то, что я ищу.
Каждыйточка - это массив 64
удваивается, поэтому
> dim(data)
[1] 3823 64
> dim(centers)
[1] 10 64
Я пробовал с
for (i in 1:n) {
for (j in 1:K) {
d[j] <- sqrt(sum((centers[j,] - data[i,])^2))
}
S[i] <- which.min(d)
}
, что очень медленно (с n = 200
, это занимает более 40 с !!).Самое быстрое решение, которое я написал, это
distance <- function(point, group) {
return(dist(t(array(c(point, t(group)), dim=c(ncol(group), 1+nrow(group)))))[1:nrow(group)])
}
for (i in 1:n) {
d <- distance(data[i,], centers)
which.min(d)
}
Даже если он делает много вычислений, которые я не использую (потому что dist(m)
вычисляет расстояние между всеми строками m
), это путьбыстрее, чем другой (кто-нибудь может объяснить, почему?), но он не достаточно быстр для того, что мне нужно, потому что он не будет использоваться только один раз.Кроме того, код distance
очень уродлив.Я попытался заменить его на
distance <- function(point, group) {
return (dist(rbind(point,group))[1:nrow(group)])
}
, но это, кажется, в два раза медленнее.Я также пытался использовать dist
для каждой пары, но это также медленнее.
Я не знаю, что делать сейчас.Кажется, я делаю что-то очень неправильно.Любая идея о том, как сделать это более эффективно?
ps: мне нужно это, чтобы реализовать k-средства вручную (и мне нужно сделать это, это часть задания).Я считаю, что мне понадобится только евклидово расстояние, но я еще не уверен, поэтому я предпочту иметь некоторый код, в котором вычисление расстояния можно легко заменить.stats::kmeans
сделать все вычисления менее чем за одну секунду.