为何负索引无法生成预期补集?R语言划分训练、验证、测试数据集的异常问题
问题原因分析
你的问题出在对R中负索引的理解偏差上:
当你执行valid <- sample(rest, 200)时,得到的valid向量是rest中的元素值(也就是原数据集里的行号,比如355、356这类数值),而不是这些元素在rest向量里的位置索引(比如1到300之间的数)。
当你用rest[-valid]时,R会把valid里的数值当作要排除的元素在rest中的位置,而不是要排除的元素值。举个简单例子:假设rest是c(355, 356, 357, ..., 654)(共300个元素),你采样得到的valid里的数值都是355到654之间的数,远大于rest的长度300。R遇到超出向量长度的索引时会忽略这些无效索引,最终导致rest[-valid]剩下的元素远多于预期的100个。
解决方案
有两种简单的方法可以修正这个问题:
方法一:采样位置而非元素值
直接对rest的位置索引进行采样,再通过位置提取验证集和测试集的元素值:
x <- 1:654 train_ind <- sample(x, 354) rest <- x[-train_ind] # 采样rest中的位置(1到300) valid_pos <- sample(seq_along(rest), 200) valid_ind <- rest[valid_pos] test_ind <- rest[-valid_pos] length(test_ind) # 输出:100
方法二:使用setdiff()函数
setdiff()可以直接找出rest中不在valid里的元素,完美匹配你的需求:
x <- 1:654 train_ind <- sample(x, 354) rest <- x[-train_ind] valid_ind <- sample(rest, 200) test_ind <- setdiff(rest, valid_ind) length(test_ind) # 输出:100
这两种方法都能准确得到100条测试集的索引,你可以根据习惯选择其中一种。
内容的提问来源于stack exchange,提问作者Ari
相关产品推荐
相关产品推荐

