R — Выбор наилучших комбинаций строк с использованием вложенного списка (перебор)

#r #list #loops #combinations #lapply

#r #Список #циклы #комбинации #lapply

Вопрос:

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

Мой фрейм данных:

     myFunction <- function (x) {
                  (x[2] - 5.1/(4 * pi^2) * (x[1] ^2)   5/pi * x[1] - 6)^2  
                  10 * (1 - 1/(8 * pi)) * cos(x[1] )   10
    }
    set.seed(1)
    x1 <- runif(5)*15-5
    x2 <- runif(5)*15
    y <- as.matrix(apply(cbind(x1,x2),1,myFunction))
    df <- data.frame(x1,x2,y)
 

Я генерирую все комбинации строк:

     Mycomb <- function(elements, simplify = FALSE){
    result <- lapply(seq_along(elements), function(m)
    combn(elements, m, simplify = simplify))
  
    result
    }

    combinations <- Mycomb(1:5)

    sub_df_list <- lapply(combinations, function(inx_list)
    lapply(inx_list, function(i) df[c(1, i),])
    )

    >sub_df_list

#[[1]]
#[[1]][[1]]
#          x1       x2        y
#1 -1.0173701 13.47585 47.79895
#2  0.5818585 14.17013 99.96885

#[[1]][[2]]
#        x1        x2        y
#1 -1.01737 13.475845 47.79895
#3  3.59280  9.911967 64.76098

#[[1]][[3]]
#         x1        x2        y
#1 -1.017370 13.475845 47.79895
#4  8.623117  9.436711 60.39821

#[[1]][[4]]
#         x1         x2        y
#1 -1.017370 13.4758453 47.79895
#5 -1.974771  0.9267941 82.26291


#[[2]]
#[[2]][[1]]
#          x1        x2        y
#1 -1.0173701 13.475845 47.79895
#2  0.5818585 14.170129 99.96885
#3  3.5928005  9.911967 64.76098

#...
 

Но я не знаю, как применить подгонку и прогнозирование lm к каждому сгенерированному набору, чтобы выбрать, какой набор выдает минимальную ошибку:

     fit <- lm(y~x1 x2, sub_df_list)
    mytest <- data.frame(x1=1,x2=2) # test data is fixed
    pred <- predict(fit,mytest)
    real <- myFunction(c(1,2))
    sqrt((pred - real)^2) # calculates error
 

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

Комментарии:

1. sub_df_list Важна ли структура?

2. @LMc структура sub_df_list не важна.

Ответ №1:

Возможно, вы можете попробовать приведенный ниже код, где sub_df_list получается по lapply unlist(combinations, recursive = FALSE)

 sub_df_list <- lapply(unlist(combinations, recursive = FALSE), function(k) df[k, ])
 

а затем вычислите ошибки в отношении real

 errors <- sapply(
  sub_df_list,
  function(v) abs(predict(lm(y ~ ., v), data.frame(x1 = 1, x2 = 2)) - myFunction(c(1, 2)))
)
 

такой, что

         1         1         1         1         1         1         1         1 
 26.17132  78.34121  43.13334  38.77058  60.63527  91.98179  33.59375  28.80784
        1         1         1         1         1         1         1         1
 46.44878  73.45175  76.28356  81.23705  45.38206  51.28394  54.49797 204.15358
        1         1         1         1         1         1         1         1
361.40750 158.85971 100.03526  61.93911  58.12593  21.52984  40.75905  51.79650
        1         1         1         1         1         1         1
 56.25079  69.51678  56.16817  54.03099  59.05836  49.33699  53.05278
 

Комментарии:

1. Спасибо! Как я могу заменить lm(y ~ ., v) на glmnet(x,y) ?

Ответ №2:

Сначала я бы сгладил вас sub_df_list , чтобы это был простой список data.frames. На данный момент это список списков (data.frames).

 datasets = unlist(sub_df_list, recursive=F)
 

После этого мы хотим запустить lm параметр data, аргумент которого меняется каждый раз, чтобы соответствовать элементам sub_df_list . Это можно сделать с помощью lapply анонимной функции, аналогично тому, как вы делали для генерации комбинаций.

 models = lapply(datasets, function(dataset) { lm(y~x1 x2, data=dataset) })
 

с этого момента остальная часть вашего кода должна работать. Вам просто нужно поместить его в функцию и использовать lapply, чтобы использовать его для каждого элемента вашего списка моделей.