我很困惑。我想通过使用mclapply:parallel来加快我的算法,但当我比较时间效率时,application仍然获胜。
我正在通过函数quansm调用的rq.fit.fnb:quantreg平滑log2ratio数据,并将数据包装到矩阵/列表中,以供apply/lapply(mclapply)使用。
我这样调整我的数据:
q = matrix(data, ncol=N) # wrapping into matrix (using N = 2, 4, 6 or 8)
ql = as.list(as.data.frame(q)) # making list
时间比较:
apply=system.time(apply(q, 1, FUN=quantsm, 0.50, 2))
lapply=system.time(lapply(ql, FUN=quantsm, 0.50, 2))
mc2lapply=system.time(mclapply(ql, FUN=quantsm, 0.50, 2, mc.cores=2))
mc4lapply=system.time(mclapply(ql, FUN=quantsm, 0.50, 2, mc.cores=4))
mc6lapply=system.time(mclapply(ql, FUN=quantsm, 0.50, 2, mc.cores=6))
mc8lapply=system.time(mclapply(ql, FUN=quantsm, 0.50, 2, mc.cores=8))
timing=rbind(apply,lapply,mc2lapply,mc4lapply,mc6lapply,mc8lapply)
函数量子:
quantsm <- function (y, p = 0.5, lambda) {
# Quantile smoothing
# Input: response y, quantile level p (0<p<1), smoothing parmeter lambda
# Result: quantile curve
# Augment the data for the difference penalty
m <- length(y)
E <- diag(m);
Dmat <- diff(E);
X <- rbind(E, lambda * Dmat)
u <- c(y, rep(0, m - 1))
# Call quantile regression
q <- rq.fit.fnb(X, u, tau = p)
q
}
函数rq.fit.fnb(quantreg库):
rq.fit.fnb <- function (x, y, tau = 0.5, beta = 0.99995, eps = 1e-06)
{
n <- length(y)
p <- ncol(x)
if (n != nrow(x))
stop("x and y don't match n")
if (tau < eps || tau > 1 - eps)
stop("No parametric Frisch-Newton method. Set tau in (0,1)")
rhs <- (1 - tau) * apply(x, 2, sum)
d <- rep(1, n)
u <- rep(1, n)
wn <- rep(0, 10 * n)
wn[1:n] <- (1 - tau)
z <- .Fortran("rqfnb", as.integer(n), as.integer(p), a = as.double(t(as.matrix(x))),
c = as.double(-y), rhs = as.double(rhs), d = as.double(d),
as.double(u), beta = as.double(beta), eps = as.double(eps),
wn = as.double(wn), wp = double((p + 3) * p), it.count = integer(3),
info = integer(1), PACKAGE = "quantreg")
coefficients <- -z$wp[1:p]
names(coefficients) <- dimnames(x)[[2]]
residuals <- y - x %*% coefficients
list(coefficients = coefficients, tau = tau, residuals = residuals)
}
对于长度为2000的数据矢量,我得到:
(值=以秒为单位的经过时间;列=平滑矩阵/列表的不同列数)
2cols 4cols 6cols 8cols
apply 0.178 0.096 0.069 0.056
lapply 16.555 4.299 1.785 0.972
mc2lapply 11.192 2.089 0.927 0.545
mc4lapply 10.649 1.326 0.694 0.396
mc6lapply 11.271 1.384 0.528 0.320
mc8lapply 10.133 1.390 0.560 0.260
对于长度为4000的数据,我得到:
2cols 4cols 6cols 8cols
apply 0.351 0.187 0.137 0.110
lapply 189.339 32.654 14.544 8.674
mc2lapply 186.047 20.791 7.261 4.231
mc4lapply 185.382 30.286 5.767 2.397
mc6lapply 184.048 30.170 8.059 2.865
mc8lapply 182.611 37.617 7.408 2.842
为什么应用程序比mclapply更有效?也许我只是犯了一些初学者常犯的错误。
谢谢你的反应。
看起来mclapply
与lapply
的比较非常好,但lapply
与apply
的比较不好。原因可能是用apply
迭代q
的行,用lapply
和mclapply
迭代q
的列。这可能是性能差异的原因。
如果您真的想迭代q
的行,您可以使用:创建ql
ql <- lapply(seq_len(nrow(x)), function(i) x[i,])
如果您想迭代q
的列,那么您应该在apply
中设置MARGIN=2
,正如@flodel所建议的那样。
lapply
和mclapply
都将在数据帧的列上迭代,因此您可以使用:创建ql
ql <- as.data.frame(q)
这是有道理的,因为数据帧实际上是一个列表。