From 364be8468046f830a76b1a11c857af0dcaf1a4f6 Mon Sep 17 00:00:00 2001 From: awinterstetter Date: Mon, 17 Nov 2025 10:10:08 +0100 Subject: [PATCH] implementation regr.lagp --- R/learner_laGP_regr_laGP.R | 83 ++++++++++ man/mlr_learners_regr.laGP.Rd | 143 ++++++++++++++++++ tests/testthat/test_laGP_regr_laGP.R | 9 ++ .../testthat/test_paramtest_laGP_regr_laGP.R | 12 ++ 4 files changed, 247 insertions(+) create mode 100644 R/learner_laGP_regr_laGP.R create mode 100644 man/mlr_learners_regr.laGP.Rd create mode 100644 tests/testthat/test_laGP_regr_laGP.R create mode 100644 tests/testthat/test_paramtest_laGP_regr_laGP.R diff --git a/R/learner_laGP_regr_laGP.R b/R/learner_laGP_regr_laGP.R new file mode 100644 index 000000000..be008eaed --- /dev/null +++ b/R/learner_laGP_regr_laGP.R @@ -0,0 +1,83 @@ +#' @title Regression Local Approximate Gaussian Process Learner +#' @author awinterstetter +#' @name mlr_learners_regr.laGP +#' +#' @description +#' Local approximate Gaussian process for regression. +#' Calls [laGP::aGP()] from \CRANpkg{laGP}. +#' Parameters `start` and `end` tune the initial and maximum neighborhood sizes +#' used for the local GP fit, `d` can fix the length-scale parameters, `g` +#' configures the nugget/regularization term, and `method` selects the search +#' heuristic (`alc`, `alcray`, `efi`, `mspe`, `nn`). Arguments `close` and +#' `numrays` further refine the ray-based search used by `method = "alcray"`, +#' while `verb` controls the output verbosity. +#' +#' @templateVar id regr.laGP +#' @template learner +#' +#' @export +#' @template seealso_learner +#' @template example +LearnerRegrLaGP = R6Class("LearnerRegrLaGP", + inherit = LearnerRegr, + + public = list( + + #' @description + #' Creates a new instance of this [R6][R6::R6Class] class. + initialize = function() { + + ps = ps( + start = p_int(default = 6L, lower = 6L, tags = "predict"), + end = p_int(default = 50L, lower = 6L, tags = "predict"), # >start? check with Marc + d = p_uty(default = NULL, special_vals = list(NULL), tags = "predict"), + g = p_uty(default = 1 / 10000, tags = "predict"), + method = p_fct(default = "alc", + levels = c("alc", "alcray", "efi", "mspe", "nn"), + tags = "predict"), + close = p_int(lower = 0L, tags = "predict"), + numrays = p_int(lower = 0L, depends = method == "alcray", tags = "predict"), + verb = p_dbl(default = 0, tags = "predict") + ) + + super$initialize( + id = "regr.laGP", + packages = c("mlr3extralearners", "laGP"), + feature_types = c("integer", "numeric"), + predict_types = c("response", "se"), + param_set = ps, + label = "Local Approximate Gaussian Process", + man = "mlr3extralearners::mlr_learners_regr.laGP" + ) + } + ), + + private = list( + .train = function(task) { + list( + X = as_numeric_matrix(task$data(cols = task$feature_names)), + Z = task$truth() + ) + }, + + .predict = function(task) { + pars = self$param_set$get_values(tags = "predict") + pred = invoke( + laGP::aGP, + X = self$model$X, + Z = self$model$Z, + XX = as_numeric_matrix(ordered_features(task, self)), + Xi.ret = FALSE, + .args = pars + ) + + if (self$predict_type == "response") { + list(response = as.numeric(pred$mean)) + } else { + list(response = as.numeric(pred$mean), se = sqrt(pred$var)) + } + } + ) +) + +.extralrns_dict$add("regr.laGP", LearnerRegrLaGP) diff --git a/man/mlr_learners_regr.laGP.Rd b/man/mlr_learners_regr.laGP.Rd new file mode 100644 index 000000000..fce19b0a1 --- /dev/null +++ b/man/mlr_learners_regr.laGP.Rd @@ -0,0 +1,143 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/learner_laGP_regr_laGP.R +\name{mlr_learners_regr.laGP} +\alias{mlr_learners_regr.laGP} +\alias{LearnerRegrLaGP} +\title{Regression Local Approximate Gaussian Process Learner} +\description{ +Local approximate Gaussian process for regression. +Calls \code{\link[laGP:aGP]{laGP::aGP()}} from \CRANpkg{laGP}. +Parameters \code{start} and \code{end} tune the initial and maximum neighborhood sizes +used for the local GP fit, \code{d} can fix the length-scale parameters, \code{g} +configures the nugget/regularization term, and \code{method} selects the search +heuristic (\code{alc}, \code{alcray}, \code{efi}, \code{mspe}, \code{nn}). Arguments \code{close} and +\code{numrays} further refine the ray-based search used by \code{method = "alcray"}, +while \code{verb} controls the output verbosity. +} +\section{Dictionary}{ + +This \link[mlr3:Learner]{Learner} can be instantiated via \link[mlr3:mlr_sugar]{lrn()}: + +\if{html}{\out{
}}\preformatted{lrn("regr.laGP") +}\if{html}{\out{
}} +} + +\section{Meta Information}{ + +\itemize{ +\item Task type: \dQuote{regr} +\item Predict Types: \dQuote{response}, \dQuote{se} +\item Feature Types: \dQuote{integer}, \dQuote{numeric} +\item Required Packages: \CRANpkg{mlr3}, \CRANpkg{mlr3extralearners}, \CRANpkg{laGP} +} +} + +\section{Parameters}{ +\tabular{lllll}{ + Id \tab Type \tab Default \tab Levels \tab Range \cr + start \tab integer \tab 6 \tab \tab \eqn{[6, \infty)}{[6, Inf)} \cr + end \tab integer \tab 50 \tab \tab \eqn{[6, \infty)}{[6, Inf)} \cr + d \tab untyped \tab NULL \tab \tab - \cr + g \tab untyped \tab 1/10000 \tab \tab - \cr + method \tab character \tab alc \tab alc, alcray, efi, mspe, nn \tab - \cr + close \tab integer \tab - \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr + numrays \tab integer \tab - \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr + verb \tab numeric \tab 0 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr +} +} + +\examples{ +\dontshow{if (learner_is_runnable("regr.laGP")) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +# Define the Learner +learner = lrn("regr.laGP") +print(learner) + +# Define a Task +task = tsk("mtcars") + +# Create train and test set +ids = partition(task) + +# Train the learner on the training ids +learner$train(task, row_ids = ids$train) + +print(learner$model) + + +# Make predictions for the test rows +predictions = learner$predict(task, row_ids = ids$test) + +# Score the predictions +predictions$score() +\dontshow{\}) # examplesIf} +} +\seealso{ +\itemize{ +\item \link[mlr3misc:Dictionary]{Dictionary} of \link[mlr3:Learner]{Learners}: \link[mlr3:mlr_learners]{mlr3::mlr_learners}. +\item \code{as.data.table(mlr_learners)} for a table of available \link[mlr3:Learner]{Learners} in the running session (depending on the loaded packages). +\item Chapter in the \href{https://mlr3book.mlr-org.com/}{mlr3book}: \url{https://mlr3book.mlr-org.com/basics.html#learners} +\item \CRANpkg{mlr3learners} for a selection of recommended learners. +\item \CRANpkg{mlr3cluster} for unsupervised clustering learners. +\item \CRANpkg{mlr3pipelines} to combine learners with pre- and postprocessing steps. +\item \CRANpkg{mlr3tuning} for tuning of hyperparameters, \CRANpkg{mlr3tuningspaces} for established default tuning spaces. +} +} +\author{ +awinterstetter +} +\section{Super classes}{ +\code{\link[mlr3:Learner]{mlr3::Learner}} -> \code{\link[mlr3:LearnerRegr]{mlr3::LearnerRegr}} -> \code{LearnerRegrLaGP} +} +\section{Methods}{ +\subsection{Public methods}{ +\itemize{ +\item \href{#method-LearnerRegrLaGP-new}{\code{LearnerRegrLaGP$new()}} +\item \href{#method-LearnerRegrLaGP-clone}{\code{LearnerRegrLaGP$clone()}} +} +} +\if{html}{\out{ +
Inherited methods + +
+}} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-LearnerRegrLaGP-new}{}}} +\subsection{Method \code{new()}}{ +Creates a new instance of this \link[R6:R6Class]{R6} class. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{LearnerRegrLaGP$new()}\if{html}{\out{
}} +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-LearnerRegrLaGP-clone}{}}} +\subsection{Method \code{clone()}}{ +The objects of this class are cloneable with this method. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{LearnerRegrLaGP$clone(deep = FALSE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{deep}}{Whether to make a deep clone.} +} +\if{html}{\out{
}} +} +} +} diff --git a/tests/testthat/test_laGP_regr_laGP.R b/tests/testthat/test_laGP_regr_laGP.R new file mode 100644 index 000000000..625a24c6d --- /dev/null +++ b/tests/testthat/test_laGP_regr_laGP.R @@ -0,0 +1,9 @@ +skip_if_not_installed("laGP") + +test_that("autotest", { + learner = lrn("regr.laGP", end = 15) # I need to use sensible values here -> check with Marc?; with 15 it works + browser() + expect_learner(learner) + result = run_autotest(learner) + expect_true(result) +}) diff --git a/tests/testthat/test_paramtest_laGP_regr_laGP.R b/tests/testthat/test_paramtest_laGP_regr_laGP.R new file mode 100644 index 000000000..1b07501ff --- /dev/null +++ b/tests/testthat/test_paramtest_laGP_regr_laGP.R @@ -0,0 +1,12 @@ +skip_if_not_installed("laGP") + +test_that("paramtest regr.laGP predict", { + learner = lrn("regr.laGP") + fun = laGP::aGP + + tested = c("start", "end", "d", "g", "method", "close", "numrays", "verb") + exclude = setdiff(names(formals(fun)), tested) + + paramtest = run_paramtest(learner, fun, exclude, tag = "predict") + expect_paramtest(paramtest) +})