Создание ветвей с разными подмножествами данных с помощью mlr3 PipeOps

#r #mlr3

#r #mlr3

Вопрос:

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

То, что я хочу сделать, похоже на пример из R для Data Science — глава 25: Многие модели. Допустим, мы используем один и тот же набор данных, gapminder , набор данных, содержащий разные переменные для стран по всему миру, такие как ВВП и ожидаемая продолжительность жизни. Если бы я хотел обучить модели ожидаемой продолжительности жизни для каждой страны, есть ли простой способ создать такой конвейер с использованием mlr3 ?

В идеале я хочу использовать mlr3pipelines для создания ветви на графике для каждого подмножества (например, отдельной ветви для каждой страны) с моделью в конце. Таким образом, конечный график будет начинаться с одного узла, а n в конечных узлах будут обученные учащиеся, по одному для каждой группы (т.Е. Страны) в наборе данных, или конечный узел, который объединяет результаты. Я также ожидаю, что он будет работать с новыми данными, например, если мы получим новые данные в будущем на 2020 год, я бы хотел, чтобы он мог создавать прогнозы для каждой страны, используя модель, подготовленную для этой конкретной страны.

Все mlr3 примеры, которые я нашел, похоже, имеют дело с моделями для всего набора данных или имеют модели, обученные со всеми группами в обучающем наборе.

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

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

1. Чтобы выразить это в терминах ml. У вас есть большой набор данных с одним столбцом факторов (страна в вашем примере). Для каждого фактора указанного столбца вы хотите обучить отдельную модель? Имейте в виду, что этот ансамбль потерпит неудачу из-за новых факторов, и модели не будут «учиться» на данных других округов.

2. @jakob-r Да, это правильно. В идеале, я думаю, у меня был бы отдельный конвейер для факторов, которых не было в обучающих данных. Или, если бы я действительно хотел получить прогноз, возможно, я мог бы применить некоторую кластеризацию для оценки группы (групп) наилучшего соответствия, чтобы временно приписать фактор для целей прогноза, пока не будет достаточно данных для обучения моделей для нового фактора.

Ответ №1:

Было бы полезно, если бы у вас были функции из этих двух пакетов: dplyr и tidyr . Следующий код показывает, как обучить несколько моделей по странам:

 library(dplyr)
library(tidyr)

df <- gapminder::gapminder

by_country <- 
  df %>% 
  nest(data = -c(continent, country)) %>% 
  mutate(model = lapply(data, learn))
  

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

 # A tibble: 142 x 4
   country     continent data              model     
   <fct>       <fct>     <list>            <list>    
 1 Afghanistan Asia      <tibble [12 x 4]> <LrnrRgrR>
 2 Albania     Europe    <tibble [12 x 4]> <LrnrRgrR>
 3 Algeria     Africa    <tibble [12 x 4]> <LrnrRgrR>
 4 Angola      Africa    <tibble [12 x 4]> <LrnrRgrR>
 5 Argentina   Americas  <tibble [12 x 4]> <LrnrRgrR>
 6 Australia   Oceania   <tibble [12 x 4]> <LrnrRgrR>
 7 Austria     Europe    <tibble [12 x 4]> <LrnrRgrR>
 8 Bahrain     Asia      <tibble [12 x 4]> <LrnrRgrR>
 9 Bangladesh  Asia      <tibble [12 x 4]> <LrnrRgrR>
10 Belgium     Europe    <tibble [12 x 4]> <LrnrRgrR>
  

Чтобы определить learn функцию, я следую инструкциям, приведенным на вебсайте mlr3. Функция

 learn <- function(df) {
  # I create a regression task as the target `lifeExp` is a numeric variable.
  task <- mlr3::TaskRegr$new(id = "gapminder", backend = df, target = "lifeExp")
  # define the learner you want to use.
  learner <- mlr3::lrn("regr.rpart")
  # train your dataset and return the trained model as an output
  learner$train(task)
}
  

Я надеюсь, что это решит вашу проблему.

Новое

Рассмотрите следующие шаги для обучения вашей модели и прогнозирования результата для каждой страны.

 create_task <- function(id, df, ratio) {
  train <- sample(nrow(df), ratio * nrow(df))
  task <- mlr3::TaskRegr$new(id = as.character(id), backend = df, target = "lifeExp")
  list(task = task, train = train, test = seq_len(nrow(df))[-train])
}

model_task <- function(learner, task_list) {
  learner$train(task_list[["task"]], row_ids = task_list[["train"]])
}

predict_result <- function(learner, task_list) {
  learner$predict(task_list[["task"]], row_ids = task_list[["test"]])
}

by_country <- 
  df %>% 
  nest(data = -c(continent, country)) %>% 
  mutate(
    task_list = Map(create_task, country, data, 0.8), 
    learner = list(mlr3::lrn("regr.rpart"))
  ) %>% 
  within({
    Map(model_task, learner, task_list)
    prediction <- Map(predict_result, learner, task_list)
  })
  

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

1. Спасибо, это похоже на то, что я сейчас делаю, за исключением data.table . Как можно было бы создавать прогнозы с помощью обученных моделей в этом примере?

2. Вам нужны дополнительные настройки. Смотрите мой новый пост выше. @ialm

3. Спасибо, я предполагаю, что текущие конвейеры не обеспечивают желаемый рабочий процесс. В итоге я сделал что-то подобное, за исключением data.table того, что вместо s tibbles , поскольку мои данные уже обрабатывались с использованием data.table .