Более быстрый способ запустить регрессию на больших данных - PullRequest
3 голосов
/ 29 апреля 2020

У меня большой набор данных, который содержит 70 000 строк и несколько столбцов с переменными данными. Также у меня есть столбец, содержащий более 5000 факторов, которые мне нужно использовать.

Есть ли способ ускорить регрессию, поскольку в настоящий момент для ее запуска требуется более 40 минут. Единственный способ ускорить его, я думаю, был бы, если бы я мог отфильтровать только факторы из тестовых данных в тренировочные данные или использовать data.table и запустить reg из этого.

Любая помощь будет принята с благодарностью.

library(dbplyr)
library(dplyr)
library(data.table)
library(readr)


greys <- read_excel("Punting'/Dogs/greys.xlsx", sheet = 'Vic')
greys$name<- as.factor(greys$name)
ggtrain<- tail(greys,63000)
gtrain<- head(ggtrain, -190)
gtest1<- tail(ggtrain,190)
gtest<- filter(gtest1, runnum >5)

#mygrey<- gam(gtrain$time~ s(name, bs='fs')+s(box)+s(distance),data = gtrain,method = 'ML')
mygrey<- lm(gtrain$margin~name+box+distance+trate+grade+trackid, data = gtrain)
pgrey<- predict(mygrey,gtest)
gdf<- data.frame(gtest$name,pgrey)
#gdf
write.csv(gdf,'thedogs.csv')```

Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   63000 obs. of  25 variables:
 $ position: num  4 5 6 7 1 2 3 4 5 6 ...
 $ box     : num  3 10 5 8 3 7 9 5 2 4 ...
 $ name    : Factor w/ 5903 levels "AARON'S ME BOY",..: 4107 2197 3294 3402 4766 4463 5477 274 5506 2249 ...
 $ trainer : chr  "Marcus Lloyd" "Ian Robinson" "Adam Richardson" "Nathan  Hunt" ...
 $ time    : num  22.9 23 23.1 23.5 22.5 ...
 $ margin  : num  7.25 8.31 9.96 15.33 0 ...
 $ split   : num  9.17 8.98 9.12 9.14 8.62 8.73 8.8 8.99 9.04 9.02 ...
 $ inrun   : num  75 44 56 67 11 22 33 54 76 67 ...
 $ weight  : num  27.9 26.2 30.3 27.7 26.5 31.5 34.1 32.8 31.2 34 ...
 $ sire    : chr  "Didda Joe" "Swift Fancy" "Barcia Bale" "Hostile" ...
 $ dam     : chr  "Hurricane Queen" "Ulla Allen" "Diva's Shadow" "Flashing Bessy" ...
 $ odds    : num  20.3 55.5 1.6 33.2 1.6 5 22.6 7.9 12.5 9.9 ...
 $ distance: num  390 390 390 390 390 390 390 390 390 390 ...
 $ grade   : num  4.5 4.5 4.5 4.5 4.5 4.5 4.5 4.5 4.5 4.5 ...
 $ race    : chr  "Race 11" "Race 11" "Race 11" "Race 11" ...
 $ location: chr  "Ballarat" "Ballarat" "Ballarat" "Ballarat" ...
 $ date    : chr  "Monday 5th of August 2019" "Monday 5th of August 2019" "Monday 5th of August 2019" "Monday 5th of August 2019" ...
 $ state   : chr  "vic" "vic" "vic" "vic" ...
 $ trate   : num  0.515 0.376 0.818 0.226 0.55 ...
 $ espeed  : num  75 44 56 67 11 22 33 54 76 67 ...
 $ trackid : num  3 3 3 3 3 3 3 3 3 3 ...
 $ runnum  : num  4 6 3 2 2 2 3 4 2 4 ...
 $ qms     : chr  "M/75" "M/44" "M/56" "M/67" ...


1 Ответ

1 голос
/ 29 апреля 2020

Ваша регрессия идет медленно из-за переменной name. Подбор коэффициента с 5903 уровнями добавит 5903 столбца к вашей матрице дизайна - это все равно что попытаться установить 5903 отдельных переменных.

Ваша матрица дизайна будет иметь размеры 63000x5908, то есть одна, займёт много памяти и две, заставит lm усердно работать, чтобы получить свои оценки (отсюда время установки 40 минут).

У вас есть несколько вариантов:

  1. Сохраните ваш дизайн как есть и подождите (или найдите немного быстрее lm)
  2. Выкиньте переменную name, в в этом случае lm будет соответствовать почти мгновенно
  3. Подберите модель со смешанными эффектами, с name в качестве случайного эффекта, используя lmer или другой пакет. В частности, lmer использует редкую расчетную матрицу для случайных эффектов, используя тот факт, что каждое наблюдение может иметь только одно из 5903 имен (поэтому большая часть матрицы пуста).

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

Простая модель для вашего набора данных может выглядеть примерно так:

library(lme4)
## read data
mygrey <- lmer(gtrain$margin~(1|name)+box+distance+trate+grade+trackid,
               data = gtrain)

Если вы хотите go На этом маршруте я рекомендую прочитать больше о моделях со смешанными эффектами, чтобы вы могли выбрать структуру модели, которая имеет смысл для ваших данных. Вот два полезных ресурса:

...