2016-07-27 8 views
0

Я только что наткнулся на пакет purrr, и я думаю, что это поможет мне немного с точки зрения того, что я хочу сделать - Я просто не могу собрать это вместе.совет по использованию dplyr :: do vs purrr: map, tidy :: nest, для прогнозов

Я думаю, что это будет по почте, но перейдет в общий прецедент. Я думаю, что многие другие сталкиваются с такой надеждой, что это тоже полезно для них.

Это то, что я стремлюсь к:

  1. С одной большой набор данных нескольких моделей выполняющиеся на каждом из различных подгрупп.
  2. Имеют ли эти модели доступными, поэтому я могу изучить - для коэффициентов, точности и т. Д.
  3. Из этого списка сохраненных моделей для каждой из разных групп можно применить соответствующую модель к соответствующей группе тестовых наборов.
grouping_vals = c("cyl", "vs") 

library(purrr) 
library(dplyr) 
set.seed(1) 
train=mtcars 
noise = sample(1:5,32, replace=TRUE) 
test = mtcars %>% mutate(hp = hp * noise) # just so dataset isn't identical 


models = train %>% 
group_by_(grouping_vals) %>% 
do(linear_model1 = lm(mpg ~hp, data=.), 
    linear_model2 = lm(mpg ~., data=.) 
) 
  1. Я получил это далеко, но я не знаю, как «карта» соответствующие модели к набору данных «тест» для соответствующих сгруппированных значений.
  2. Теперь я также могу попытаться получить остатки от обучения linear_model1 или linear_model2 с данными обучения для соответствующих групп.

модели $ linear_model1 [[2]] $ остатки покажут остатки для 2-й группы модели1. Я просто не знаю, как переместить все модели $ linear_model1 $ остатков в набор данных поезда.

Мое понимание заключается в том, что функция tidyr nest() выполняет ту же самую функцию, что и при создании моего do() создания моделей.

models_with_nest = train %>% 
    group_by_(grouping_vals) %>% 
        nest() %>% 
    mutate(linear_model2 = purrr::map(data, ~lm(mpg~., data=.)), 
      linear_model1 = purrr::map(data, ~lm(mpg~ hp+disp, data=.)) 
    ) 

Опять же просто искать способ легко быть в состоянии «карта» эти остатки/подготовки прогнозов в тренировочном наборе данных и применить затем применить соответствующую модель невидимому тестового набора данных, как один я создал выше.

Надеюсь, это не сбивает с толку, так как я вижу много обещаний здесь, я просто не могу понять, как это сделать.

Я полагаю, что это задача, которую тонна людей хотела бы сделать в этом более автоматизированном виде, но вместо этого это то, что люди делают очень медленно и шаг за шагом.

+0

