我有一个包含55万个项目的数据集,我将其分为50万用于训练和5万用于测试。在训练阶段,需要确定每种算法参数的最佳组合。为了实现这一点,我并不想使用全部的50万数据,而愿意使用一个子集,但在使用最佳参数组合训练最终模型时,我想使用全部的50万数据。用伪代码描述这个任务如下:
subset the 500k training data to 50kfor each combination of model parameters (3, 6, or 9) for each repeat (3) for each fold (10) fit the model on 50k training data using the 9 folds evaluate performance on the remaining foldestablish the best combination of parametersfit to all 500k using best combination of parameters
为了实现这一点,我需要告诉caret在优化之前应该对数据进行子集划分,但在最终拟合时,使用所有数据。
我可以通过以下步骤来实现:(1) 对数据进行子集划分;(2) 进行常规的训练阶段;(3) 停止最终拟合(不需要);(4) 确定最佳参数组合(这在训练输出中);(5) 在完整的50万数据上运行训练,不进行参数优化。
这种方法有点不整洁,而且我不知道如何阻止caret训练最终模型,因为我永远不会使用它。
回答:
可以通过指定trainControl中的index、indexOut和indexFinal参数来实现这一点。
以下是使用mlbench库中的Sonar数据集的一个示例:
library(caret)library(mlbench)data(Sonar)
假设我们每次希望从Sonar数据集中抽取一半用于训练,并重复10次:
train_inds <- replicate(10, sample(1:nrow(Sonar), size = nrow(Sonar)/2), simplify = FALSE)
如果您对不同的抽样方法感兴趣,请发布详细信息。这仅用于说明。
对于测试,我们将使用不在train_inds中的随机10行:
test_inds <- lapply(train_inds, function(x){ inds <- setdiff(1:nrow(Sonar), x) return(sample(inds, size = 10))})
现在只需在trainControl中指定test_inds和train_inds:
ctrl <- trainControl( method = "boot", number = 10, classProbs = T, savePredictions = "final", index = train_inds, indexOut = test_inds, indexFinal = 1:nrow(Sonar), summaryFunction = twoClassSummary )
如果您不希望在所有行上拟合最终模型,也可以指定indexFinal。
然后进行拟合:
model <- train( Class ~ ., data = Sonar, method = "rf", trControl = ctrl, metric = "ROC" )model#outputRandom Forest 208 samples, 208 used for final model 60 predictor 2 classes: 'M', 'R' No pre-processingResampling: Bootstrapped (10 reps) Summary of sample sizes: 104, 104, 104, 104, 104, 104, ... Resampling results across tuning parameters: mtry ROC Sens Spec 2 0.9104167 0.7750 0.8250000 31 0.9125000 0.7875 0.7916667 60 0.9083333 0.7875 0.8166667