稀疏矩阵上的所有对相关

时间:2015-03-18 16:49:39

标签: r data.table

我编写了一些代码来计算数据集中所有id对之间的相关性。输入和输出格式如下所示:

Input:  obsid | varid | value
Output: obsid1 | obsid2 | correl

我意识到相关和所有对功能都可用,并在之前讨论过。这可能有所不同,因为我使用键/值或深度格式进行输入和输出。此外,我需要解决的实例有大约200,000个观测值和~500个密度为20%的变量。实际上,我需要计算4 x 10 ^ 10个相关性!所以,我希望能够提高效率。

这是创建实例的代码:

require(data.table)

CreateInstance <- function(nobs,nvar,density) {
    dtbl <- data.table(
        do.call("rbind", 
            lapply(1:nobs, function(n) { 
                v <- which(runif(nvar)<density)
                if(length(v)>0) {cbind(n,v)}
            })
        )
    )
    setnames(dtbl, c("obsid","varid"))
    dtbl$value <- as.numeric(sample(1:50, nrow(dtbl), replace=TRUE))
    return(dtbl)
}

代码运行如下:

set.seed(100)
nobs <- 10
nvar <- 4
dens <- .5
inst <- CreateInstance(nobs,nvar,dens)

计算1次观察的所有相关性并选择前N

的代码
GetCorrelationsForObs <- function(n) {
    dtbl <- inst[inst[obsid==n,2:3,with=FALSE]][, list(sumxy=sum(value*i.value)), by=obsid]
    if(nrow(dtbl)==0) {return(data.table(obsid1=integer(0),obsid2=integer(0),correl=numeric(0)))}
    dtbl <- inst.summ[dtbl][obsid!=n]
    infoy <- inst.summ[obsid==n,c(sumx,sdx)]
    dtbl <- dtbl[, list(obsid2=obsid, 
        correl=(nvar*sumxy-infoy[1]*sumx)/(infoy[2]*sdx))][!is.na(correl),][order(-rank(correl))]
    return(if(nrow(dtbl)>nbors) cbind(obsid1=n,dtbl[1:nbors]) else cbind(obsid1=n,dtbl))
}

此代码使用

运行
inst.summ <- inst[, list(sumx=sum(value), sdx=sqrt(nvar*sum(value^2)-sum(value)^2)), by="obsid"]
nbors <- 2
setkey(inst,varid)
setkey(inst.summ,obsid)
correl.dt <- data.table(do.call("rbind", lapply(1:nobs, GetCorrelationsForObs) ))

对于较大的实例nobs <- 200000nvar <- 500dens <- .2nbors <- 100,50次调用需要38秒才能GetCorrelationsForObs

问题:我意识到问题是embarrassingly parallel,我可以轻松地并行运行它。我正在寻找有关如何让GetCorrelationsForObs更快运行的输入。这是我第一次使用data.table并想了解它是否可以运行得更快(不同的键?其他选项?)。感谢。

0 个答案:

没有答案