Параллельная матрица расстояний в R

в настоящее время я использую встроенную функцию dist для вычисления матрицы расстояний в R.

dist(featureVector,method="manhattan")

это в настоящее время bottlneck приложения и поэтому идея была parallize этой задачи(концептуально это должно быть возможно)

поиск в google и этот форум не удался.

у кого-нибудь есть идея?

6 ответов


вот структура для одного маршрута, по которому вы могли бы пойти. Это не быстрее, чем просто использовать dist() функция, вместо этого принимая много времен более длиной. Он обрабатывает параллельно, но даже если время вычисления было уменьшено до нуля, время запуска функции и экспорта переменных в кластер, вероятно, будет больше, чем просто использование dist()

library(parallel)

vec.array <- matrix(rnorm(2000 * 100), nrow = 2000, ncol = 100)

TaxiDistFun <- function(one.vec, whole.matrix) {
    diff.matrix <- t(t(whole.matrix) - one.vec)
    this.row <- apply(diff.matrix, 1, function(x) sum(abs(x)))
    return(this.row)
}

cl <- makeCluster(detectCores())
clusterExport(cl, list("vec.array", "TaxiDistFun"))

system.time(dist.array <- parRapply(cl, vec.array,
                        function(x) TaxiDistFun(x, vec.array)))

stopCluster(cl)

dim(dist.array) <- c(2000, 2000)

пакет R amap обеспечивает надежные и распараллеленные функции для кластеризации и анализа основных компонентов. Среди этих функций р-н метод предлагает то, что вы ищете: вычисляет и возвращает матрицу расстояний параллельно.

Dist(x, method = "euclidean", nbproc = 8)

код выше вычисляет евклидово расстояние с 8 потоками.


вы также можете использовать


Я пользователь windows, ищущий эффективный способ вычисления матрицы расстояний, чтобы использовать ее в иерархической кластеризации (например, используя функцию hclust из пакета "статистика"). Функция Dist не работает параллельно в Windows поэтому мне пришлось искать что-то другое, и я нашел "wordspace" пакет Стефана Эверта, который содержит


Я также работаю с несколько большими матрицами расстояний и пытаюсь ускорить вычисления. Будет ли Бенсон выше, вероятно, будет прав, когда он говорит, что "время запуска функции и экспорта переменных в кластер, вероятно, будет больше, чем просто использование".

однако я думаю, что это относится к матрицам расстояний с малым и средним размером. См. пример ниже, используя функции Dist из пакета amap С 10 процессоров, dist из пакета статистика и rdist пакета поля, который вызывает функцию Fortran. В первом примере создается матрица расстояний 400 x 400. Второй создает матрицу расстояний 3103 x 3103.

require(sp)
require(fields)
require(amap)
data(meuse.grid)
meuse.gridA <- meuse.grid[1:400, 1:2]
meuse.gridB <- meuse.grid[, 1:2]

# small distance matrix
a <- Sys.time()
invisible(dist(meuse.gridA, diag = TRUE, upper = TRUE))
Sys.time() - a
Time difference of 0.002138376 secs
a <- Sys.time()
invisible(Dist(meuse.gridA, nbproc = 10, diag = TRUE, upper = TRUE))
Sys.time() - a
Time difference of 0.005409241 secs
a <- Sys.time()
invisible(rdist(meuse.gridA))
Sys.time() - a
Time difference of 0.02312016 secs

# large distance matrix
a <- Sys.time()
invisible(dist(meuse.gridB, diag = TRUE, upper = TRUE))
Sys.time() - a
Time difference of 0.09845328 secs
a <- Sys.time()
invisible(Dist(meuse.gridB, nbproc = 10, diag = TRUE, upper = TRUE))
Sys.time() - a
Time difference of 0.05900002 secs
a <- Sys.time()
invisible(rdist(meuse.gridB))
Sys.time() - a
Time difference of 0.8928168 secs

обратите внимание, как время вычисления сократилось с 0.09845328 сек до 0.05900002 сек, используя Dist по сравнению с dist когда матрица расстояний была большой (3103 3103 х). Таким образом, я бы предложил вам использовать функцию Dist от amap пакет при условии, что у вас есть несколько доступных процессоров.


я обнаружил, что parallelDist на порядок быстрее, чем dist, и пережевывает гораздо меньше виртуальной памяти в процессе, на моем Mac под Microsoft R Open 3.4.0. Однако слово предупреждения - мне не удалось скомпилировать его на R 3.3.3. Он не перечисляет версию R как зависимость, но я подозреваю, что это так.