不同变量组合下运行模型的最优方法及性能对比
变量组合拟合模型的方案对比与优化问题
我尝试用数据中不同变量组合拟合模型,目标是找到性能最优的实现方式。常见解决方案包括:通过lm遍历变量组合(构建公式或子集化数据),或用MuMIn::dredge做模型筛选。
核心问题:是否有其他可选方案?包括上述两种在内,哪种方法速度最快?
我尝试了tidymodels但首次尝试速度过慢,基于workflowsets的方法无法正常运行,寻求帮助。
模拟数据
library(tidyverse) library(tidymodels) data = mtcars[,1:5] # 模拟数据 preds = names(data)[-1] # 自变量 preds.combs = map(1:length(preds), ~ combn(preds, .x, simplify = FALSE)) %>% flatten() # 所有自变量组合的列表
我的尝试
方案一:通过map遍历所有组合并调用lm
test_map = function(){ map(preds.combs, ~ lm(reformulate(.x, "mpg"), data))}
构建公式的方式速度更快,因为R无需修改对象,而~ lm(mpg ~ ., select(data, mpg, all_of(.x))))的子集化方式会更慢。
方案二:使用MuMIn::dredge进行模型筛选
test_dredge = function(){ lm(mpg ~ ., data, na.action = "na.fail") %>% MuMIn::dredge()}
我倾向于避免该方法,因为它不会返回完整模型,且仅支持该包兼容的模型类型。
方案三:使用tidymodels创建工作流并更新变量组合
test_wflow = function(){ wflow = workflow() %>% add_model(linear_reg()) %>% add_variables(mpg, cyl) res = list() for(i in seq_along(preds.combs)){ res[[i]] = wflow %>% update_variables(mpg, all_of(preds.combs[[i]])) %>% fit(data)}}
改用update_formula或update_recipe方法对运行时间无显著影响。
方案四:使用workflowsets创建工作流集并拟合所有模型
library(workflowset) test_wflowset = function(){ wflow = workflow_set( preproc = map(preds.combs, ~ reformulate(.x, "mpg")), models = list(lm = linear_reg()), cross = TRUE) fit(wflow)} # 此处写法有误,如何拟合工作流集中的每个工作流?
可结合交叉验证使用workflow_map(wflow, resamples = vfold_cv(data, v = 10))调参,但我仅需拟合模型,无需调参。该方法目前无法正常运行,未纳入基准测试。
基准测试
bench::mark(test_map(), test_dredge(), test_wflow(), check = FALSE, min_iterations = 3) %>% select(c(expression, min, median, mem_alloc, n_itr, n_gc))
测试结果:
| expression | min | median | mem_alloc | n_itr | n_gc |
|---|---|---|---|---|---|
| test_map() | 20.4ms | 21.44ms | 99.2KB | 21 | 1 |
| test_dredge() | 46.75ms | 48.9ms | 110.9KB | 11 | 0 |
| test_wflow() | 2.12s | 2.13s | 5MB | 3 | 5 |
内容的提问来源于stack exchange,提问作者Ricardo Semião
相关产品推荐
相关产品推荐

