Мне нужно построить косинусная матрица (то есть матрица косинусных расстояний между каждой комбинацией векторов) для набора векторов с 89 000 векторов длиной 500, что приводит к окончательной матрице 89 000 x 89 000. Мой нынешний подход кажется очень неэффективным, что приводит к очень длительному времени обработки (например, использование набора векторов с 52 000 векторов длиной 500 занимает ~ 36 часов для построения матрицы 52 000 x 52 000).
Мое текущее решение использует версию R 3.0.1 (2013-05-16), работающую на 64-битной версии Ubuntu 13.10 на процессоре Intel Core i7 4960X с платформой 3,60 ГГц x 12 и 64 ГБ ОЗУ. Несмотря на то, что я использовал 64-битную систему, я все еще сталкиваюсь с ошибками длины вектора, возвращенными из собственных подфункций в R (например, Ошибка: … слишком много индексов (> 2 ^ 31-1) для извлечения); похоже, нет решения этой проблемы. Таким образом, мое текущее решение использует big.matrix объекты из bigmemory пакет. Я также использую doParallel пакет для использования всех 12 процессорных ядер на моей рабочей станции.
Это код, который я сейчас использую:
setSize <- nrow(vectors_gw2014_FREQ_csMns) #i.e. =89,095
COSmatrix <- filebacked.big.matrix(
#set dimensions and element value type
setSize, setSize, init=0,
type="double",
backingpath = './COSmatrices',
backingfile = "cosMAT_gw2014_VARppmi.bak",
descriptorfile = "cosMAT_gw2014_VARppmi.dsc")
#initialize progress bar
pb <- txtProgressBar(min = 0, max = setSize, style = 3)
feErr <- foreach(i=1:setSize) %dopar% {
COSmatrix <- attach.big.matrix("./COSmatrices/cosMAT_gw2014_FREQ_csMns.dsc")
setTxtProgressBar(pb, i)
for (j in 1:setSize)
{
if (j < i)
{
COSmatrix[i,j] <- cosine( as.vector(vectors_gw2014_FREQ_csMns[i,],mode="numeric"),
as.vector(vectors_gw2014_FREQ_csMns[j,],mode="numeric") )
COSmatrix[j,i] <- COSmatrix[i,j]
}
else break
}#FOR j
}#FOREACH DOPAR i
close(pb)
Я подозреваю, что главная проблема с моим кодом — т.е. приводит к чрезмерному времени обработки — это вызов для повторного присоединения объекта big.matrix в каждой итерации основного цикла foreach:
COSmatrix <- attach.big.matrix("./COSmatrices/cosMAT_gw2014_FREQ_csMns.dsc")
Однако это, по-видимому, необходимо для того, чтобы иметь доступ к объекту big.matrix в FOREACH (то есть к функции параллельной обработки из doparallel упаковка) петля; без этой строки кода в главном цикле объект COSmatrix недоступен (см. Использование big.matrix в циклах foreach).
Я ищу любые и все предложения по оптимизации этого процесса и сокращению времени обработки от дней до часов. Это означает, что я открыт для использования других подходов, либо внутри R (то есть, используя альтернативы пакету Bigmemory), либо с совершенно другим набором инструментов (например, код Python или C ++). Пожалуйста, имейте в виду, что многие (большинство?) Из часто используемых функций R не будут работать с матрицами такого размера; Я исследовал множество многообещающих путей только для того, чтобы столкнуться с 32/64-битным ограничением длинных векторов (т.е. Ошибка: … слишком много индексов (> 2 ^ 31-1) для извлечения; увидеть Максимальная длина для вектора в R).
Ура!
Задача ещё не решена.