R语言测试集出现训练集未涵盖分类值时的均值填补方案咨询
分类变量出现训练集未覆盖取值时的y值填补R实现方案
样本示例
训练集
仅提供2行样本方便复现,cat1~catN为分类变量,y为数值型因变量:
w1=structure(list(cat1 = c(1L, 1L), cat2 = c(2L, 2L), cat3 = c(3L, 3L), cat4 = c(4L, 4L), y = c(30L, 40L)), class = "data.frame", row.names = c(NA, -2L))
测试集示例1(单分类变量出现新取值)
w2中cat3出现训练集不存在的取值2:
w2=structure(list(cat1 = c(1L, 1L), cat2 = c(2L, 2L), cat3 = 3:2, cat4 = c(4L, 4L), y = c(30L, 40L)), class = "data.frame", row.names = c(NA, -2L))
测试集示例2(多分类变量同时出现新取值)
w3中cat2的取值3、cat4的取值3均未在训练集中出现:
w3=structure(list(cat1 = c(1L, 1L), cat2 = 2:3, cat3 = c(3L, 3L), cat4 = 3:4, y = c(30L, 40L)), class = "data.frame", row.names = c(NA, -2L))
核心逻辑
对测试集每条样本按以下规则处理:
- 识别取值未在训练集对应分类变量中出现的变量,直接排除该类变量
- 用剩余取值匹配的分类变量作为分组键,筛选训练集对应分组的样本
- 计算筛选样本的
y均值,作为当前测试样本的填补值
通用实现代码
适配任意数量、任意前缀的分类变量场景:
fill_test_y <- function(train_df, test_df, cat_prefix = "cat", y_col = "y") { # 自动识别所有分类变量 cat_cols <- grep(paste0("^", cat_prefix), colnames(train_df), value = TRUE) # 预存训练集各分类变量的取值集合,减少重复计算 train_cat_levels <- lapply(cat_cols, function(col) unique(train_df[[col]])) names(train_cat_levels) <- cat_cols # 逐行处理测试集样本 test_df[[y_col]] <- apply(test_df, 1, function(row) { row <- as.list(row) # 筛选出取值匹配训练集的有效分类变量 valid_cols <- Filter(function(col) row[[col]] %in% train_cat_levels[[col]], cat_cols) # 构建训练集筛选条件 filter_cond <- rep(TRUE, nrow(train_df)) for (col in valid_cols) { filter_cond <- filter_cond & (train_df[[col]] == row[[col]]) } # 返回分组均值 return(mean(train_df[filter_cond, ][[y_col]], na.rm = TRUE)) }) return(test_df) }
效果验证
测试w2
fill_test_y(w1, w2)
输出结果:
cat1 cat2 cat3 cat4 y 1 1 2 3 4 35 2 1 2 2 4 35
测试w3
fill_test_y(w1, w3)
输出结果:
cat1 cat2 cat3 cat4 y 1 1 2 3 3 35 2 1 3 3 4 35
内容的提问来源于stack exchange,提问作者psysky
相关产品推荐
相关产品推荐

