Мне нужно создать ~ 110 ковариационных матриц размером в 19347 x 19347, а затем добавить их все вместе.Создание большой ковариационной матрицы
Это само по себе не очень сложно, и для меньших матриц следующий код работает нормально.
covmat <- matrix(0, ncol=19347, nrow=19347)
files<-list.files("path/to/folder/")
for(name in files){
text <- readLines(paste("path/to/folder/", name, sep=""), n=19347, encoding="UTF-8")
for(i in 1:19347){
for(k in 1:19347){
covmat[i, k] <- covmat[i,k] + (as.numeric(text[i]) * as.numeric(text[k]))
}
}
}
Для сохранения памяти Я не вычисляю каждую отдельную матрицу, а добавляю ее вместе, когда она проходит через каждый файл.
Проблема заключается в том, что я запускаю ее на реальных данных, которые мне нужны, чтобы использовать это слишком долго. На самом деле данных не так много, но я думаю, что это работа с процессором и памятью. Таким образом, его запуск в течение ~ 10 часов не вычисляет результат.
Я искал попытку использования Map Reduce (AWS EMR), но я пришел к выводу, что я не верю, что это проблема с уменьшением карты, поскольку это не большая проблема с данными. Однако вот код для моего картографа и редуктора, с которым я играл, если я только делал это неправильно.
#Mapper
text <- readLines("stdin", n=4, encoding="UTF-8")
covmat <- matrix(0, ncol=5, nrow=5)
for(i in 1:5){
for(k in 1:5){
covmat[i, k] <- (as.numeric(text[i]) * as.numeric(text[k]))
}
}
cat(covmat)
#Reducer
trimWhiteSpace <- function(line) gsub("(^ +)|(+$)", "", line)
splitIntoWords <- function(line) unlist(strsplit(line, "[[:space:]]+"))
final <- matrix(0, ncol=19347, nrow=19347)
## **** could wo with a single readLines or in blocks
con <- file("stdin", open = "r")
while (length(line <- readLines(con, n = 1, warn = FALSE)) > 0) {
line <- trimWhiteSpace(line)
words <- splitIntoWords(line)
final <- final + matrix(as.numeric(words), ncol=19347, nrow=19347)
}
close(con)
cat(final)
Может кто-нибудь предложить, как решить эту проблему?
Заранее спасибо
EDIT
Благодаря большой помощи со стороны некоторых комментаторов ниже я пересмотрел код, чтобы он намного эффективнее.
files<-list.files("path/to/file")
covmat <- matrix(0, ncol=19347, nrow = 19347)
for(name in files){
invec <- scan(paste("path/to/file", name, sep=""))
covmat <- covmat + outer(invec,invec, "*")
}
Вот пример файла, который я пытаюсь обработать.
1 0.00114582882882883
2 -0.00792611711711709
... ...
19346 -0.00089507207207207
19347 -0.00704709909909909
При запуске программы все равно требуется ~ 10 минут на файл. Есть ли у кого-нибудь советы о том, как это можно ускорить?
У меня 8 ГБ ОЗУ, и когда программа запускается R, она использует только 4,5 ГБ, и есть небольшая сумма бесплатно.
Я бегу Mac OS X Snow Leopard и R 64-битной ст. 2,15
Что-то не так; Я не могу сказать вам, что, но не должно занимать более 10 часов, чтобы выполнять умножения и дополнения на 44E9. Как долго он обрабатывает только одну матрицу? Также рассмотрите преобразование каждого вектора из текста в числовой * один раз *, а не внутри цикла. Кроме того, вы пытались переставить свой порядок вложения в петлю? Я не знаю, является ли R [основным или крупным] (http://en.wikipedia.org/wiki/Row_major), но если вам не повезло, вы будете пропускать кеш при каждом обновлении на 'covmat'. –
Вы НЕ должны добавлять элемент матрицы по элементу. Просто используйте «+». Не имеет смысла преобразовывать числовые в текст и использовать 'readLines'. Если вы знаете размеры файла и все его числовые, вы можете просто использовать 'scan()' для ввода. В pkg MASS есть функция 'write.matrix', которая может сэкономить накладные расходы на хранение. Возможно, вам захочется просмотреть ваши старые вопросы. Есть некоторая нерешительность в том, чтобы тратить много времени, когда есть послужной список непринятия. –
Спасибо за ответ. Я ждал час для одной матрицы, но он не вычислил результат, поэтому я отменил работу. – TrueWheel