From d329bf60658342a5deefa9fd86a1659ace71e1e6 Mon Sep 17 00:00:00 2001 From: Marc Becker <33069354+be-marc@users.noreply.github.com> Date: Mon, 30 Mar 2020 17:31:52 +0200 Subject: [PATCH] Add Parameter test and missing parameters (#3) --- .github/workflows/paramtest.yml | 97 +++++++++++++++++++ R/LearnerClassifGAMBoost.R | 16 +-- R/LearnerClassifGLMBoost.R | 6 +- R/LearnerRegrGAMBoost.R | 5 +- R/LearnerRegrGLMBoost.R | 6 +- README.md | 1 + inst/paramtest/helper.R | 3 + .../test_paramtest_classif_gamboost.R | 29 ++++++ .../test_paramtest_classif_glmboost.R | 29 ++++++ inst/paramtest/test_paramtest_regr_gamboost.R | 29 ++++++ inst/paramtest/test_paramtest_regr_glmboost.R | 29 ++++++ 11 files changed, 241 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/paramtest.yml create mode 100644 inst/paramtest/helper.R create mode 100644 inst/paramtest/test_paramtest_classif_gamboost.R create mode 100644 inst/paramtest/test_paramtest_classif_glmboost.R create mode 100644 inst/paramtest/test_paramtest_regr_gamboost.R create mode 100644 inst/paramtest/test_paramtest_regr_glmboost.R diff --git a/.github/workflows/paramtest.yml b/.github/workflows/paramtest.yml new file mode 100644 index 0000000..9de368b --- /dev/null +++ b/.github/workflows/paramtest.yml @@ -0,0 +1,97 @@ +on: + push: + pull_request: + # for now, CRON jobs only run on the default branch of the repo (i.e. usually on master) + schedule: + # * is a special character in YAML so you have to quote this string + - cron: "0 4 * * *" + +name: Parameter Check + +jobs: + R-CMD-check: + runs-on: ${{ matrix.config.os }} + + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + + strategy: + fail-fast: false + matrix: + config: + - { os: ubuntu-latest, r: "release" } + + env: + # otherwise remotes::fun() errors cause the build to fail. Example: Unavailability of binaries + R_REMOTES_NO_ERRORS_FROM_WARNINGS: true + CRAN: ${{ matrix.config.cran }} + # we are not allowed to write to ~/.ccache on GH Actions + # setting some ccache options + CCACHE_BASEDIR: ${{ GITHUB.WORKSPACE }} + CCACHE_DIR: ${{ GITHUB.WORKSPACE }}/.ccache + CCACHE_NOHASHDIR: true + CCACHE_SLOPPINESS: include_file_ctime + # make sure to run `tic::use_ghactions_deploy()` to set up deployment + id_rsa: ${{ secrets.id_rsa }} + # prevent rgl issues because no X11 display is available + RGL_USE_NULL: true + + steps: + - uses: actions/checkout@v2 + + - uses: r-lib/actions/setup-r@master + with: + r-version: ${{ matrix.config.r }} + Ncpus: 4 + + # set date/week for use in cache creation + # https://github.community/t5/GitHub-Actions/How-to-set-and-access-a-Workflow-variable/m-p/42970 + # - cache R packages daily + # - cache ccache weekly -> 'ccache' helps rebuilding the package cache faster + - name: "[Cache] Prepare daily timestamp for cache" + if: runner.os != 'Windows' + id: date + run: echo "::set-output name=date::$(date '+%d-%m')" + + - name: "[Cache] Prepare weekly timestamp for cache" + if: runner.os != 'Windows' + id: datew + run: echo "::set-output name=datew::$(date '+%Y-%V')" + + - name: "[Cache] Cache R packages" + if: runner.os != 'Windows' + uses: pat-s/always-upload-cache@v1.1.4 + with: + path: ${{ env.R_LIBS_USER }} + key: ${{ runner.os }}-r-${{ matrix.config.r }}-${{steps.date.outputs.date}}-1 + restore-keys: ${{ runner.os }}-r-${{ matrix.config.r }}-${{steps.date.outputs.date}}-1 + + - name: "[Cache] Cache ccache" + if: runner.os != 'Windows' + uses: pat-s/always-upload-cache@v1.1.4 + with: + path: ${{ env.CCACHE_DIR}} + key: ${{ runner.os }}-r-${{ matrix.config.r }}-ccache-${{steps.datew.outputs.datew}} + restore-keys: ${{ runner.os }}-r-${{ matrix.config.r }}-ccache-${{steps.datew.outputs.datew}} + + # install ccache and write config file + - name: "[Linux] ccache" + if: runner.os == 'Linux' + run: | + sudo apt install ccache libcurl4-openssl-dev + mkdir -p ~/.R && echo -e 'CXX_STD = CXX14\n\nCC=ccache gcc -std=gnu99\nCXX=ccache g++\nCXX11=ccache g++ -std=gnu99\nCXX14=ccache g++ -std=gnu99\nC11=ccache g++\nC14=ccache g++\nFC=ccache gfortran\nF77=ccache gfortran' > $HOME/.R/Makevars + + # for some strange Windows reason this step and the next one need to be decoupled + - name: "[Stage] Prepare" + run: | + Rscript -e "if (!requireNamespace('remotes')) install.packages('remotes', type = 'source')" + Rscript -e "if (getRversion() < '3.2' && !requireNamespace('curl')) install.packages('curl', type = 'source')" + + - name: "[Stage] Install" + if: matrix.config.os != 'macOS-latest' || matrix.config.r != 'devel' + run: Rscript -e "remotes::install_github('ropensci/tic')" -e "print(tic::dsl_load())" -e "tic::prepare_all_stages()" -e "tic::before_install()" -e "tic::install()" + + - name: "[Stage] Parameter test" + run: | + R CMD INSTALL . + Rscript -e "remotes::install_github('mlr-org/mlr3@paramtest')" + Rscript -e "testthat::test_dir(system.file('paramtest', package = 'mlr3learners.mboost'))" diff --git a/R/LearnerClassifGAMBoost.R b/R/LearnerClassifGAMBoost.R index abb7614..0155981 100644 --- a/R/LearnerClassifGAMBoost.R +++ b/R/LearnerClassifGAMBoost.R @@ -39,7 +39,10 @@ LearnerClassifGAMBoost = R6Class("LearnerClassifGAMBoost", ParamDbl$new(id = "nu", default = 0.1, tags = "train"), ParamFct$new(id = "risk", default = "inbag", levels = c("inbag", "oobag", "none"), tags = "train"), - ParamUty$new(id = "oobweights", default = NULL, tags = "train") + ParamUty$new(id = "oobweights", default = NULL, tags = "train"), + ParamLgl$new(id = "trace", default = FALSE, tags = "train"), + ParamUty$new(id = "stopintern", default = FALSE, tags = "train"), + ParamUty$new(id = "na.action", default = na.omit, tags = "train") ) ) ps$add_dep("type", "family", CondEqual$new("Binomial")) @@ -84,7 +87,7 @@ LearnerClassifGAMBoost = R6Class("LearnerClassifGAMBoost", } pars_gamboost$family = switch(pars_gamboost$family, - Binomial = invoke(mboost::Binomial, .args = pars_binomial), + Binomial = mlr3misc::invoke(mboost::Binomial, .args = pars_binomial), AdaExp = mboost::AdaExp(), AUC = mboost::AUC()) @@ -94,12 +97,12 @@ LearnerClassifGAMBoost = R6Class("LearnerClassifGAMBoost", data[[task$target_names]] = factor(data[[task$target_names]], levs) } - ctrl = invoke(mboost::boost_control, .args = pars_boost) + ctrl = mlr3misc::invoke(mboost::boost_control, .args = pars_boost) # baselearner argument requires attached mboost package withr::with_package("mboost", { - invoke(mboost::gamboost, formula = f, data = data, control = ctrl, - .args = pars_gamboost) + mlr3misc::invoke(mboost::gamboost, formula = f, data = data, + control = ctrl, .args = pars_gamboost) }) }, @@ -116,7 +119,8 @@ LearnerClassifGAMBoost = R6Class("LearnerClassifGAMBoost", p = invoke(predict, self$model, newdata = newdata, type = "class") PredictionClassif$new(task = task, response = p) } else { - p = invoke(predict, self$model, newdata = newdata, type = "response") + p = mlr3misc::invoke(predict, self$model, newdata = newdata, + type = "response") p = matrix(c(p, 1 - p), ncol = 2L, nrow = length(p)) colnames(p) = task$class_names PredictionClassif$new(task = task, prob = p) diff --git a/R/LearnerClassifGLMBoost.R b/R/LearnerClassifGLMBoost.R index b584cea..ba40ce3 100644 --- a/R/LearnerClassifGLMBoost.R +++ b/R/LearnerClassifGLMBoost.R @@ -37,7 +37,11 @@ LearnerClassifGLMBoost = R6Class("LearnerClassifGLMBoost", ParamDbl$new(id = "nu", default = 0.1, tags = "train"), ParamFct$new(id = "risk", default = "inbag", levels = c("inbag", "oobag", "none"), tags = "train"), - ParamUty$new(id = "oobweights", default = NULL, tags = "train") + ParamUty$new(id = "oobweights", default = NULL, tags = "train"), + ParamLgl$new(id = "trace", default = FALSE, tags = "train"), + ParamUty$new(id = "stopintern", default = FALSE, tags = "train"), + ParamUty$new(id = "na.action", default = na.omit, tags = "train"), + ParamUty$new(id = "contrasts.arg", tags = "train") ) ) ps$add_dep("link", "family", CondEqual$new("Binomial")) diff --git a/R/LearnerRegrGAMBoost.R b/R/LearnerRegrGAMBoost.R index 8b9070c..e35805e 100644 --- a/R/LearnerRegrGAMBoost.R +++ b/R/LearnerRegrGAMBoost.R @@ -38,7 +38,10 @@ LearnerRegrGAMBoost = R6Class("LearnerRegrGAMBoost", inherit = LearnerRegr, ParamDbl$new(id = "nu", default = 0.1, tags = "train"), ParamFct$new(id = "risk", default = "inbag", levels = c("inbag", "oobag", "none"), tags = "train"), - ParamUty$new(id = "oobweights", default = NULL, tags = "train") + ParamUty$new(id = "oobweights", default = NULL, tags = "train"), + ParamLgl$new(id = "trace", default = FALSE, tags = "train"), + ParamUty$new(id = "stopintern", default = FALSE, tags = "train"), + ParamUty$new(id = "na.action", default = na.omit, tags = "train") ) ) ps$add_dep("oobweights", "risk", CondEqual$new("oobag")) diff --git a/R/LearnerRegrGLMBoost.R b/R/LearnerRegrGLMBoost.R index 2fe1731..5e3128b 100644 --- a/R/LearnerRegrGLMBoost.R +++ b/R/LearnerRegrGLMBoost.R @@ -36,7 +36,11 @@ LearnerRegrGLMBoost = R6Class("LearnerRegrGLMBoost", inherit = LearnerRegr, ParamDbl$new(id = "nu", default = 0.1, tags = "train"), ParamFct$new(id = "risk", default = "inbag", levels = c("inbag", "oobag", "none"), tags = "train"), - ParamUty$new(id = "oobweights", default = NULL, tags = "train") + ParamUty$new(id = "oobweights", default = NULL, tags = "train"), + ParamLgl$new(id = "trace", default = FALSE, tags = "train"), + ParamUty$new(id = "stopintern", default = FALSE, tags = "train"), + ParamUty$new(id = "na.action", default = na.omit, tags = "train"), + ParamUty$new(id = "contrasts.arg", tags = "train") ) ) ps$add_dep("oobweights", "risk", CondEqual$new("oobag")) diff --git a/README.md b/README.md index 69c8be5..2c21cd5 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![R CMD Check via {tic}](https://github.com/mlr3learners/mlr3learners.mboost/workflows/R%20CMD%20Check%20via%20{tic}/badge.svg?branch=master)](https://github.com/mlr3learners/mlr3learners.mboost/actions) +![Parameter Check](https://github.com/mlr3learners/mlr3learners.mboost/workflows/Parameter%20Check/badge.svg?branch=master) [![codecov](https://codecov.io/gh/mlr3learners/mlr3learners.mboost/branch/master/graph/badge.svg)](https://codecov.io/gh/mlr3learners/mlr3learners.mboost) [![StackOverflow](https://img.shields.io/badge/stackoverflow-mlr3-orange.svg)](https://stackoverflow.com/questions/tagged/mlr3) diff --git a/inst/paramtest/helper.R b/inst/paramtest/helper.R new file mode 100644 index 0000000..c45e08b --- /dev/null +++ b/inst/paramtest/helper.R @@ -0,0 +1,3 @@ +library(mlr3) +lapply(list.files(system.file("testthat", package = "mlr3"), + pattern = "helper_autotest", full.names = TRUE), source) diff --git a/inst/paramtest/test_paramtest_classif_gamboost.R b/inst/paramtest/test_paramtest_classif_gamboost.R new file mode 100644 index 0000000..bcfb9f8 --- /dev/null +++ b/inst/paramtest/test_paramtest_classif_gamboost.R @@ -0,0 +1,29 @@ +library(mlr3learners.mboost) + +test_that("classif.gamboost", { + learner = lrn("classif.gamboost") + fun = mboost::gamboost + exclude = c( + "formula", # handled via mlr3 + "data", # handled via mlr3 + "weights", # handled via mlr3 + "control", # handled to mboost::boost_control + "..." # not used + ) + + ParamTest = run_paramtest(learner, fun, exclude) + expect_true(ParamTest, info = paste0("\nMissing parameters:\n", + paste0("- '", ParamTestresult$missing,"'", collapse = "\n"))) +}) + +test_that("classif.gamboost_boost_control", { + learner = lrn("classif.gamboost") + fun = mboost::boost_control + exclude = c( + "center" # deprecated + ) + + ParamTest = run_paramtest(learner, fun, exclude) + expect_true(ParamTest, info = paste0("\nMissing parameters:\n", + paste0("- '", ParamTest$missing,"'", collapse = "\n"))) +}) diff --git a/inst/paramtest/test_paramtest_classif_glmboost.R b/inst/paramtest/test_paramtest_classif_glmboost.R new file mode 100644 index 0000000..dbb3c65 --- /dev/null +++ b/inst/paramtest/test_paramtest_classif_glmboost.R @@ -0,0 +1,29 @@ +library(mlr3learners.mboost) + +test_that("classif.glmboost", { + learner = lrn("classif.glmboost") + fun = mboost:::glmboost.formula + exclude = c( + "formula", # handled via mlr3 + "data", # handled via mlr3 + "weights", # handled via mlr3 + "control", # handled to mboost::boost_control + "..." # not used + ) + + ParamTest = run_paramtest(learner, fun, exclude) + expect_true(ParamTest, info = paste0("\nMissing parameters:\n", + paste0("- '", ParamTest$missing, "'", collapse = "\n"))) +}) + +test_that("classif.glmboost_boost_control", { + learner = lrn("classif.glmboost") + fun = mboost::boost_control + exclude = c( + "center" # deprecated + ) + + ParamTest = run_paramtest(learner, fun, exclude) + expect_true(ParamTest, info = paste0("\nMissing parameters:\n", + paste0("- '", ParamTest$missing, "'", collapse = "\n"))) +}) diff --git a/inst/paramtest/test_paramtest_regr_gamboost.R b/inst/paramtest/test_paramtest_regr_gamboost.R new file mode 100644 index 0000000..e391c3a --- /dev/null +++ b/inst/paramtest/test_paramtest_regr_gamboost.R @@ -0,0 +1,29 @@ +library(mlr3learners.mboost) + +test_that("regr.gamboost", { + learner = lrn("regr.gamboost") + fun = mboost::gamboost + exclude = c( + "formula", # handled via mlr3 + "data", # handled via mlr3 + "weights", # handled via mlr3 + "control", # handled to mboost::boost_control + "..." # not used + ) + + ParamTest = run_paramtest(learner, fun, exclude) + expect_true(ParamTest, info = paste0("\nMissing parameters:\n", + paste0("- '", ParamTest$missing, "'", collapse = "\n"))) +}) + +test_that("regr.gamboost_boost_control", { + learner = lrn("regr.gamboost") + fun = mboost::boost_control + exclude = c( + "center" # deprecated + ) + + ParamTest = run_paramtest(learner, fun, exclude) + expect_true(ParamTest, info = paste0("\nMissing parameters:\n", + paste0("- '", ParamTest$missing, "'", collapse = "\n"))) +}) diff --git a/inst/paramtest/test_paramtest_regr_glmboost.R b/inst/paramtest/test_paramtest_regr_glmboost.R new file mode 100644 index 0000000..02af01a --- /dev/null +++ b/inst/paramtest/test_paramtest_regr_glmboost.R @@ -0,0 +1,29 @@ +library(mlr3learners.mboost) + +test_that("regr.glmboost", { + learner = lrn("regr.glmboost") + fun = mboost:::glmboost.formula + exclude = c( + "formula", # handled via mlr3 + "data", # handled via mlr3 + "weights", # handled via mlr3 + "control", # handled to mboost::boost_control + "..." # not used + ) + + ParamTest = run_paramtest(learner, fun, exclude) + expect_true(ParamTest, info = paste0("\nMissing parameters:\n", + paste0("- '", ParamTest$missing, "'", collapse = "\n"))) +}) + +test_that("regr.glmboost_boost_control", { + learner = lrn("regr.glmboost") + fun = mboost::boost_control + exclude = c( + "center" # deprecated + ) + + ParamTest = run_paramtest(learner, fun, exclude) + expect_true(ParamTest, info = paste0("\nMissing parameters:\n", + paste0("- '", ParamTest$missing, "'", collapse = "\n"))) +})