Создание очень большой матрицы косинусов
Мне нужно построить матрицу косинусов (то есть матрицу косинусных расстояний между каждой комбинацией векторов) для набора векторов с 89 000 векторов длиной 500, что приведет к окончательной матрице 89 000x89 000. Мой нынешний подход кажется очень неэффективным, что приводит к очень длительному времени обработки (например, использование векторного набора с 52 000 векторов длиной 500 занимает ~36 часов для построения матрицы 52 000x52 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 (то есть, используя альтернативы пакету большой памяти), либо с совершенно другим набором инструментов (например, код на python или C++). Пожалуйста, имейте в виду, что многие (большинство?) Из часто используемых функций R не будут работать с матрицами такого размера; Я исследовал многообещающие пути только для того, чтобы столкнуться с 32/64-битным ограничением длинных векторов (т.е. Ошибка: ... Слишком много индексов (>2^31-1) для извлечения; см. Максимальная длина для вектора в R).
Ура!