You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用tidymodels处理分布在多列的同一分类变量?

tidymodels处理分散在多列的同分类变量方案

核心要求是同一分类取值无论出现在哪一列,模型效应完全一致,你设想的「宽转长-编码-聚合回单行」逻辑完全可行,且tidymodels的recipe框架完全支持这类操作,不需要跳出工作流做手动预处理(手动预处理会带来数据泄露风险)。以下是两种可直接复用的实现方式:


方案1:哑变量聚合(无自定义步骤,代码最简洁)

不需要做长宽转换,核心逻辑是先统一所有关联列的因子水平,编码后对同取值的哑变量做行聚合,完全满足同值同效应的要求:

  • 先收集所有Pet列的全部非缺失取值,设为全局统一因子水平,避免某一列未出现某个取值导致水平缺失
  • 对所有Pet列做全哑变量编码(不设基准水平)
  • 按分类取值对哑变量列做行聚合:只要任意Pet列出现某个取值,对应聚合列就记为存在(或计数)
  • 删除编码生成的中间列,保留聚合后的结果即可

可直接运行的示例代码:

library(tidymodels)

# 构造示例数据集
df <- tibble(
  ID = 1:4,
  Pet_1 = c("dog", "cat", NA, "horse"),
  Pet_2 = c("horse", "bird", NA, "dog"),
  Pet_3 = c("cat", NA, NA, "snake"),
  Siblings = c(0,1,3,1),
  Income = c(90000,50000,75000,120000),
  Result = c(0,1,1,0)
)

# 收集所有Pet列的全局取值
all_pet_levels <- unique(unlist(select(df, starts_with("Pet_"))) %>% na.omit())

pet_recipe <- recipe(Result ~ ., data = df) %>%
  # 标记ID列,不参与建模
  update_role(ID, new_role = "ID") %>%
  # 统一所有Pet列的因子水平
  step_mutate_at(
    starts_with("Pet_"),
    fn = ~factor(., levels = all_pet_levels)
  ) %>%
  # 对所有Pet列做独热编码
  step_dummy(starts_with("Pet_"), one_hot = TRUE) %>%
  # 按宠物类型聚合哑变量:存在记为1,不存在记为0
  step_mutate(
    across(
      all_of(paste0("Pet_1_", all_pet_levels)),
      ~ as.integer(rowSums(across(ends_with(paste0("_", cur_column() %>% str_extract("[a-z]+$")))), na.rm = T) > 0),
      .names = "contains_{.col %>% str_extract('[a-z]+$')}"
    )
  ) %>%
  # 删除编码生成的中间列
  step_rm(matches("^Pet_[1-3]_")) %>%
  # 常规后续预处理:数值变量标准化等
  step_normalize(all_numeric_predictors(), -starts_with("contains_"), -Siblings)

# 验证预处理结果
prep(pet_recipe) %>% bake(new_data = NULL)

运行后你会发现,无论dog出现在Pet_1还是Pet_2,contains_dog列都会正确标记为1,完全满足同值同效应的要求。如果需要统计饲养数量而非是否存在,把as.integer(>0)的判断去掉,直接保留rowSums的结果即可。三个Pet列全为NA的样本,所有contains_*列都会为0,自动对应「无宠物」分组,不需要额外插补缺失值。


方案2:自定义recipe步骤实现宽转长-编码-聚合

如果你更习惯长格式处理逻辑(比如需要对Pet变量做目标编码、权重编码等更复杂的编码操作),可以自定义recipe步骤完成全流程,所有计算都在recipe框架内完成,不会泄露测试集信息:

  1. prep阶段:仅用训练集数据收集所有Pet列的合法取值,训练对应的编码器
  2. bake阶段:对任意传入的数据集(训练/测试/新数据),依次完成「选Pet列+ID转长格式→剔除缺失值→用预训练的编码器编码→按ID分组聚合编码结果→合并回原数据集还原单行结构」的操作
  3. 聚合逻辑和方案1一致,同取值的编码结果会被合并到同一列,保证效应一致

关键注意点:绝对不要在定义recipe之前手动做Pet列的聚合和编码,否则交叉验证时测试集的取值会提前参与因子水平、编码参数的计算,导致模型评估结果虚高。所有预处理逻辑必须封装在recipe内部,由tidymodels工作流自动在每个交叉验证折的训练集上拟合参数,再应用到对应折的测试集上。


内容的提问来源于stack exchange,提问作者WTB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 05:12:19