R中加权最小二乘均值估计的加速逆计算

时间:2014-06-13 14:15:35

标签: r performance matrix regression

我需要加快计算R中WLS的beta平均估计值 - 我能够加快协方差计算thanks to SO,现在我想知道是否还有另一个技巧来加速平均计算(或者我正在做的事情已经足够有效)。

n = 10000
y = rnorm(n, 3, 0.4)
X = matrix(c(rnorm(n,1,2), sample(c(1,-1), n, replace = TRUE), rnorm(n,2,0.5)), nrow = n, ncol = 3)
Q = diag(rnorm(n, 1.5, 0.3))
wls.cov.matrix = crossprod(X / sqrt(diag(Q)))
Q.inv = diag(1/diag(Q))
wls.mean = wls.cov.matrix%*%t(X)%*%Q.inv%*%y
system.time(wls.cov.matrix%*%t(X)%*%Q.inv%*%y)

还有另外类似于wls.cov.matrix crossprod的技巧来加速整个平均计算,还是没有必要?谢谢!

2 个答案:

答案 0 :(得分:2)

在你上一个问题的答案中,你被教导crossprod。再次使用该功能:

n = 1e4
set.seed(42)
y = rnorm(n, 3, 0.4)
X = matrix(c(rnorm(n,1,2), sample(c(1,-1), n, replace = TRUE), rnorm(n,2,0.5)), nrow = n, ncol = 3)
Q = diag(rnorm(n, 1.5, 0.3))
wls.cov.matrix = crossprod(X / sqrt(diag(Q)))
Q.inv = diag(1/diag(Q))
wls.mean = wls.cov.matrix%*%t(X)%*%Q.inv%*%y
wls.mean2 <- wls.cov.matrix %*% crossprod(X, Q.inv) %*% y
all.equal(wls.mean, wls.mean2)
#[1] TRUE

library(microbenchmark)
microbenchmark(wls.cov.matrix %*% t(X) %*% Q.inv %*% y,
               wls.cov.matrix %*% crossprod(X, Q.inv) %*% y,
               times=5)

#Unit: milliseconds
#                                        expr       min        lq    median       uq       max neval
#     wls.cov.matrix %*% t(X) %*% Q.inv %*% y 1019.3955 1022.1679 1022.2766 1024.540 1025.9131     5
#wls.cov.matrix %*% crossprod(X, Q.inv) %*% y  314.0622  315.3588  315.3933  317.024  317.1142     5

使用某些矩阵代数技巧可能会提高性能,但这不是我的强项。

答案 1 :(得分:2)

通过在此过程中不使用任何n乘n矩阵,可以实现性能的主要增益。我的意思是没有Q矩阵,只能用它的对角线。

以@Roland的答案为基础:

Qdiag = rnorm(n, 1.5, 0.3);
Q = diag(Qdiag);

wls.mean3 <- wls.cov.matrix %*% crossprod(X/Qdiag, y);
all.equal(wls.mean, wls.mean3)
microbenchmark(wls.cov.matrix %*% t(X) %*% Q.inv %*% y,
               wls.cov.matrix %*% crossprod(X, Q.inv) %*% y,
               wls.cov.matrix %*% crossprod(X/Qdiag, y),
           times=5)
#      wls.cov.matrix %*% t(X) %*% Q.inv %*% y 358050.195 363713.250 368820.818 372414.747 374824.56     5
# wls.cov.matrix %*% crossprod(X, Q.inv) %*% y  79449.856  81411.195  84616.706  85351.968  88108.62     5
#     wls.cov.matrix %*% crossprod(X/Qdiag, y)    279.092    284.867    285.252    291.796    295.26     5