我正在运行一个基准实验,其中我调整了一个过滤后的学习器,类似于 mlr 教程中嵌套重采样下给出的示例,标题为"示例 3:一个任务,两个学习器,使用调优进行特征过滤"。我的代码如下:
library(survival)
library(mlr)
data(veteran)
set.seed(24601)
configureMlr(show.learner.output=TRUE, show.info=TRUE)
task_id = "MAS"
mas.task <- makeSurvTask(id = task_id, data = veteran, target = c("time", "status"))
mas.task <- createDummyFeatures(mas.task)
inner = makeResampleDesc("CV", iters=2, stratify=TRUE) # Tuning
outer = makeResampleDesc("CV", iters=3, stratify=TRUE) # Benchmarking
cox.lrn <- makeLearner(cl="surv.coxph", id = "coxph", predict.type="response")
cox.filt.uni.thresh.lrn = makeTuneWrapper(
makeFilterWrapper(
makeLearner(cl="surv.coxph", id = "cox.filt.uni.thresh", predict.type="response"),
fw.method="univariate.model.score",
perf.learner=cox.lrn
),
resampling = inner,
par.set = makeParamSet(makeDiscreteParam("fw.threshold", values=c(0.5, 0.6, 0.7))),
control = makeTuneControlGrid(),
show.info = TRUE)
learners = list( cox.filt.uni.thresh.lrn )
bmr = benchmark(learners=learners, tasks=mas.task, resamplings=outer, measures=list(cindex), show.info = TRUE)
使用这种方法,似乎外部重采样循环的每次迭代都将使用 fw.threshold 可能不同的值 - 它将使用内部循环中确定的最佳值。我的问题是,这是可以接受的,还是先使用 tuneParams 和交叉验证调整该参数,然后使用之前调整的参数运行基准测试,如下所示:
library(survival)
library(mlr)
data(veteran)
set.seed(24601)
configureMlr(show.learner.output=TRUE, show.info=TRUE)
task_id = "MAS"
mas.task <- makeSurvTask(id = task_id, data = veteran, target = c("time", "status"))
mas.task <- createDummyFeatures(mas.task)
inner = makeResampleDesc("CV", iters=2, stratify=TRUE) # Tuning
outer = makeResampleDesc("CV", iters=3, stratify=TRUE) # Benchmarking
cox.lrn <- makeLearner(cl="surv.coxph", id = "coxph", predict.type="response")
cox.filt.uni.thresh.lrn =
makeFilterWrapper(
makeLearner(cl="surv.coxph", id = "cox.filt.uni.thresh", predict.type="response"),
fw.method="univariate.model.score",
perf.learner=cox.lrn
)
params = makeParamSet(makeDiscreteParam("fw.threshold", values=c(0.5, 0.6, 0.7)))
ctrl = makeTuneControlGrid()
tuned.params = tuneParams(cox.filt.uni.thresh.lrn, mas.task, resampling = inner, par.set=params, control=ctrl, show.info = TRUE)
tuned.lrn = setHyperPars(cox.filt.uni.thresh.lrn, par.vals = tuned.params$x)
learners = list( tuned.lrn )
bmr = benchmark(learners=learners, tasks=mas.task, resamplings=outer, measures=list(cindex), show.info = TRUE)
在这种情况下,第二种方法给出的结果略差,但我想知道哪种方法是正确的。
使用这种方法,似乎每次迭代的外部重采样 循环将为 fw.threshold 使用可能不同的值 - 它将 使用在内部循环中确定的最佳值。我的问题 是,这是可以接受的还是调整该参数更好 首先,使用 tuneParams 和交叉验证,然后运行 使用之前调整的参数进行基准测试,如下所示:
否,因为在本例中,您的模型已经看到了数据。 这引入了偏见。 您应该在CV中分别对每个折叠进行所有优化。 所以方法#1是正确的。
此外,我建议不要使用网格搜索或MBO,而不是使用网格搜索。