R tidymodels中workflow_set使用glm模型调用workflow_map报错
问题描述
使用tidymodels包为数据集拟合多个glm模型筛选最优性能模型时,为测试多种预处理流程与模型规格的组合,通常采用workflow_set()批量生成工作流集合,再通过workflow_map()批量拟合并获取性能指标。
对工作流集合调用workflow_map()时会触发如下晦涩报错:
Error in if (rlang::call_name(x) == "tune") {: argument is of length zero
初步排查显示报错来自workflow_map()内部的check_fn()函数,但无法定位底层代码问题。测试发现:单独从工作流集合中提取单个工作流执行拟合、预测操作均可正常运行,仅直接调用workflow_map()时触发错误。
复现代码
library(tidyverse) library(tidymodels) data("mtcars") glm_recipe = recipe(hp ~ disp, data = mtcars) glm_model = linear_reg() %>% set_engine("glm", family = stats::gaussian("log")) glm_workflows = workflow_set(list(glm_recipe), list(glm_model)) # 单独提取工作流做拟合、预测可正常运行 glm_workflows %>% extract_workflow("recipe_linear_reg") %>% fit(mtcars) %>% predict(mtcars) #> # A tibble: 32 x 1 #> .pred #> <dbl> #> 1 117. #> 2 117. #> 3 103. #> 4 151. #> 5 195. #> 6 138. #> 7 195. #> 8 113. #> 9 112. #> 10 120. #> # ... with 22 more rows # 直接调用workflow_map会报错 workflow_map(glm_workflows) #> Error in if (rlang::call_name(x) == "tune") {: argument is of length zero #> Execution stopped; returning current results #> # A workflow set/tibble: 1 x 4 #> wflow_id info option result #> <chr> <list> <list> <list> #> 1 recipe_linear_reg <tibble [1 x 4]> <opts[0]> <list [0]>
报错原因
workflow_map()执行前会遍历所有模型引擎参数,检查是否存在tune()调优标记。当在set_engine()中直接传入带命名空间前缀的函数调用(即stats::gaussian("log"))时,检查逻辑用rlang::call_name()提取函数名会返回空值,触发判断条件长度为0的错误。
单个工作流拟合时不会走这套调优参数检查逻辑,所以可以正常运行。
解决方法
任选以下一种修改方式即可:
- 去掉
gaussian()前的stats::命名空间前缀,基础包函数默认在R搜索路径中,无需显式声明命名空间:
glm_model = linear_reg() %>% set_engine("glm", family = gaussian("log"))
- 如果需要显式指定命名空间,提前将family对象赋值给变量,再传入
set_engine(),避免参数中直接出现带命名空间的函数调用:
log_gauss <- stats::gaussian("log") glm_model = linear_reg() %>% set_engine("glm", family = log_gauss)
修改完成后重新生成工作流集合,再调用workflow_map()即可正常批量拟合。
内容的提问来源于stack exchange,提问作者Ildifa
相关产品推荐
相关产品推荐

