【发布时间】:2018-08-06 04:22:46
【问题描述】:
我需要加快我正在执行的模拟,我发现我的一个函数的特定组件是造成速度如此缓慢的主要原因。
这部分函数的工作是演示从分布中增加随机抽奖的数量 (n) 如何提高该组抽奖的平均估计精度。
程序如下:
- 样本 n 从具有固定参数 mu 和 sigma 的正态分布中随机抽取,其中 n 从1 到 500。(在本例中,我只设置 mu = 500 和 sigma = 100。)
- 在每个 n 处,计算所有采样值的平均值
- 重复此过程 1000 次。
我目前在嵌套循环中使用它,我知道它效率不高。代码如下:
# generate empty container for the simulated data
# parameters:
# n_repetition = how many times to repeat the whole procedure
# max_n = maximum number of draws to explore
set.seed(42)
n_repetition <- 1000
max_n <- 500
# function to generate n random draws, and find their mean
r_norm <- function(n, mean, sd){
temp <- rnorm(n, mean, sd)
return(mean(temp))
}
sim_results <- matrix(0, nrow = n_repetition, ncol = max_n)
for(i in 1:n_repetition){
for(j in 1:max_n){
sim_results[i, j] <- r_norm(j, mean = 500, sd = 100)
}
}
这很慢;在我的机器上大约 9.80 秒。因此,我尝试使用“应用系列”方法。事实证明这同样慢:
sim_results <- matrix(1:max_n, nrow = max_n, ncol = n_repetition)
sim_results <- apply(sim_results, 1:2, r_norm, mean = 500, sd = 100)
我不确定如何继续。我认为 R 中的减速是循环,但我使用“应用”删除了它,它同样慢。
我什至想不出如何让它更快,所以非常感谢任何帮助。
【问题讨论】:
-
Apply 仍在循环中,它只是隐藏了循环,因此您不必自己编写。这是您正在做的一个非常简单的程序 - 没有太多工作可以加快速度。您可以直接调用
.Internal(mean())而不是mean()来减少几微秒的调度和输入检查,但在不到10 秒的时间内完成500k 次模拟似乎并不算太糟糕。为什么你需要这个更快?你是否经常重新模拟这个?你需要那里的每一个j吗?获得 10 倍加速的简单方法是将j运行为seq(10, max_n, by = 10)而不是1:max_n -
谢谢@Gregor。不幸的是,我确实需要那里的每一个 j。我试图简化我的完整模拟背后的想法,以专注于这个问题。对于传递给采样分布的每个组参数值(64 个参数变体),上述过程可能会重复 1000 次。这意味着完整的模拟将需要大约一周的时间。
-
而不是每次重复生成 500 组不同的随机数。尝试生成一组 500 个数字并使用列表中的
cummean函数。然后为下一次重复生成一个新集合。 -
您的
apply与您的循环不同,您翻译了您的矩阵并且您没有在apply中使用mean,因此每个单元格值都是一个向量。你可能想要apply(sim_results, 1:2, function(x) mean(rnorm(x), mean = 500, sd = 100)) -
我建议你看看是随机抽签还是瓶颈所在。我的猜测是采取手段至少比从您的分布中随机抽取快一个数量级,这意味着获得大幅加速的唯一方法是减少抽取次数(或提高抽取速度)。 Dave2e 的建议,单抽 500 分并在上面使用
cummean是一个非常好的建议,如果您对此方法满意的话。
标签: r