我在分割数据时希望在80/20的训练/验证集中实现样本在各个数据集中的均匀分布。我不想随机进行分割,因为我需要确保样本在两个集合中的分布均匀,并且避免产生偏见。然而,我希望确保每个类别的80%样本都在训练集中。
为此,我想尝试在R语言的caret包中实现这一点,例如:
data_split <- createDataPartition(y=data$column, p=0.8, list=F) #分割数据training <- data[data_split,] #调用训练数据testing <- data[-data_split,] #调用测试或验证数据
例如,我有64个类别,并且考虑对每个类别进行随机数据分割。
这样做正确吗?
回答:
如果我正确理解了您的需求,您的做法是正确的。createDataPartition
函数正是为这种情况设计的。它基于结果进行简单分割,如说明文档中所述
随机抽样在每个类别内部进行,并应保持数据的整体类别分布
我们可以通过一个简单的图表来验证这一点
library(caret)library(ggplot2)set.seed(5)df <- data.frame(a=runif(1000),b=runif(1000)*10,c=sample(as.character(1:64),1000,replace = T))str(df)#将数据按80/20分割成训练/测试集ind <- createDataPartition(df$c, p=0.8,list = F)train <- df[ind,]test <- df[-ind,]#整个数据集每个类别的频率x <- table(df$c)/length(df$c)#训练集的频率x_train <- table(train$c)/length(train$c)#测试集的频率x_test<- table(test$c)/length(test$c)freq <- data.frame(class=names(x),df=as.numeric(x),train=as.numeric(x_train),test=as.numeric(x_test))ggplot(freq,aes(x=class))+geom_line(aes(y=df,group=1),col="red")+geom_line(aes(y=train,group=1),col="green")+geom_line(aes(y=test,group=1),col="blue")+ylab("频率")
如您所见,每个类别的分布得到了保持