2016-11-10 159 views
2

在mlr中,可以使用嵌套交叉验证来进行过滤器特征选择以及超参数调整,例如,用下面的代码。R mlr - 无需嵌套嵌套交叉验证的包装特征选择+超参数调整?

lrn = makeFilterWrapper(learner = "regr.kknn", fw.method = "chi.squared") 
ps = makeParamSet(makeDiscreteParam("fw.abs", values = 10:13), 
        makeDiscreteParam("k", values = c(2, 3, 4))) 
ctrl = makeTuneControlGrid() 
inner = makeResampleDesc("CV", iter = 2) 
outer = makeResampleDesc("Subsample", iter = 3) 
lrn = makeTuneWrapper(lrn, resampling = inner, par.set = ps, control = ctrl, show.info = FALSE) 
res = resample(lrn, bh.task, outer, mse, extract = getTuneResult) 

但据我所知,这是不可能做这样的事情使用的包装功能的选择,例如:

lrn = makeFeatSelWrapper(learner = "regr.kknn", ww.method = "random") # imaginary code 
ps = makeParamSet(makeDiscreteParam("maxit", 15), 
        makeDiscreteParam("k", values = c(2, 3, 4))) # imaginary code, no method parameter & no resampling provided 
ctrl = makeTuneControlGrid() 
inner = makeResampleDesc("CV", iter = 2) 
outer = makeResampleDesc("Subsample", iter = 3) 
lrn = makeTuneWrapper(lrn, resampling = inner, par.set = ps, control = ctrl, show.info = FALSE) 
res = resample(lrn, bh.task, outer, mse, extract = getTuneResult) 

有没有办法实现这样的事情?特别是,为了避免嵌套嵌套交叉验证?有没有方法论的原因,为什么这不合适?因为实际上,使用具有调整参数(特征数量)的过滤器特征选择看起来与包装器方法非常相似,也就是说,您的附加超参数实际上是一组特征,可以从过滤器(例如“卡方”)+阈值(最高90%,80%,70%)或包装算法(随机,遗传算法,穷举,顺序)的输出,最好的特征集合是基于两种情况下的内部cv性能。我相信这两种方法(与过滤和嵌套嵌套的附加参数嵌套)在计算复杂性方面类似,但您可能不想使用嵌套嵌套CV进一步减少训练数据集,这是可以实现的采用第一种方法。

这是我正在做的一个方法错误还是这是一个缺乏(可能不是真正流行)的功能?

+1

'bh.task'是一个回归任务'lm'也是一种回归方法。您可能希望使用'mse'作为重采样的一项措施。 –

+0

@jakobr啊,对不起,我只是无意识地复制了一段代码,只是为了展示我所问的概念。编辑 – Matek

回答

1

此功能在MLR可用,因为July。一个需要安装Git版本

devtools::install_github("mlr-org/mlr") 

TuneWrapper需要在内部采样循环而FeatSelWrapper需要在外部采样循环。下面是使用iris.task和rpart包与后向选择的一个示例:

library(mlr) 

调谐参数:

ps <- makeParamSet(
    makeNumericParam("cp", lower = 0.01, upper = 0.1), 
    makeIntegerParam("minsplit", lower = 10, upper = 20) 
) 

网格搜索:

ctrl <- makeTuneControlGrid(resolution = 5L) 

指定学习者:

lrn <- makeLearner("classif.rpart", predict.type = "prob") 

生成调包装:

lrn <- makeTuneWrapper(lrn, resampling = cv3, par.set = ps, control = makeTuneControlGrid(), show.info = FALSE) 

生成特征选择包装:

lrn = makeFeatSelWrapper(lrn, 
         resampling = cv3, 
         control = makeFeatSelControlSequential(method = "sbs"), show.info = FALSE) 

进行重新取样:

res <- resample(lrn, task = iris.task, resampling = cv3, show.info = TRUE, models = TRUE) 

注意,即使这个小例子将需要一些时间

res 
#output 
Resample Result 
Task: iris_example 
Learner: classif.rpart.tuned.featsel 
Aggr perf: mmce.test.mean=0.1000000 
Runtime: 92.1436 

可以做t他同样的事情没有最外面的resample:

lrn <- makeLearner("classif.rpart", predict.type = "prob") 
lrn <- makeTuneWrapper(lrn, resampling = cv3, par.set = ps, control = makeTuneControlGrid(), show.info = TRUE) 
res2 <- selectFeatures(learner = lrn , task = iris.task, resampling = cv3, 
         control = makeFeatSelControlSequential(method = "sbs"), show.info = TRUE) 
+0

哇!真高兴你让我知道这么古老的线程,谢谢!接受答案。 – Matek

+0

我在寻找一种方式来执行完全相同的事情时找到了线程。很高兴我能帮上忙。 – missuse

1

如果我找到了你,你基本上是问如何调整FeatSelWrapper?这有点复杂,因为特征选择(在mlr)取决于重采样,因为它基本上是调谐。我们不调整学习者参数,但我们调整了功能的选择以优化性能指标。要计算度量我们需要重新采样。

所以你换句话说建议是什么来调整“功能调整”通过选择对功能调整算法的最佳参数。这自然会带来另一层嵌套重采样。

但是,如果这是必要的话,这是值得商榷的,因为特征选择的选择通常取决于您的可用资源和其他情况。

你可以做的是测试不同特征选择方法:

inner = makeResampleDesc("CV", iter = 2) 
outer = makeResampleDesc("Subsample", iter = 3) 
settings = list(random1 = makeFeatSelControlRandom(maxit = 15), random2 = makeFeatSelControlRandom(maxit = 20)) 
lrns = Map(function(x, xn) { 
    lrn = makeFeatSelWrapper(learner = "regr.lm", control = x, resampling = inner) 
    lrn$id = paste0(lrn$id, ".", xn) 
    lrn 
}, x = settings, xn = names(settings)) 
benchmark(lrns, bh.task, outer, list(mse, timeboth)) 
+0

你好,谢谢你的回答。也许我没有把自己弄清楚(我现在可以看到事实确实如此)。我想问的是,是否可以调整'FeatSelWrapper' **以及学习者超参数,就像你可以用'FilterWrapper'一样做到这一点(这样你就可以避免嵌套CV并保持标准嵌套CV) 。 AFAIK,目前这是不可能的,但也许我错了,或者有一个特殊的原因,为什么我不知道这是不可能的。我编辑了问题的代码,使其更清楚,请查看。 – Matek

+0

嗯,我刚刚意识到你不能真的做嵌套嵌套交叉验证,因为你不能用'TuneWrapper'封装一个'FeatSelWrapper'(或者反过来)。 – Matek