Как оценить время работы R скрипта? - PullRequest
2 голосов
/ 26 апреля 2020

У меня есть data.frame, как показано ниже:

> str(df)
'data.frame':   8219 obs. of  60 variables:
 $ q01: int  3 3 3 1 4 3 1 5 2 5 ...
 $ q02: int  3 3 3 2 4 5 4 4 3 5 ...
 $ q03: int  4 2 1 2 4 4 2 3 2 2 ...
 $ q04: int  3 4 2 3 2 2 2 4 4 5 ...
 .
 .
 .
 $q60: int   3 3 5 2 1 2 4 2 1 2 ...

Каждый элемент int от 1-5.
Когда я запускаю corr.test(df,method = "kendall"), я не могу получить никакого вывода даже 2 часа прошлое.

Что касается управления временем, если я могу оценить время процесса, я могу выпить чашку кофе, если это 10 минут, я могу сначала написать другой проект, если это 2 часа.

Я хочу знать, есть ли какой-нибудь метод для оценки времени выполнения R-скрипта?

Плюс, у моего ноутбука двухъядерный процессор 2,4 ГГц, 8 ГБ памяти.

1 Ответ

3 голосов
/ 26 апреля 2020

Вот способ оценить время, основанное на количестве строк данных. Я имитирую фрейм данных из 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 минуты на моем ноутбуке.

* 1021.

Кроме того, обратите внимание, что время значительно варьируется в зависимости от скорости процессора, количества ядер и доступной оперативной памяти на машине. Эти тесты проводились на MacBook Pro 15 эпохи 2015 года со следующей конфигурацией.

enter image description here

Улучшение модели

Учитывая обратную и далее по комментариям между оригинальным постом и моим ответом, мы можем предположить, что существует нелинейный эффект, который становится заметным после 2000 наблюдений. Мы можем проверить это, добавив в модель квадратичный c термин и создав новые прогнозы.

Сначала мы соберем данные для 3000, 4000 и 5000 наблюдений, чтобы увеличить количество степеней свободы в модели, а также предоставить больше данных, из которых мы могли бы обнаружить квадратичные c эффект.

> 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 

>

Далее мы запустим линейные модели с квадратичным c эффектом и без него, сгенерируем прогнозы и сравним результаты. Сначала мы запустим модели и распечатаем сводку для модели quadrati c.

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 с моделью квадратичного c, линейные и квадратичные члены c значительно отличаются от 0 при альфа = 0,05. Интересно, что с квадратичным c слагаемым в модели линейный эффект отрицателен.

Наконец, мы сгенерируем прогнозы для обеих моделей, объединим их в фрейм данных и распечатаем результаты.

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 секунд. Как и ожидалось, добавление данных в модель помогло повысить ее точность.

Во-вторых, прогноз по времени для квадратичной c модели был более чем в 2 раза выше, чем для линейной модели, а прогноз в 2 417,9 секунды был в пределах 13,74 секунды от фактического времени выполнения, что составляет менее 0,6% ошибки.

Приложение

Вопрос: Сколько времени действительно потребовалось для обработки всех наблюдений?

Когда я пропустил фрейм данных наблюдения за 9000 в ходе теста, для его завершения потребовалось 40 минут , Это было почти в 5 раз дольше, чем первоначальное линейное предсказание с пробегами до 2000 наблюдений, и чуть более чем в 2 раза по сравнению с линейным предсказанием до 4000 наблюдений.

> # 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 , которая первоначально предсказывала 1 000 000 - 2 000 000 смертельных случаев в В США это все еще слишком неточно, чтобы быть полезным в качестве предиктора того, сколько времени потребуется машине, чтобы выполнить 9 000 анализов наблюдений по 60 переменным с corr.test().

Однако квадратичная c модель очень точна, что иллюстрирует важность разработки нескольких гипотез перед использованием какой-либо одной модели для прогнозирования.

Вопрос: не имеет значения количество ядер?

В нескольких комментариях к моему ответу утверждается, что, поскольку функция R corr.test() использует один поток для обработки данных, число ядра на процессоре не имеют отношения к производительности во время выполнения.

Мои тесты для этого ответа, а также анализы производительности, которые я провел с функциями R, поддерживающими многопоточность (например, Повышение производительности caret :: train () с помощью Random Forest ), показывают, что на практике процессоры с аналогичной скоростью, но меньшим количеством ядер работают медленнее, чем процессоры с большим количеством ядер.

В этой конкретной c ситуации, когда мы анализировали производительность core.test(), я провел вторую серию тестов на HP Spectre x-360 с процессором Intel i7-U6500, который также работает на частоте 2,5 ГГц , Время его обработки уменьшается быстрее, чем у процессора Intel i7-4870HQ (также с частотой 2,5 ГГц), как показано в следующей таблице.

enter image description here

Как видно из таблицы, i7-U6500 на 22,5% медленнее, чем i7-4870HQ при 100 наблюдениях, и этот дефицит растет так как количество наблюдений, в том числе в симуляциях времени, увеличивается до 4000.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...