问题描述
我想通过列举这似乎是一个常见问题来开头我的问题:
- Incorrect splitting of data using sample.split in R and issue with logistic regression
- SplitRatio results with sample.split (caTools)
但是,我无法使用第一个问题中建议的解决方案来解决问题,而第二个问题从未得到解答。
在下面的代码中,我希望对四个结果分别进行100次观察,显然100/150 = 2/3:
library(caTools)
set.seed(123)
isample <- sample.split(iris[,1],SplitRatio = 2/3,group = NULL)
iris2 <- iris[isample,]
isample2 <- sample.split(iris[,group = NULL)
iris3 <- subset(iris,isample2 == T)
isample3 <- sample.split(iris$Sepal.Length,group = NULL)
sepal.length2 <- iris[isample3,1]
isample4 <- sample.split(iris$Sepal.Length,group = NULL)
sepal.length3 <- subset(iris[,isample4 == T)
但是,我在iris2
和iris3
以及向量sepal.length2
和sepal.length3
中都得到了104个观测值。我确保每次都绘制一个新的样本,以确保这对于样本函数的四舍五入来说并不奇怪。使用iris
中的第2列和第3列返回100个观测值,而使用第5列则返回99个观测值。为什么更改列返回不同的值?此功能的一个常见错误是意外地给了它整个数据帧,因此它是基于列进行选择的,但是在这里,我确保每次都给它一个向量。在最后两个示例中,我给它提供了一个向量,然后从向量中确定了拆分,它仍然不起作用。
如果有帮助,我将在OS X上运行R 3.6.0和caTools 1.18.0。我通常会使用sample
或sample.int
函数,所以我并不那么熟悉caTools。
解决方法
在对可用的源文件进行了一些搜索和一些测试之后,1我开始意识到,这是由于作者编写此函数的方式中舍入错误的累积所致。以for( iU in 1:nU)
开始的循环会舍入每个标签上的随机抽奖次数,因此对于比率为2/3的标签以及在数据中出现4次的标签,我们以n = round(length(idx)*rat)
结尾四舍五入到3,或者8 * 2/3四舍五入到5。在循环过程中,这导致最终的计数过量。
重新阅读sample.split文档,它说:“将向量Y的数据按预定义比例分成两组,同时保留Y中不同标签的相对比例。因此,我的结论是,该函数试图保留向量中每个唯一标签的比率,这意味着它试图在萼片长度上保持5.3出现的2 / 3、4.9出现的2/3。等在每个测试和培训集中。使用此功能的用户宁愿进行不精确的测试/培训划分,最后最终得到更精确的测试错误,因为他们可以期望保留每次出现的比率。由于此函数用于分类,因此我得出结论,在数据中有许多唯一值的情况下,应避免使用它。