如何从基于recipe与logistic_reg() %>% set_engine("glm")构建的tidymodel对象中提取原生glm类模型?
提取tidymodels中的原生glm模型并解决参数差异问题
当然可以从tidymodels的工作流拟合结果中提取出原生的glm类模型,完美适配easystats工具包!下面一步步帮你解决问题:
1. 提取原生glm模型
你用pull_workflow_fit()得到的model_fit对象,内部其实包含了原生的glm模型实例,只需要通过$fit或者pluck("fit")就能提取出来:
library(tidymodels) library(easystats) # 示例:构建并拟合一个逻辑回归工作流 data(mtcars) mtcars$am <- factor(mtcars$am) # 转为分类变量 # 创建预处理配方 rec <- recipe(am ~ mpg + hp, data = mtcars) %>% step_center(all_predictors()) %>% step_scale(all_predictors()) # 定义模型规格 log_reg_spec <- logistic_reg() %>% set_engine("glm") # 组装工作流并拟合 wf_fit <- workflow() %>% add_recipe(rec) %>% add_model(log_reg_spec) %>% fit(data = mtcars) # 提取原生glm模型 native_glm <- wf_fit %>% pull_workflow_fit() %>% pluck("fit") # 现在可以直接用easystats的工具啦 model_summary(native_glm) check_model(native_glm)
提取后的native_glm就是标准的glm类对象,完全兼容easystats的所有函数。
2. 解决直接用glm()拟合的参数差异问题
你提到直接用glm()和配方中的公式得到参数不同,这核心原因是工作流中的配方做了预处理(比如中心化、标准化、哑变量编码等),而直接调用glm()时没有应用这些预处理步骤。要让参数一致,只需要让glm()使用和工作流中完全相同的预处理后数据即可:
方法一:用预处理后的数据集拟合glm
先通过配方处理原始数据,再用处理后的数据拟合glm:
# 预处理数据 processed_data <- prep(rec, data = mtcars) %>% bake(new_data = NULL) # 用处理后的数据拟合glm glm_direct <- glm(am ~ mpg + hp, data = processed_data, family = binomial()) # 对比参数,完全一致! all.equal(coef(native_glm), coef(glm_direct))
方法二:从工作流中提取预处理后的训练数据
也可以直接从已拟合的工作流中提取处理好的数据:
# 从工作流中提取预处理后的训练数据 wf_processed_data <- wf_fit %>% pull_workflow_prepped_recipe() %>% bake(new_data = NULL) # 拟合glm glm_from_wf <- glm(am ~ mpg + hp, data = wf_processed_data, family = binomial()) # 参数完全匹配 all.equal(coef(native_glm), coef(glm_from_wf))
这样就能保证两种方式拟合出的模型参数完全一致,同时也能顺利使用easystats工具包分析模型啦。
内容的提问来源于stack exchange,提问作者Marco B
相关产品推荐
相关产品推荐

