h2o 和 caret 中的数据分区函数似乎在泄漏数据?

Data partitioning functions in h2o and caret seem to be leaking data?

我怀疑 h2o 和 caret 的数据分区函数可能会以某种方式泄漏数据。我怀疑这是因为我在使用 h2o 的 h2o.splitFrame 函数或插入符号的 createDataPartition 函数时得到了两个完全不同的结果 - 与我自己手动分区数据时相比:

在我的时间序列数据、3000-4000 个数据点和使用 10 倍 CV 的数据框中,我在所有数据集中获得了非常可接受的结果:训练、验证、交叉验证和测试集使用插入符号的 xgboost 或 h2o 时。但是,当我使用插入符号的 createDataPartition 函数和 h2o 的 h2o.splitFrame 函数时,这些高 r2/low RMSE(良好)结果 出现。

另一方面,如果我手动自己删除一部分数据以创建一个完全独立的测试集数据框(同时仍然使用适当的分区函数将数据拆分为训练和验证集),那么 手动创建的 测试集结果很差 - 而训练、验证和交叉验证结果仍然很好(高 r2/low RMSE)。

为了建立控制,我可以故意弄乱数据 - 使用随机数,删除多个 features/columns 等 - 并且预测结果在训练、验证、10 倍 CV 和测试中都很糟糕集。

例如,这里是我用来分区数据的h2o代码。当我使用特定于包的数据分区函数时看到的这些奇怪的、不一致的结果让我想知道所有这些 "amazing accuracy" 是否可以在媒体上阅读关于机器学习的内容 - 可能部分是由于数据泄漏什么时候使用分区函数?

#Pre-process
df_h2o <- write.csv(df, file = "df_h2o.csv")
df <- h2o.importFile(path = normalizePath("df_h2o.csv"),  destination_frame 
= "df")

## Pre moodel
#Splitting the data
splits <- h2o.splitFrame(df, c(0.6,0.2), seed=1234)
train <- h2o.assign(splits[[1]], "train")   
valid <- h2o.assign(splits[[2]], "valid")   
test <- h2o.assign(splits[[3]], "test") ### <--- My test results are poor if 
                                        ### I manually partition test data                                            
                                        ### myself (i.e. without using any
                                        ### partitioning function). 
                                        ### Otherwise, results are good.   

#Identify the variable that will predict and independent variables
y <- "Target"
x <- setdiff(colnames(train),y)

#Build model
model<-h2o.deeplearning(x=x,              
                    y=y,
                    seed = 1234,
                    training_frame = train,
                    validation_frame = valid,
                    hidden = c(40,40),
                    nfolds = 10,
                    stopping_rounds = 7,
                    epochs = 500,
                    overwrite_with_best_model = TRUE,
                    standardize = TRUE,
                    activation = "Tanh",
                    loss = "Automatic",
                    distribution = "AUTO",
                    stopping_metric = "MSE",
                    variable_importances=T)

如果您的意思是 "data leakage",该术语通常与意外包含与响应列相关(以 "bad"/作弊方式)的预测列的过程相关联。按行拆分数据框永远不会导致虚假数据泄漏。

如果您手动创建的训练、有效和测试框架产生了糟糕的结果,这可能是因为您的行不是随机的并且您的模型对训练集过度拟合。由于 h2o::h2o.splitFrame()caret::createDataPartition() 在拆分过程中使用随机化,它将产生均匀分布的训练集、有效集和测试集,并产生更好的模型。但是,如果您的手动数据集也是随机创建的,那么您所说的对我来说意义不大。

希望您使用 h2o.performance(model, test) 来确定测试集的准确性(尽管我在您的脚本中没有看到)。默认情况下,H2O 的深度学习将使用 validation_frame 进行提前停止,因此验证指标不是对泛化误差的诚实估计。因此需要一个测试集。