diff --git a/NAMESPACE b/NAMESPACE index 34bc0a72f..23e97a1ad 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -49,6 +49,7 @@ export(LearnerClassifLSSVM) export(LearnerClassifLiblineaR) export(LearnerClassifLightGBM) export(LearnerClassifLogistic) +export(LearnerClassifLvq1) export(LearnerClassifMda) export(LearnerClassifMdeb) export(LearnerClassifMob) diff --git a/NEWS.md b/NEWS.md index 66926c61b..44a1d0923 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,9 +1,10 @@ # mlr3extralearners (development version) + ## New Features -* New Learners: - - `LearnerSurvDNN` +- `LearnerClassifLvq1` +- `LearnerSurvDNN` ## Other diff --git a/R/learner_class_classif_lvq1.R b/R/learner_class_classif_lvq1.R new file mode 100644 index 000000000..b9f8712bb --- /dev/null +++ b/R/learner_class_classif_lvq1.R @@ -0,0 +1,82 @@ +#' @title Classification Learning Vector Quantization 1 +#' @author awinterstetter +#' @name mlr_learners_classif.lvq1 +#' +#' @description +#' Learning Vector Quantization 1. +#' Calls [class::lvqinit()], [class::lvq1()], and [class::lvqtest()] from \CRANpkg{class}. +#' +#' @note +#' The learner does not work on tasks with two target groups and one feature. +#' +#' @templateVar id classif.lvq1 +#' @template learner +#' +#' @references +#' `r format_bib("kohonen_1990", "kohonen_1995")` +#' +#' @template seealso_learner +#' @template example +#' @export +LearnerClassifLvq1 = R6Class("LearnerClassifLvq1", + inherit = LearnerClassif, + public = list( + #' @description + #' Creates a new instance of this [R6][R6::R6Class] class. + initialize = function() { + param_set = ps( + size = p_int(default = NULL, lower = 1L, special_vals = list(NULL), tags = "train"), + prior = p_uty(default = NULL, tags = "train"), + k = p_int(default = 5L, lower = 1L, tags = "train"), + niter = p_int(default = NULL, lower = 1L, special_vals = list(NULL), tags = "train"), + alpha = p_dbl(default = 0.03, lower = 0, tags = "train") + ) + + super$initialize( + id = "classif.lvq1", + packages = "class", + feature_types = c("integer", "numeric"), + predict_types = "response", + param_set = param_set, + properties = c("twoclass", "multiclass"), + man = "mlr3extralearners::mlr_learners_classif.lvq1", + label = "Learning Vector Quantization 1" + ) + } + ), + private = list( + .train = function(task) { + pars = self$param_set$get_values(tags = "train") + + d = as.matrix(task$data(cols = task$feature_names)) + target = task$truth() + + cdbk_pars = pars[names(pars) %in% c("size", "prior", "k")] + cdbk_args = c(list(x = d, cl = target), cdbk_pars) + codebk = invoke( + class::lvqinit, + .args = cdbk_args + ) + + lvq_pars = pars[names(pars) %in% c("niter", "alpha")] + lvq_args = c(list(x = d, cl = target, codebk = codebk), lvq_pars) + + invoke( + class::lvq1, + .args = lvq_args + ) + + }, + .predict = function(task) { + newdata = as.matrix(ordered_features(task, self)) + pred = invoke( + class::lvqtest, + codebk = self$model, + test = newdata + ) + list(response = pred) + } + ) +) + +.extralrns_dict$add("classif.lvq1", LearnerClassifLvq1) diff --git a/man/mlr_learners_classif.bayes_net.Rd b/man/mlr_learners_classif.bayes_net.Rd index 0977c86d1..00ae73073 100644 --- a/man/mlr_learners_classif.bayes_net.Rd +++ b/man/mlr_learners_classif.bayes_net.Rd @@ -77,20 +77,8 @@ This \link[mlr3:Learner]{Learner} can be instantiated via \link[mlr3:mlr_sugar]{ } \section{Parameters}{ -\tabular{lllll}{ - Id \tab Type \tab Default \tab Levels \tab Range \cr - subset \tab untyped \tab - \tab \tab - \cr - na.action \tab untyped \tab - \tab \tab - \cr - D \tab logical \tab - \tab TRUE, FALSE \tab - \cr - B \tab untyped \tab - \tab \tab - \cr - Q \tab character \tab - \tab global.K2, global.HillClimber, global.SimulatedAnnealing, global.TabuSearch, global.TAN, local.K2, local.HillClimber, local.LAGDHillClimber, local.SimulatedAnnealing, local.TabuSearch, \link{...} \tab - \cr - E \tab character \tab - \tab estimate.SimpleEstimator, estimate.BMAEstimator, estimate.MultiNomialBMAEstimator \tab - \cr - output_debug_info \tab logical \tab FALSE \tab TRUE, FALSE \tab - \cr - do_not_check_capabilities \tab logical \tab FALSE \tab TRUE, FALSE \tab - \cr - num_decimal_places \tab integer \tab 2 \tab \tab \eqn{[1, \infty)}{[1, Inf)} \cr - batch_size \tab integer \tab 100 \tab \tab \eqn{[1, \infty)}{[1, Inf)} \cr - options \tab untyped \tab NULL \tab \tab - \cr -} + +`r paste(mlr3misc::rd_info(lrn("classif.bayes_net")$param_set), collapse = "\n")` } \examples{ diff --git a/man/mlr_learners_classif.earth.Rd b/man/mlr_learners_classif.earth.Rd index d5e082b65..a024c5a1a 100644 --- a/man/mlr_learners_classif.earth.Rd +++ b/man/mlr_learners_classif.earth.Rd @@ -33,42 +33,8 @@ This \link[mlr3:Learner]{Learner} can be instantiated via \link[mlr3:mlr_sugar]{ } \section{Parameters}{ -\tabular{lllll}{ - Id \tab Type \tab Default \tab Levels \tab Range \cr - wp \tab untyped \tab NULL \tab \tab - \cr - offset \tab untyped \tab NULL \tab \tab - \cr - keepxy \tab logical \tab FALSE \tab TRUE, FALSE \tab - \cr - trace \tab character \tab 0 \tab 0, .3, .5, 1, 2, 3, 4, 5 \tab - \cr - degree \tab integer \tab 1 \tab \tab \eqn{[1, \infty)}{[1, Inf)} \cr - penalty \tab numeric \tab 2 \tab \tab \eqn{[-1, \infty)}{[-1, Inf)} \cr - nk \tab untyped \tab NULL \tab \tab - \cr - thresh \tab numeric \tab 0.001 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr - minspan \tab numeric \tab 0 \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr - endspan \tab numeric \tab 0 \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr - newvar.penalty \tab numeric \tab 0 \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr - fast.k \tab integer \tab 20 \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr - fast.beta \tab integer \tab 1 \tab \tab \eqn{[0, 1]}{[0, 1]} \cr - linpreds \tab untyped \tab FALSE \tab \tab - \cr - allowed \tab untyped \tab - \tab \tab - \cr - pmethod \tab character \tab backward \tab backward, none, exhaustive, forward, seqrep, cv \tab - \cr - nprune \tab integer \tab - \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr - nfold \tab integer \tab 0 \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr - ncross \tab integer \tab 1 \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr - stratify \tab logical \tab TRUE \tab TRUE, FALSE \tab - \cr - varmod.method \tab character \tab none \tab none, const, lm, rlm, earth, gam, power, power0, x.lm, x.rlm, \link{...} \tab - \cr - varmod.exponent \tab numeric \tab 1 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr - varmod.conv \tab numeric \tab 1 \tab \tab \eqn{[0, 1]}{[0, 1]} \cr - varmod.clamp \tab numeric \tab 0.1 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr - varmod.minspan \tab numeric \tab -3 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr - Scale.y \tab logical \tab FALSE \tab TRUE, FALSE \tab - \cr - Adjust.endspan \tab numeric \tab 2 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr - Auto.linpreds \tab logical \tab TRUE \tab TRUE, FALSE \tab - \cr - Force.weights \tab logical \tab FALSE \tab TRUE, FALSE \tab - \cr - Use.beta.cache \tab logical \tab TRUE \tab TRUE, FALSE \tab - \cr - Force.xtx.prune \tab logical \tab FALSE \tab TRUE, FALSE \tab - \cr - Get.leverages \tab logical \tab TRUE \tab TRUE, FALSE \tab - \cr - Exhaustive.tol \tab numeric \tab 1e-10 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr -} + +`r paste(mlr3misc::rd_info(lrn("classif.earth")$param_set), collapse = "\n")` } \examples{ diff --git a/man/mlr_learners_classif.lvq1.Rd b/man/mlr_learners_classif.lvq1.Rd new file mode 100644 index 000000000..334a5bf38 --- /dev/null +++ b/man/mlr_learners_classif.lvq1.Rd @@ -0,0 +1,146 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/learner_class_classif_lvq1.R +\name{mlr_learners_classif.lvq1} +\alias{mlr_learners_classif.lvq1} +\alias{LearnerClassifLvq1} +\title{Classification Learning Vector Quantization 1} +\description{ +Learning Vector Quantization 1. +Calls \code{\link[class:lvqinit]{class::lvqinit()}}, \code{\link[class:lvq1]{class::lvq1()}}, and \code{\link[class:lvqtest]{class::lvqtest()}} from \CRANpkg{class}. +} +\note{ +The learner does not work on tasks with two target groups and one feature. +} +\section{Dictionary}{ + +This \link[mlr3:Learner]{Learner} can be instantiated via \link[mlr3:mlr_sugar]{lrn()}: + +\if{html}{\out{
}}\preformatted{lrn("classif.lvq1") +}\if{html}{\out{
}} +} + +\section{Meta Information}{ + +\itemize{ +\item Task type: \dQuote{classif} +\item Predict Types: \dQuote{response} +\item Feature Types: \dQuote{integer}, \dQuote{numeric} +\item Required Packages: \CRANpkg{mlr3}, \CRANpkg{class} +} +} + +\section{Parameters}{ +\tabular{llll}{ + Id \tab Type \tab Default \tab Range \cr + size \tab integer \tab NULL \tab \eqn{[1, \infty)}{[1, Inf)} \cr + prior \tab untyped \tab NULL \tab - \cr + k \tab integer \tab 5 \tab \eqn{[1, \infty)}{[1, Inf)} \cr + niter \tab integer \tab NULL \tab \eqn{[1, \infty)}{[1, Inf)} \cr + alpha \tab numeric \tab 0.03 \tab \eqn{[0, \infty)}{[0, Inf)} \cr +} +} + +\examples{ +\dontshow{if (learner_is_runnable("classif.lvq1")) withAutoprint(\{ # examplesIf} +# Define the Learner +learner = lrn("classif.lvq1") +print(learner) + +# Define a Task +task = tsk("sonar") + +# 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} +} +\references{ +Kohonen, Teuvo (1990). +\dQuote{The self-organizing map.} +\emph{Proceedings of the IEEE}, \bold{78}, 1464--1480. + +Kohonen, Teuvo (1995). +\emph{Self-Organizing Maps}. +Springer, Berlin. +} +\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:LearnerClassif]{mlr3::LearnerClassif}} -> \code{LearnerClassifLvq1} +} +\section{Methods}{ +\subsection{Public methods}{ +\itemize{ +\item \href{#method-LearnerClassifLvq1-new}{\code{LearnerClassifLvq1$new()}} +\item \href{#method-LearnerClassifLvq1-clone}{\code{LearnerClassifLvq1$clone()}} +} +} +\if{html}{\out{ +
Inherited methods + +
+}} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-LearnerClassifLvq1-new}{}}} +\subsection{Method \code{new()}}{ +Creates a new instance of this \link[R6:R6Class]{R6} class. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{LearnerClassifLvq1$new()}\if{html}{\out{
}} +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-LearnerClassifLvq1-clone}{}}} +\subsection{Method \code{clone()}}{ +The objects of this class are cloneable with this method. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{LearnerClassifLvq1$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/man/mlr_learners_regr.earth.Rd b/man/mlr_learners_regr.earth.Rd index d5eb19954..243ce4c44 100644 --- a/man/mlr_learners_regr.earth.Rd +++ b/man/mlr_learners_regr.earth.Rd @@ -33,42 +33,8 @@ This \link[mlr3:Learner]{Learner} can be instantiated via \link[mlr3:mlr_sugar]{ } \section{Parameters}{ -\tabular{lllll}{ - Id \tab Type \tab Default \tab Levels \tab Range \cr - wp \tab untyped \tab NULL \tab \tab - \cr - offset \tab untyped \tab NULL \tab \tab - \cr - keepxy \tab logical \tab FALSE \tab TRUE, FALSE \tab - \cr - trace \tab character \tab 0 \tab 0, .3, .5, 1, 2, 3, 4, 5 \tab - \cr - degree \tab integer \tab 1 \tab \tab \eqn{[1, \infty)}{[1, Inf)} \cr - penalty \tab numeric \tab 2 \tab \tab \eqn{[-1, \infty)}{[-1, Inf)} \cr - nk \tab untyped \tab NULL \tab \tab - \cr - thresh \tab numeric \tab 0.001 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr - minspan \tab numeric \tab 0 \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr - endspan \tab numeric \tab 0 \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr - newvar.penalty \tab numeric \tab 0 \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr - fast.k \tab integer \tab 20 \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr - fast.beta \tab integer \tab 1 \tab \tab \eqn{[0, 1]}{[0, 1]} \cr - linpreds \tab untyped \tab FALSE \tab \tab - \cr - allowed \tab untyped \tab - \tab \tab - \cr - pmethod \tab character \tab backward \tab backward, none, exhaustive, forward, seqrep, cv \tab - \cr - nprune \tab integer \tab - \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr - nfold \tab integer \tab 0 \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr - ncross \tab integer \tab 1 \tab \tab \eqn{[0, \infty)}{[0, Inf)} \cr - stratify \tab logical \tab TRUE \tab TRUE, FALSE \tab - \cr - varmod.method \tab character \tab none \tab none, const, lm, rlm, earth, gam, power, power0, x.lm, x.rlm, \link{...} \tab - \cr - varmod.exponent \tab numeric \tab 1 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr - varmod.conv \tab numeric \tab 1 \tab \tab \eqn{[0, 1]}{[0, 1]} \cr - varmod.clamp \tab numeric \tab 0.1 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr - varmod.minspan \tab numeric \tab -3 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr - Scale.y \tab logical \tab FALSE \tab TRUE, FALSE \tab - \cr - Adjust.endspan \tab numeric \tab 2 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr - Auto.linpreds \tab logical \tab TRUE \tab TRUE, FALSE \tab - \cr - Force.weights \tab logical \tab FALSE \tab TRUE, FALSE \tab - \cr - Use.beta.cache \tab logical \tab TRUE \tab TRUE, FALSE \tab - \cr - Force.xtx.prune \tab logical \tab FALSE \tab TRUE, FALSE \tab - \cr - Get.leverages \tab logical \tab TRUE \tab TRUE, FALSE \tab - \cr - Exhaustive.tol \tab numeric \tab 1e-10 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr -} + +`r paste(mlr3misc::rd_info(lrn("regr.earth")$param_set), collapse = "\n")` } \examples{ diff --git a/man/mlr_learners_surv.flexreg.Rd b/man/mlr_learners_surv.flexreg.Rd index 97a6c384b..f51dfb6d3 100644 --- a/man/mlr_learners_surv.flexreg.Rd +++ b/man/mlr_learners_surv.flexreg.Rd @@ -27,25 +27,8 @@ This \link[mlr3:Learner]{Learner} can be instantiated via \link[mlr3:mlr_sugar]{ } \section{Parameters}{ -\tabular{lllll}{ - Id \tab Type \tab Default \tab Levels \tab Range \cr - formula \tab untyped \tab - \tab \tab - \cr - anc \tab untyped \tab - \tab \tab - \cr - bhazard \tab untyped \tab - \tab \tab - \cr - rtrunc \tab untyped \tab - \tab \tab - \cr - dist \tab character \tab - \tab gengamma, gengamma.orig, genf, genf.orig, weibull, weibullph, gamma, exp, exponential, llogis, \link{...} \tab - \cr - inits \tab untyped \tab - \tab \tab - \cr - fixedpars \tab untyped \tab - \tab \tab - \cr - cl \tab numeric \tab 0.95 \tab \tab \eqn{[0, 1]}{[0, 1]} \cr - hessian \tab logical \tab TRUE \tab TRUE, FALSE \tab - \cr - hess.control \tab untyped \tab - \tab \tab - \cr - maxiter \tab integer \tab 30 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr - rel.tolerance \tab numeric \tab 1e-09 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr - toler.chol \tab numeric \tab 1e-10 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr - debug \tab integer \tab 0 \tab \tab \eqn{[0, 1]}{[0, 1]} \cr - outer.max \tab integer \tab 10 \tab \tab \eqn{(-\infty, \infty)}{(-Inf, Inf)} \cr - times \tab untyped \tab - \tab \tab - \cr -} + +`r paste(mlr3misc::rd_info(lrn("surv.flexreg")$param_set), collapse = "\n")` } \section{Prediction types}{ diff --git a/tests/testthat/test_class_classif_lvq1.R b/tests/testthat/test_class_classif_lvq1.R new file mode 100644 index 000000000..ea3683268 --- /dev/null +++ b/tests/testthat/test_class_classif_lvq1.R @@ -0,0 +1,8 @@ +skip_if_not_installed("class") + +test_that("autotest", { + learner = lrn("classif.lvq1") + expect_learner(learner) + result = run_autotest(learner, exclude = "feat_single_integer_binary|feat_single_numeric_binary") + expect_true(result, info = result$error) +}) diff --git a/tests/testthat/test_paramtest_class_classif_lvq1.R b/tests/testthat/test_paramtest_class_classif_lvq1.R new file mode 100644 index 000000000..e2a55534f --- /dev/null +++ b/tests/testthat/test_paramtest_class_classif_lvq1.R @@ -0,0 +1,14 @@ +skip_if_not_installed("class") + +test_that("paramtest classif.lvq1 train", { + learner = lrn("classif.lvq1") + fun_list = list(class::lvqinit, class::lvq1) + exclude = c( + "x", # handled internally + "cl", # handled internally + "codebk" # handled internally + ) + + paramtest = run_paramtest(learner, fun_list, exclude, tag = "train") + expect_paramtest(paramtest) +})