double サイズ 19347 x 19347 の最大 110 の共分散行列を作成し、それらをすべて加算する必要があります。
これ自体はそれほど難しくなく、小さな行列の場合は次のコードで問題なく動作します。
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]))
}
}
}
メモリを節約するために、個々の行列を計算するのではなく、各ファイルをループするときにそれらを加算します。
問題は、使用する必要がある実際のデータで実行すると、時間がかかりすぎることです。実際にはそれほど多くのデータはありませんが、CPU とメモリを集中的に使用するジョブだと思います。したがって、約 10 時間実行しても結果は計算されません。
Map Reduce (AWS EMR) の使用を検討しましたが、ビッグデータの問題ではないため、これが Map Reduce の問題であるとは思わないという結論に達しました。ただし、これは私が遊んでいたマッパーとリデューサーのコードです。
#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)
誰でもこの問題を解決する方法を提案できますか?
前もって感謝します
編集
以下のコメンターの何人かからの大きな助けのおかげで、コードを修正して、はるかに効率的になりました。
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 GB の RAM を持っていますが、プログラムを実行すると、R はそのうちの 4.5 GB しか使用せず、少量の空き容量があります。
Mac OS X Snow Leopard と R 64bit v. 2.15 を実行しています。