Пакет Брума в 'augment' полезно для добавления остатки в наборе данных, используемые для соответствия модели. Для создания прогнозов с помощью тестового набора данных вы можете использовать 'прогноз' в' map', используя аргумент 'newdata'. Если вы еще этого не видели, вас может также заинтересовать этот [разговор Хэдли Уикхэма] (https://www.youtube.com/watch?v=rz3_FDVt9eg), который проходит пример установки многих моделей с dplyr/tidyr/purrr/метла. – aosmith

+0

Да, я думал о Венике, но большинство моделей, которые я запускаю, похоже, не соответствуют этому - это был простой пример, но я думал, что он будет запущен с использованием Neural Networks, SVM, Random Forest и т. Д. – runningbirds

+2

Вы читали http : //r4ds.had.co.nz/many-models.html? – hadley

ответ

1

Мне очень интересно узнать различия между do и подходами nest, map. Возможно, люди попробовали оба, и они могут комментировать, что быстрее, когда речь идет о гораздо больших наборах данных или о многом другом.

До сих пор я использовал do подход следующим образом:

library(tidyverse) 

# reproducible results 
set.seed(47) 

# shuffle/randomise rows 
mtcars2 = mtcars %>% sample_frac(1) 

# split train/test 
mtcars_train = mtcars2[1:20,] 
mtcars_test = mtcars2[21:32,] 

# for each cyl group create subsets and fit the models of interest using do 
dt_models = mtcars_train %>% 
    group_by(cyl) %>% 
    do(model1 = lm(disp ~ hp, data = .), 
    model2 = lm(disp ~ mpg, data = .)) %>% 
    ungroup %>% 
    print() 

# reshape model dataset (for easier use later) 
dt_models = dt_models %>% gather("name","model", -cyl) %>% print() 

# function to pick model and predict corresponding data (row) 
GetModelAndPredict = function(input_cyl, model_name, dd){ 

    m = (dt_models %>% filter(cyl==input_cyl & name==model_name))$model[[1]] 

    predict.lm(m, newdata=dd) 

} 

# predict each row using the corresponding model 
mtcars_test %>% 
    rowwise() %>% 
    do(data.frame(., 
       pred1 = GetModelAndPredict(.$cyl, "model1", .), 
       pred2 = GetModelAndPredict(.$cyl, "model2", .))) %>% 
    ungroup 


# # A tibble: 12 × 13 
#  mpg cyl disp hp drat wt qsec vs am gear carb  pred1  pred2 
# * <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>  <dbl> 
# 1 22.8  4 108.0 93 3.85 2.320 18.61  1  1  4  1 103.11501 115.24903 
# 2 17.3  8 275.8 180 3.07 3.730 17.60  0  0  3  3 356.19839 316.20091 
# 3 18.1  6 225.0 105 2.76 3.460 20.22  1  0  3  1 200.10912 151.56750 
# 4 21.0  6 160.0 110 3.90 2.875 17.02  0  1  4  4 195.69767 198.89904 
# 5 32.4  4 78.7 66 4.08 2.200 19.47  1  1  4  1 87.99347 77.54320 
# 6 26.0  4 120.3 91 4.43 2.140 16.70  0  1  5  2 101.99490 102.68042 
# 7 15.8  8 351.0 264 4.22 3.170 14.50  0  1  5  4 365.97745 339.57501 
# 8 24.4  4 146.7 62 3.69 3.190 20.00  1  0  4  2 85.75324 108.96473 
# 9 27.3  4 79.0 66 4.08 1.935 18.90  1  1  4  1 87.99347 97.57442 
# 10 33.9  4 71.1 65 4.22 1.835 19.90  1  1  4  1 87.43341 71.65166 
# 11 22.8  4 140.8 95 3.92 3.150 22.90  1  0  4  2 104.23513 115.24903 
# 12 18.7  8 360.0 175 3.15 3.440 17.02  0  0  3  2 355.61630 294.38507 

Но я нашел действительно интересна nest, map подход, а также:

library(tidyverse) 

# reproducible results 
set.seed(47) 

# shuffle/randomise rows 
mtcars2 = mtcars %>% sample_frac(1) 

# split train/test 
mtcars_train = mtcars2[1:20,] 
mtcars_test = mtcars2[21:32,] 

# for each cyl group create subsets and fit the models of interest using map 
dt_models = mtcars_train %>% 
    nest(-cyl) %>% 
    mutate(model1 = map(data, ~lm(disp ~ hp, data = .)), 
     model2 = map(data, ~lm(disp ~ mpg, data = .))) %>% 
    rename(data_train = data) %>% 
    print() 

# join test data to be able to predict them 
dt_models_and_test_data = mtcars_test %>% 
    nest(-cyl) %>% 
    inner_join(dt_models, by = "cyl") %>% 
    rename(data_test = data) %>% 
    print() 

# predict test data using map2 
dt_preds = dt_models_and_test_data %>% 
    mutate(pred1 = map2(model1, data_test, predict.lm), 
     pred2 = map2(model2, data_test, predict.lm)) %>% 
    print() 

# go back to a reasonable data frame using unnest on columns of interest 
dt_preds_upd = dt_preds %>% 
    unnest(data_test,pred1,pred2) %>% 
    print() 


# # A tibble: 12 × 13 
#  cyl  pred1  pred2 mpg disp hp drat wt qsec vs am gear carb 
# <dbl>  <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
# 1  4 103.11501 115.24903 22.8 108.0 93 3.85 2.320 18.61  1  1  4  1 
# 2  4 87.99347 77.54320 32.4 78.7 66 4.08 2.200 19.47  1  1  4  1 
# 3  4 101.99490 102.68042 26.0 120.3 91 4.43 2.140 16.70  0  1  5  2 
# 4  4 85.75324 108.96473 24.4 146.7 62 3.69 3.190 20.00  1  0  4  2 
# 5  4 87.99347 97.57442 27.3 79.0 66 4.08 1.935 18.90  1  1  4  1 
# 6  4 87.43341 71.65166 33.9 71.1 65 4.22 1.835 19.90  1  1  4  1 
# 7  4 104.23513 115.24903 22.8 140.8 95 3.92 3.150 22.90  1  0  4  2 
# 8  8 356.19839 316.20091 17.3 275.8 180 3.07 3.730 17.60  0  0  3  3 
# 9  8 365.97745 339.57501 15.8 351.0 264 4.22 3.170 14.50  0  1  5  4 
# 10  8 355.61630 294.38507 18.7 360.0 175 3.15 3.440 17.02  0  0  3  2 
# 11  6 200.10912 151.56750 18.1 225.0 105 2.76 3.460 20.22  1  0  3  1 
# 12  6 195.69767 198.89904 21.0 160.0 110 3.90 2.875 17.02  0  1  4  4 
+1

см. Некоторые комментарии здесь http://stackoverflow.com/questions/35505187/comparison-between-dplyrdo-purrrmap-what-advantages – aurelien

 Смежные вопросы

  • Нет связанных вопросов^_^