使用 mlr3 PipeOps 创建具有不同数据子集的分支
Create branches with different subsets of data with mlr3 PipeOps
我想使用 mlr3
在不同的数据子集上训练模型,我想知道是否有办法在管道中的不同数据子集上训练模型。
我想做的与R for Data Science - Chapter 25: Many models中的例子类似。假设我们使用同一个数据集,gapminder
,这个数据集包含了世界各国不同的变量,比如 GDP 和预期寿命。如果我想为每个国家/地区的预期寿命训练模型,是否有使用 mlr3
创建此类管道的简单方法?
理想情况下,我想使用 mlr3pipelines
在图形中为每个子集创建一个分支(例如,为每个国家/地区创建一个单独的分支),最后有一个模型。因此,最终图将从单个节点开始,并在末端节点有 n
个训练有素的学习者,数据集中每个组(即国家/地区)一个,或聚合结果的最终节点。我还希望它适用于新数据,例如,如果我们在未来获得 2020 年的新数据,我希望它能够使用针对特定国家/地区训练的模型为每个国家/地区创建预测。
我发现的所有 mlr3
示例似乎都处理整个数据集的模型,或者用训练集中的所有组训练模型。
目前,我只是手动为每组数据创建一个单独的任务,但如果将数据子集化步骤合并到建模管道中会很好。
如果您拥有以下两个包中的函数,将会有所帮助:dplyr
和 tidyr
。以下代码向您展示了如何按国家/地区训练多个模型:
library(dplyr)
library(tidyr)
df <- gapminder::gapminder
by_country <-
df %>%
nest(data = -c(continent, country)) %>%
mutate(model = lapply(data, learn))
请注意,learn
是一个将单个数据帧作为其输入的函数。稍后我将向您展示如何定义该函数。现在你需要知道这个管道返回的dataframe是这样的:
# 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)
})
我想使用 mlr3
在不同的数据子集上训练模型,我想知道是否有办法在管道中的不同数据子集上训练模型。
我想做的与R for Data Science - Chapter 25: Many models中的例子类似。假设我们使用同一个数据集,gapminder
,这个数据集包含了世界各国不同的变量,比如 GDP 和预期寿命。如果我想为每个国家/地区的预期寿命训练模型,是否有使用 mlr3
创建此类管道的简单方法?
理想情况下,我想使用 mlr3pipelines
在图形中为每个子集创建一个分支(例如,为每个国家/地区创建一个单独的分支),最后有一个模型。因此,最终图将从单个节点开始,并在末端节点有 n
个训练有素的学习者,数据集中每个组(即国家/地区)一个,或聚合结果的最终节点。我还希望它适用于新数据,例如,如果我们在未来获得 2020 年的新数据,我希望它能够使用针对特定国家/地区训练的模型为每个国家/地区创建预测。
我发现的所有 mlr3
示例似乎都处理整个数据集的模型,或者用训练集中的所有组训练模型。
目前,我只是手动为每组数据创建一个单独的任务,但如果将数据子集化步骤合并到建模管道中会很好。
如果您拥有以下两个包中的函数,将会有所帮助:dplyr
和 tidyr
。以下代码向您展示了如何按国家/地区训练多个模型:
library(dplyr)
library(tidyr)
df <- gapminder::gapminder
by_country <-
df %>%
nest(data = -c(continent, country)) %>%
mutate(model = lapply(data, learn))
请注意,learn
是一个将单个数据帧作为其输入的函数。稍后我将向您展示如何定义该函数。现在你需要知道这个管道返回的dataframe是这样的:
# 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)
})