这是一种基于数据行数估计时间的方法。我模拟了一个60列的数据帧,然后使用
lapply()
和
system.time()
以计算定时。
library(psych)
# create 9000 rows of data w/ 60 columns
system.time(data <- as.data.frame(matrix(round(runif(9000*60,min = 1, max = 5)),
nrow = 9000)))
id <- 1:9000
data <- cbind(id,data)
observations <- c(100,200,500,1000,2000)
theTimings <- lapply(observations,function(x){
system.time(r <- corr.test(data[id <= x,2:61],method = "kendall"))
})
theNames <- paste0("timings_",observations,"_obs")
names(theTimings) <- theNames
theTimings
…以及输出:
> theTimings
$timings_100_obs
user system elapsed
0.435 0.023 0.457
$timings_200_obs
user system elapsed
1.154 0.019 1.174
$timings_500_obs
user system elapsed
5.969 0.026 5.996
$timings_1000_obs
user system elapsed
24.260 0.045 24.454
$timings_2000_obs
user system elapsed
106.465 0.109 106.603
生成预测
我们可以从迄今为止的分析中获取数据,拟合模型,并预测更大数据集的时间。首先,我们用时序信息创建一个数据帧,然后拟合一个线性模型。我们将打印模型摘要以检查R^2的拟合度。
time <- c(0.457,1.174,5.996,24.454,106.603)
timeData <- data.frame(observations,time)
fit <- lm(time ~ observations, data = timeData)
summary(fit)
总结表明,线性模型似乎与数据很好地吻合,认识到我们使用了少量的观测值作为模型的输入。
> summary(fit)
Call:
lm(formula = time ~ observations, data = timeData)
Residuals:
1 2 3 4 5
9.808 4.906 -7.130 -16.769 9.186
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -14.970240 8.866838 -1.688 0.18993
observations 0.056193 0.008612 6.525 0.00731 **
---
Signif. codes: 0 â***â 0.001 â**â 0.01 â*â 0.05 â.â 0.1 â â 1
Residual standard error: 13.38 on 3 degrees of freedom
Multiple R-squared: 0.9342, Adjusted R-squared: 0.9122
F-statistic: 42.57 on 1 and 3 DF, p-value: 0.007315
接下来,我们将使用额外数量的观测值构建另一个数据帧,并使用它来生成预测的时间。
predictions <- data.frame(observations = c(3000,4000,5000,6000,7000,8000,9000))
data.frame(observations = predictions,predicted = predict(fit,predictions))
根据我们的模型,9000个观测数据帧在我的笔记本电脑上大约需要8.2分钟。
> data.frame(observations = predictions,predicted = predict(fit,predictions))
observations predicted
1 3000 153.6102
2 4000 209.8037
3 5000 265.9971
4 6000 322.1906
5 7000 378.3841
6 8000 434.5776
7 9000 490.7710
> 490 / 60
[1] 8.166667
我们需要在更多的观测值上运行模型,以确定是否有2000到9000之间的观测值会使算法降级到线性可扩展性以下。
此外,请注意,时序会因CPU速度、内核数量和机器上的可用RAM而异。这些测试是在2015年的MacBook Pro 15上进行的,配置如下。
改进模型
考虑到原始帖子和我的回答之间的来回评论,我们可以假设,在2000次观察之后,非线性效应变得突出。我们可以通过在模型中添加二次项并生成新的预测来测试这一点。
首先,我们将收集3000、4000和5000次观测的数据,以增加模型中的自由度,并提供更多数据,从中我们可以检测到二次效应。
> theTimings
$timings_3000_obs
user system elapsed
259.444 0.329 260.149
$timings_4000_obs
user system elapsed
458.993 0.412 460.085
$timings_5000_obs
user system elapsed
730.178 0.839 731.915
接下来,我们将运行有和没有二次效应的线性模型,生成预测,并比较结果。首先,我们将运行模型并打印二次模型的摘要。
observations <- c(100,200,500,1000,2000,3000,4000,5000)
obs_squared <- observations^2
time <- c(0.457,1.174,5.996,24.454,106.603,260.149,460.085,731.951)
timeData <- data.frame(observations,obs_squared,time)
fitLinear <- lm(time ~ observations, data = timeData)
fitQuadratic <- lm(time ~ observations + obs_squared, data = timeData)
summary(fitQuadratic)
> summary(fitQuadratic)
Call:
lm(formula = time ~ observations + obs_squared, data = timeData)
Residuals:
1 2 3 4 5 6 7 8
-0.2651 0.2384 0.7455 -0.2363 -2.8974 4.5976 -2.7581 0.5753
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.121e+00 1.871e+00 0.599 0.5752
observations -7.051e-03 2.199e-03 -3.207 0.0238 *
obs_squared 3.062e-05 4.418e-07 69.307 1.18e-08 ***
---
Signif. codes: 0 â***â 0.001 â**â 0.01 â*â 0.05 â.â 0.1 â â 1
Residual standard error: 2.764 on 5 degrees of freedom
Multiple R-squared: 0.9999, Adjusted R-squared: 0.9999
F-statistic: 3.341e+04 on 2 and 5 DF, p-value: 4.841e-11
不仅使用二次模型将R^2提高到0.9999,而且在α=0.05时,线性项和二次项都与0有显著差异。有趣的是,模型中有一个二次项,线性效应是负的。
最后,我们将为这两个模型生成预测,将它们组合成一个数据帧并打印结果。
predLinear = predict(fitLinear,predictions)
predQuadratic <- predict(fitQuadratic,predictions)
data.frame(observations = predictions$observations,
obs_squared = predictions$obs_squared,
predLinear,
predQuadratic)
…以及结果:
observations obs_squared predLinear predQuadratic
1 3000 9.0e+06 342.6230 255.5514
2 4000 1.6e+07 482.8809 462.8431
3 5000 2.5e+07 623.1388 731.3757
4 6000 3.6e+07 763.3967 1061.1490
5 7000 4.9e+07 903.6546 1452.1632
6 8000 6.4e+07 1043.9125 1904.4181
7 9000 8.1e+07 1184.1704 2417.9139
结论
首先,随着我们添加数据,9000次观测的处理时间的线性预测从491秒增加到1184秒。正如预期的那样,向模型中添加数据有助于提高其准确性。
其次,二次模型的时间预测是线性模型的2倍多,2417.9秒的预测在实际运行时间的13.74秒内,误差小于0.6%。
附录
问题:处理所有观察结果到底需要多长时间?
当我运行9000个观测数据帧进行测试时,需要40分钟才能完成。这比最初的线性预测长了近5倍,最多可进行2000次观测,比最多可进行4000次观测的线性预测略长2倍。
> # validate model
> system.time(r <- corr.test(data[,2:61],method = "kendall"))
user system elapsed
2398.572 2.990 2404.175
> 2404.175 / 60
[1] 40.06958
>
结论:
而线性版本的模型比
IHME COVID-19 predicted fatalities model
最初预测美国有100万至200万人死亡,但它仍然太不准确,无法作为预测一个人的机器在60个变量中完成9000次观测分析所需时间的预测工具
corr.test()
.
然而,二次模型非常准确,这说明了在使用任何一个模型进行预测之前,开发多个假设的重要性。
问:核心的数量不是无关紧要吗?
对我的回答的一些评论断言,由于R
corr.test()
函数使用单个线程来处理数据,CPU上的内核数量与运行时性能无关。
我对这个答案的测试以及我对支持多线程的R函数所做的性能分析(例如。,
Improving Performance of caret::train() with Random Forest
),表明在实践中,速度相似但内核较少的CPU比内核较多的CPU慢。
在这种特定情况下,我们分析了
corr.test()
,我在一台
HP Spectre x360
与英特尔
Core i7-6500U
同样以2.5GHz运行的CPU,但它只有两个内核。它的处理时间比英特尔更快地缩短
Core i7-4870HQ
CPU(同样为2.5GHz),如下表所示。
从表中可以看出,在100次观测时,i7-U6500比Core i7-4870HQ慢22.5%,并且随着包括定时模拟在内的观测次数增加到4000次,这一差距也在增加。