在 purr 和模型中进行 k 折交叉验证
k fold cross validation in purr and model
我遇到了这个例子
library(mtcars)
set.seed(17)
cv.error.10 = rep(0,10)
for (i in 1:10){
glm.fit = glm(mpg∼poly(horsepower ,i),data=Auto)
cv.error.10[i] = cv.glm(Auto,glm.fit,K=10)$delta[1]
}
cv.error.10
[1] 24.21 19.19 19.31 19.34 18.88 19.02 18.90 19.71 18.95 19.50
我一直在尝试拿起 purrr
和 modelr
。这似乎是一个很好的尝试复制的例子,因为它包括循环和交叉验证。我如何将这段代码转换成更整洁的诗句?
更新
根据以下建议,这是代码所在的位置
data(mtcars)
cv_mtcars = mtcars %>%
crossv_kfold(k = 5)
cv_models = cv_mtcars %>%
mutate(model = map(train, ~lm(mpg ~ hp, data = .)),
rmse_all_models = map2_dbl(model, test, ~rmse(.x, .y)))
print(cv_models)
我想做的是对 hp
的递增多项式重复此操作,例如 hp^2
、hp^3
等。我猜有一个 purr
方法这样做。
更新 2
这里是未迭代代码的例子
data(mtcars)
cv_mtcars = mtcars %>%
crossv_kfold(k = 5)
cv_models = cv_mtcars %>%
mutate(model1 = map(train, ~lm(mpg ~ hp, data = .)),
model2 = map(train, ~lm(mpg ~I(hp^2), data = .)),
model3 = map(train, ~lm(mpg ~I(hp^3), data = .)),
model4 = map(train, ~lm(mpg ~I(hp^4), data = .)),
model5 = map(train, ~lm(mpg ~I(hp^5), data = .)),
model6 = map(train, ~lm(mpg ~I(hp^6), data = .)),
rmse_all_models1 = map2_dbl(model1, test, ~rmse(.x, .y)),
rmse_all_models2 = map2_dbl(model2, test, ~rmse(.x, .y)),
rmse_all_models3 = map2_dbl(model3, test, ~rmse(.x, .y)),
rmse_all_models4 = map2_dbl(model4, test, ~rmse(.x, .y)),
rmse_all_models5 = map2_dbl(model5, test, ~rmse(.x, .y)),
rmse_all_models6 = map2_dbl(model6, test, ~rmse(.x, .y)))
print(cv_models)
我不知道 mtcars 库,但如果您需要访问 mtcars 数据,可以使用以下内容:
data(mtcars)
library(tidyverse)
library(modelr)
然后您可以使用 cross_mc()
创建一个重采样列表
cv_mtcars = mtcars %>%
crossv_mc(n = 50)
print(cv_mtcars)
现在您可以在重采样上训练您的模型。 train 是包含用于训练的数据帧的列。我将 mutate() 用于一个名为 model 的列,我将 lm() 函数(或任何其他模型)映射到数据。
cv_models = cv_mtcars %>%
mutate(model = map(train, ~lm(mpg ~ horsepower, data = .)))
print(cv_models)
您可以使用 modelr 的 rmse() 函数添加均方根误差:
rmse_cv = cv_models %>%
mutate(rmse_all_models = map2_dbl(model, test, ~rmse(.x, .y))) %>%
pull(rmse_all_models)
print(rmse_cv)
然后您可以计算您需要的 rmse() 的任何统计数据。如果您不熟悉列表列的概念,这段代码可能有点让人不知所措。您可以在此处阅读有关列表列的更多信息:https://campus.datacamp.com/courses/exploratory-data-analysis-in-r-case-study/tidy-modeling-with-broom?ex=10&_escaped_fragment_=#skiponboarding
我在 public 计算机上,所以我无法尝试代码,但它 应该 工作。
更新
所以我有点误解了这个问题,这里还有一些提示:
powers = seq(1:6)
create_form = function(power){
rhs = substitute(I(hp^pow), list(pow=power))
rlang::new_formula(quote(mpg), rhs)
}
此函数创建公式,然后您可以将一系列幂映射到此函数:
list_forms = map(seq(1,6), create_form)
然后将结果列表映射到lm
:
map(list_forms, lm, data=mtcars)
要将其集成到管道工作流中,您需要创建一个新函数:
train_model = function(cv_data, form){
cv_data %>%
mutate(model = map(train, ~lm(form, data = .)))
}
在一个模型上进行测试:
test = train_model(cv_mtcars, list_forms[[1]])
现在 运行 它适用于一切:
all_models = map(list_forms, train_model, cv_data=cv_mtcars)
希望这对您有所帮助。
我遇到了这个例子
library(mtcars)
set.seed(17)
cv.error.10 = rep(0,10)
for (i in 1:10){
glm.fit = glm(mpg∼poly(horsepower ,i),data=Auto)
cv.error.10[i] = cv.glm(Auto,glm.fit,K=10)$delta[1]
}
cv.error.10
[1] 24.21 19.19 19.31 19.34 18.88 19.02 18.90 19.71 18.95 19.50
我一直在尝试拿起 purrr
和 modelr
。这似乎是一个很好的尝试复制的例子,因为它包括循环和交叉验证。我如何将这段代码转换成更整洁的诗句?
更新
根据以下建议,这是代码所在的位置
data(mtcars)
cv_mtcars = mtcars %>%
crossv_kfold(k = 5)
cv_models = cv_mtcars %>%
mutate(model = map(train, ~lm(mpg ~ hp, data = .)),
rmse_all_models = map2_dbl(model, test, ~rmse(.x, .y)))
print(cv_models)
我想做的是对 hp
的递增多项式重复此操作,例如 hp^2
、hp^3
等。我猜有一个 purr
方法这样做。
更新 2
这里是未迭代代码的例子
data(mtcars)
cv_mtcars = mtcars %>%
crossv_kfold(k = 5)
cv_models = cv_mtcars %>%
mutate(model1 = map(train, ~lm(mpg ~ hp, data = .)),
model2 = map(train, ~lm(mpg ~I(hp^2), data = .)),
model3 = map(train, ~lm(mpg ~I(hp^3), data = .)),
model4 = map(train, ~lm(mpg ~I(hp^4), data = .)),
model5 = map(train, ~lm(mpg ~I(hp^5), data = .)),
model6 = map(train, ~lm(mpg ~I(hp^6), data = .)),
rmse_all_models1 = map2_dbl(model1, test, ~rmse(.x, .y)),
rmse_all_models2 = map2_dbl(model2, test, ~rmse(.x, .y)),
rmse_all_models3 = map2_dbl(model3, test, ~rmse(.x, .y)),
rmse_all_models4 = map2_dbl(model4, test, ~rmse(.x, .y)),
rmse_all_models5 = map2_dbl(model5, test, ~rmse(.x, .y)),
rmse_all_models6 = map2_dbl(model6, test, ~rmse(.x, .y)))
print(cv_models)
我不知道 mtcars 库,但如果您需要访问 mtcars 数据,可以使用以下内容:
data(mtcars)
library(tidyverse)
library(modelr)
然后您可以使用 cross_mc()
创建一个重采样列表cv_mtcars = mtcars %>%
crossv_mc(n = 50)
print(cv_mtcars)
现在您可以在重采样上训练您的模型。 train 是包含用于训练的数据帧的列。我将 mutate() 用于一个名为 model 的列,我将 lm() 函数(或任何其他模型)映射到数据。
cv_models = cv_mtcars %>%
mutate(model = map(train, ~lm(mpg ~ horsepower, data = .)))
print(cv_models)
您可以使用 modelr 的 rmse() 函数添加均方根误差:
rmse_cv = cv_models %>%
mutate(rmse_all_models = map2_dbl(model, test, ~rmse(.x, .y))) %>%
pull(rmse_all_models)
print(rmse_cv)
然后您可以计算您需要的 rmse() 的任何统计数据。如果您不熟悉列表列的概念,这段代码可能有点让人不知所措。您可以在此处阅读有关列表列的更多信息:https://campus.datacamp.com/courses/exploratory-data-analysis-in-r-case-study/tidy-modeling-with-broom?ex=10&_escaped_fragment_=#skiponboarding
我在 public 计算机上,所以我无法尝试代码,但它 应该 工作。
更新
所以我有点误解了这个问题,这里还有一些提示:
powers = seq(1:6)
create_form = function(power){
rhs = substitute(I(hp^pow), list(pow=power))
rlang::new_formula(quote(mpg), rhs)
}
此函数创建公式,然后您可以将一系列幂映射到此函数:
list_forms = map(seq(1,6), create_form)
然后将结果列表映射到lm
:
map(list_forms, lm, data=mtcars)
要将其集成到管道工作流中,您需要创建一个新函数:
train_model = function(cv_data, form){
cv_data %>%
mutate(model = map(train, ~lm(form, data = .)))
}
在一个模型上进行测试:
test = train_model(cv_mtcars, list_forms[[1]])
现在 运行 它适用于一切:
all_models = map(list_forms, train_model, cv_data=cv_mtcars)
希望这对您有所帮助。