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)
+})