基于双结果变量的分层数据划分方案咨询(R语言)
解决方案:基于双变量组合的分层抽样
这是个很实际的问题——当需要同时维护多个不平衡变量的类别比例,还要保证训练/测试集对齐时,单独按每个变量分层肯定会出问题。这里有个靠谱的解决方案:基于两个变量的组合进行分层抽样,这样既能同时保留case1和case2的类别分布,又能让训练集和测试集的样本量完全一致。
核心思路
把case1和case2的组合作为一个新的分层因子,用这个组合因子来划分数据集。这样做能确保每个(case1, case2)的组合在训练集和测试集中的比例与原始数据一致,自然也就同时保留了两个单独变量的类别分布,而且训练/测试集的样本量会完全匹配。
代码实现
我们基于你的示例数据来演示这个方法:
library(caret) set.seed(123) # 生成你的示例数据 matris <- matrix(rnorm(10), 1000, 20) case1 <- as.factor(ceiling(runif(1000, 0, 4))) case2 <- as.factor(ceiling(runif(1000, 0, 50))) df <- as.data.frame(matris) df$case1 <- case1 df$case2 <- case2 # 创建case1和case2的组合因子(drop=TRUE自动移除没有样本的组合) df$case_combined <- interaction(df$case1, df$case2, drop = TRUE) # 基于组合因子进行分层抽样,测试集比例设为0.2 set.seed(123) split_combined <- createDataPartition(df$case_combined, p = 0.2)[[1]] train_combined <- df[-split_combined, ] test_combined <- df[split_combined, ] # 查看样本量,现在训练和测试集大小完全一致 nrow(train_combined) # 799 nrow(test_combined) # 201
验证比例是否符合要求
我们可以简单验证一下两个变量的类别比例是否在训练/测试集中保持一致:
# 验证case1的比例一致性 cat("--- case1比例验证 --- \n") print(prop.table(table(df$case1))) print(prop.table(table(train_combined$case1))) print(prop.table(table(test_combined$case1))) # 随机选几个case2的水平验证比例(case2水平太多,不用全看) cat("\n--- case2随机水平比例验证 --- \n") sample_case2_levels <- sample(levels(df$case2), 5) for(level in sample_case2_levels) { cat("Case2水平", level, "\n") cat("原始数据:", round(table(df$case2)[level]/nrow(df), 3), "\n") cat("训练集:", round(table(train_combined$case2)[level]/nrow(train_combined), 3), "\n") cat("测试集:", round(table(test_combined$case2)[level]/nrow(test_combined), 3), "\n\n") }
额外说明
- 这个方法完全适配
case2后续增加水平的场景,interaction函数会自动识别新的组合并纳入分层逻辑。 - 如果某些
(case1, case2)组合的样本量极小(比如只有1个样本),createDataPartition会自动处理这类情况,不会影响整体的分布平衡;如果这类极端组合太多,你可以考虑合并相似的小样本组合,或者调整抽样比例。
内容的提问来源于stack exchange,提问作者Andres
相关产品推荐
相关产品推荐

