缘由
艺多不压身
碎碎念
我们继续飞行在云层和雾气之间,飞行在一个无光无影的空洞世界中。 ——《风沙星辰》
Ref
7 A Model Workflow | Tidy Modeling with R
解读
本文用 Ames 房价数据集 演示一个最基础的线性回归工作流,并展示如何批量比较多个公式。
1️ 数据准备
我们先加载必要的包,并划分训练集与测试集。
library(tidymodels)
library(modeldata)
tidymodels_prefer()
# 数据集
data(ames)
ames <- mutate(ames, Sale_Price = log10(Sale_Price))
# 划分训练集/测试集
set.seed(502)
ames_split <- initial_split(ames, prop = 0.80, strata = Sale_Price)
ames_train <- training(ames_split)
ames_test <- testing(ames_split)2️ parsnip 的最简用法
tidymodels 的核心建模语法来自 parsnip。只需三步:
- 定义模型
- 指定引擎
- 使用
fit()拟合
# 仅使用 parsnip
lm_model <- linear_reg() %>%
set_engine("lm")
lm_fit2 <- fit(lm_model, Sale_Price ~ Longitude + Latitude, data = ames_train)特点:语法简洁,但只能快速拟合,缺少统一的“项目管理”机制。
3️workflow 的引入
workflow 把 公式 + 模型 封装在一起,方便扩展。
# 使用 workflow()
lm_wflow <- workflow() %>%
add_model(lm_model) %>%
add_formula(Sale_Price ~ Longitude + Latitude)
lm_fit <- fit(lm_wflow, ames_train)
predict(lm_fit, ames_test %>% head(3))还可以用 update_formula() 更新公式:
lm_fit %>% update_formula(Sale_Price ~ Longitude)4️ add_formula vs add_variables
workflow 提供两种不同的接口:
用公式
lm_wflow <- workflow() %>%
add_model(lm_model) %>%
add_formula(Sale_Price ~ Longitude + Latitude)用变量
lm_wflow <- lm_wflow %>%
remove_formula() %>%
add_variables(outcome = Sale_Price, predictors = c(Longitude, Latitude))
fit(lm_wflow, ames_train)add_formula():写法接近lm(),简单直观。add_variables():更适合配合 recipes 做特征工程。
5️ 批量比较:workflowsets
如果想对比多个特征组合,可以用 workflowsets:
library(workflowsets)
# 定义不同的公式
location <- list(
longitude = Sale_Price ~ Longitude,
latitude = Sale_Price ~ Latitude,
coords = Sale_Price ~ Longitude + Latitude,
neighborhood = Sale_Price ~ Neighborhood
)
# 生成 workflow set
location_models <- workflow_set(
preproc = location,
models = list(lm = lm_model)
)
# 批量拟合
location_models <- location_models %>%
mutate(fit = map(info, ~ fit(.x$workflow[[1]], ames_train)))
location_models$fit[[1]]6️ 使用特殊公式:多水平模型
有些模型支持更复杂的公式,比如随机截距和斜率。
lme4::lmer() 常见写法:
library(nlme)
library(lme4)
lmer(distance ~ Sex + (age | Subject), data = Orthodont)在 tidymodels 中,需要借助 multilevelmod:
library(multilevelmod)
multilevel_spec <- linear_reg() %>% set_engine("lmer")
multilevel_workflow <- workflow() %>%
add_variables(outcome = distance, predictors = c(Sex, age, Subject)) %>%
add_model(multilevel_spec,
formula = distance ~ Sex + (age | Subject))说明:
- 这里的
formula会直接传递给lmer引擎。 - 普通
lm模型不支持这种(age | Subject)写法。
7️ 模型评估:训练集 vs 测试集
在 tidymodels 中:
fit()默认只在训练集拟合。last_fit()会自动在训练集拟合,并在测试集上评估。
final_lm_res <- last_fit(lm_wflow, ames_split)查看结果
- 评估指标(测试集表现)
collect_metrics(final_lm_res)- 预测结果(测试集对比)
collect_predictions(final_lm_res) %>% slice(1:5)- 提取训练好的 workflow
fitted_lm_wflow <- extract_workflow(final_lm_res)
tidy(fitted_lm_wflow)