【问题标题】:Set hyperparameters to a learner in mlr after parameter tuning参数调整后在 mlr 中为学习器设置超参数
【发布时间】:2018-12-14 21:28:28
【问题描述】:

我正在使用 mlr 包在 R 中构建分类任务,以调整我正在使用验证集的超参数,其中一个参数是使用特征选择(chi.square)根据重要性使用的变量百分比方法)

lrn = makeFilterWrapper(learner = "classif.xgboost", fw.method = "chi.squared")
params <- makeParamSet(
     makeDiscreteParam("booster",values = c("gbtree","dart")),
     makeDiscreteParam("nrounds", values = 1000, tunable = F),
     makeDiscreteParam("eta", values = c(0.1,0.05,0.2)),
     makeIntegerParam("max_depth",lower = 3L,upper = 10L),
     makeNumericParam("min_child_weight",lower = 1L,upper = 10L),
     makeNumericParam("subsample",lower = 0.5,upper = 1),
     makeNumericParam("colsample_bytree",lower = 0.5,upper = 1),
     makeDiscreteParam("fw.perc", values = seq(0.2, 1, 0.05)))
rdesc = makeResampleDesc("CV", iters = 5)
ctrl <- makeTuneControlRandom(maxit = 1L)
res = tuneParams(lrn, task = valTask2016, resampling = rdesc, par.set = params, control = ctrl)

我不确定是否需要在这里进行 5 折交叉验证,但变量 res 提供了我需要的所有参数,包括 fw.perc,它将按降序修剪我的变量选择重要性。

我的问题是,我如何使用这些参数再次使用重采样(这次使用Subsampling)但这次是在训练数据上?这是我得到的:

rdesc = makeResampleDesc("Subsample", iters = 5, split = 0.8)
lrn = setHyperPars(makeLearner("classif.xgboost"), par.vals = res$x)
r = resample(lrn, trainTask2016, rdesc, measures = list(mmce, fpr, fnr, timetrain))

在这种情况下,valTask2016 是我用于验证参数的分类任务。我使用createDummyFeatures 进行 XGBoost 所需的 one-hot 编码。

这是我得到的错误:

setHyperPars2.Learner(learner, insert(par.vals, args)) 中的错误: classif.xgboost:在没有可用描述对象的情况下设置参数 fw.perc! 您是否指的是这些超参数之一: booster eta alpha

【问题讨论】:

    标签: r xgboost mlr


    【解决方案1】:

    我相信您收到此错误的原因是第二个学习者是“简单”的 xgboost 学习者,而不是像您的第一个学习者一样被过滤器包裹的 xgboost 学习者(learnermakeFilterWrapper 返回一个学习者)。

    所以,你有两个选择:

    1. 您在第二次训练中定义了一个新的 paramSet,在这里您只“复制”了 res$x 中引用 xgboost 的部分,即没有 fw.perc
    2. 您使用相同的过滤器包装您的第二个 xgboost 学习器

    我希望这是有道理的。

    编辑:这适用于我使用泰坦尼克数据集的第二个选项:

    library(mlr)
    library(dplyr)
    library(titanic)
    
    sample <- sample.int(n = nrow(titanic_train), size = floor(.7*nrow(titanic_train)), replace = F)
    train <- titanic_train[sample, ] %>% select(Pclass, Sex, Age, SibSp, Fare, Survived) %>% mutate(Sex = ifelse(Sex == 'male', 0, 1))
    
    lrn = makeFilterWrapper(learner = "classif.xgboost", fw.method = "chi.squared")
    
    params <- makeParamSet(
      makeDiscreteParam("booster",values = c("gbtree","dart")),
      makeDiscreteParam("nrounds", values = 1000, tunable = F),
      makeDiscreteParam("eta", values = c(0.1,0.05,0.2)),
      makeIntegerParam("max_depth",lower = 3L,upper = 10L),
      makeNumericParam("min_child_weight",lower = 1L,upper = 10L),
      makeNumericParam("subsample",lower = 0.5,upper = 1),
      makeNumericParam("colsample_bytree",lower = 0.5,upper = 1),
      makeDiscreteParam("fw.perc", values = seq(0.2, 1, 0.05)))
    
    classif.task <- mlr::makeClassifTask(data = train,
                                     target = "Survived",
                                     positive = "1")
    
    rdesc = makeResampleDesc("CV", iters = 3)
    
    ctrl <- makeTuneControlRandom(maxit = 2L)
    
    res = tuneParams(lrn, task = classif.task, resampling = rdesc, par.set = params, control = ctrl)
    
    ##########################
    
    test <- titanic_train[-sample,] %>% select(Pclass, Sex, Age, SibSp, Fare, Survived) %>% mutate(Sex = ifelse(Sex == 'male', 0, 1))
    
    lrn2 = setHyperPars(makeFilterWrapper(learner = "classif.xgboost", fw.method = "chi.squared"), par.vals = res$x)
    
    classif.task2 <- mlr::makeClassifTask(data = test,
                                     target = "Survived",
                                     positive = "1")
    
    rdesc = makeResampleDesc("CV", iters = 3)
    r = resample(learner = lrn2, task = classif.task2, resampling = rdesc, show.info = T, models = TRUE)
    

    【讨论】:

    • 嗨,我尝试使用过滤器包装器,但它似乎没有得到正确的 fw.perc 值:&gt; lrn = makeFilterWrapper(learner = "classif.xgboost", fw.method = "chi.squared", par.vals = res$x) &gt; rdesc = makeResampleDesc("CV", iters = 10) &gt; r = resample(learner = lrn, task = trainTask2016, resampling = rdesc, show.info = T, models = TRUE) 我收到此错误:checkFilterArguments 中的错误(perc,abs,阈值) : 'perc'、'abs' 或 'threshold' 中的至少一个不能为 NULL
    • 尝试先用 FilterWrapper 包裹学习者,然后调用setHyperPars(lrn, par.vals = res$)。您不能在makeFilterWrapper() 中为"classif.xgboost" 设置参数。但看起来您想要获得的内容可以通过makeTuneWrapper() 轻松完成。查看有关嵌套重采样的教程:mlr-org.github.io/mlr/articles/tutorial/devel/…
    猜你喜欢
    • 2020-04-14
    • 2020-04-15
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 2016-01-17
    • 2022-04-27
    • 2018-12-07
    • 2011-02-15
    相关资源
    最近更新 更多