Commit 816b942b authored by Tom Reynkens's avatar Tom Reynkens

Use "cv1se" to indicate selection of lambda using cross-validation with the one standard error rule

parent 6ec27823
Type: Package
Package: smurf
Title: Sparse Multi-Type Regularized Feature Modeling
Version: 0.3.0.9023
Version: 0.3.0.9024
Date: 2018-09-21
Authors@R: c(
person("Tom", "Reynkens", email = "tomreynkens@hotmail.com", role = c("aut", "cre"),
......
......@@ -34,7 +34,7 @@
# Number of folds
# In-sample selection of lambda using measures is the same as cross-validation with 1 fold
# For out-of-sample selection we only have one fold, validation data is in 'valdata'
n.folds <- ifelse(!(lambda %in% c("cv.dev", "cv.mse", "cv.dss", "cv.dev.1se", "cv.mse.1se", "cv.dss.1se")),
n.folds <- ifelse(!(lambda %in% c("cv.dev", "cv.mse", "cv.dss", "cv1se.dev", "cv1se.mse", "cv1se.dss")),
1, control$k)
n <- length(y)
......@@ -444,17 +444,17 @@
lambda.opt <- lambda.vector[.which.min.last(rowMeans(dss.val))]
} else if (lambda == "cv.dev.1se") {
} else if (lambda == "cv1se.dev") {
lambda.opt <- .cv.1se(x = dev.val, lambda.vector = lambda.vector, n.folds = n.folds)
lambda.opt <- .cv1se(x = dev.val, lambda.vector = lambda.vector, n.folds = n.folds)
} else if (lambda == "cv.mse.1se") {
} else if (lambda == "cv1se.mse") {
lambda.opt <- .cv.1se(x = mse.val, lambda.vector = lambda.vector, n.folds = n.folds)
lambda.opt <- .cv1se(x = mse.val, lambda.vector = lambda.vector, n.folds = n.folds)
} else if (lambda == "cv.dss.1se") {
} else if (lambda == "cv1se.dss") {
lambda.opt <- .cv.1se(x = dss.val, lambda.vector = lambda.vector, n.folds = n.folds)
lambda.opt <- .cv1se(x = dss.val, lambda.vector = lambda.vector, n.folds = n.folds)
} else if (lambda == "is.aic") {
......@@ -521,7 +521,7 @@
# x: Matrix with error measures per value of lambda (rows) and fold (columns)
# lambda.vector: Vector of considered values of lambda
# n.folds: Number of folds
.cv.1se <- function(x, lambda.vector, n.folds) {
.cv1se <- function(x, lambda.vector, n.folds) {
# Index of lambda with minimum average error measure
ind0 <- .which.min.last(rowMeans(x))
......
......@@ -314,13 +314,13 @@
# If lambda is NULL (or not given), set to default
if (is.null(lambda)) {
lambda <- "cv.dev.1se"
lambda <- "cv1se.dev"
} else if (is.character(lambda)) {
# Check if lambda is selected using one of the supported methods
lambda_char_vec <- c("cv.dev", "cv.mse", "cv.dss",
"cv.dev.1se", "cv.mse.1se", "cv.dss.1se",
"cv1se.dev", "cv1se.mse", "cv1se.dss",
"is.aic", "is.bic", "is.gcv",
"oos.dev", "oos.mse", "oos.dss")
......
......@@ -33,12 +33,12 @@
#' \item \code{"cv.dev"} (cross-validation (CV); deviance),
#' \item \code{"cv.mse"} (CV; MSE),
#' \item \code{"cv.dss"} (CV; DSS),
#' \item \code{"cv.dev.1se"} (CV with one standard error (SE) rule; deviance),
#' \item \code{"cv.mse.1se"} (CV with one SE rule; MSE),
#' \item \code{"cv.dss.1se"} (CV with one SE rule; DSS).
#' \item \code{"cv1se.dev"} (CV with one standard error (SE) rule; deviance),
#' \item \code{"cv1se.mse"} (CV with one SE rule; MSE),
#' \item \code{"cv1se.dss"} (CV with one SE rule; DSS).
#' }
#' E.g. \code{"is.aic"} indicates in-sample selection of lambda with the AIC as measure.
#' When \code{lambda} is missing, it will be selected using cross-validation with the one standard error rule and the deviance as measure (\code{"cv.dev.1se"}).
#' When \code{lambda} is missing, it will be selected using cross-validation with the one standard error rule and the deviance as measure (\code{"cv1se.dev"}).
#' @param lambda1 The penalty parameter for the \eqn{L_1}-penalty in Sparse (Generalized) Fused Lasso or Sparse Graph-Guided Fused Lasso is \eqn{\lambda \times \lambda_1}.
#' A positive numeric with default 0 (no extra \eqn{L_1}-penalty).
#' @param lambda2 The penalty parameter for the \eqn{L_2}-penalty in Group (Generalized) Fused Lasso or Group Graph-Guided Fused Lasso is \eqn{\lambda \times \lambda_2}. A positive numeric with default 0 (no extra \eqn{L_2}-penalty).
......
......@@ -19,8 +19,8 @@
#' determined based on method that was used to select lambda.
#' @param lambda.opt Logical indicating if the optimal value of lambda should be indicated on the plot
#' by a vertical dashed line. Default is \code{TRUE}.
#' @param cv.1se Logical indicating if the standard errors should be indicated on the plot
#' when cross-validation with the one standard error rule is performed (e.g. "cv.dev.1se"). Default is \code{TRUE}.
#' @param cv1se Logical indicating if the standard errors should be indicated on the plot
#' when cross-validation with the one standard error rule is performed (e.g. "cv1se.dev"). Default is \code{TRUE}.
#' @param log.lambda Logical indicating if the logarithm of lambda is plotted on the x-axis, default is \code{TRUE}.
#' @param ... Additional arguments for the \code{\link[graphics]{plot}} function.
#'
......@@ -34,7 +34,7 @@ plot_lambda <- function(x, ...) UseMethod("plot_lambda", x)
#' @export
#' @rdname plot_lambda
plot_lambda.glmsmurf <- function(x, xlab = NULL, ylab = NULL, lambda.opt = TRUE, cv.1se = TRUE, log.lambda = TRUE, ...) {
plot_lambda.glmsmurf <- function(x, xlab = NULL, ylab = NULL, lambda.opt = TRUE, cv1se = TRUE, log.lambda = TRUE, ...) {
# Check if wanted objects exist
if (exists(c("lambda.vector", "lambda.method", "lambda.measures"), where = x)) {
......@@ -58,9 +58,9 @@ plot_lambda.glmsmurf <- function(x, xlab = NULL, ylab = NULL, lambda.opt = TRUE,
# Get validation scores and potential new y-axis label
if (lambda.method %in% c("cv.dev", "cv.dev.1se", "oos.dev")) {
if (lambda.method %in% c("cv.dev", "cv1se.dev", "oos.dev")) {
if (lambda.method %in% c("cv.dev", "cv.dev.1se")) {
if (lambda.method %in% c("cv.dev", "cv1se.dev")) {
ylab.new <- "Deviance (CV)"
} else {
......@@ -69,9 +69,9 @@ plot_lambda.glmsmurf <- function(x, xlab = NULL, ylab = NULL, lambda.opt = TRUE,
lambda.measures <- x$lambda.measures$dev
} else if (lambda.method %in% c("cv.mse", "cv.mse.1se", "oos.mse")) {
} else if (lambda.method %in% c("cv.mse", "cv1se.mse", "oos.mse")) {
if (lambda.method %in% c("cv.mse", "cv.mse.1se")) {
if (lambda.method %in% c("cv.mse", "cv1se.mse")) {
ylab.new <- "Mean Squared Error (CV)"
} else {
......@@ -80,9 +80,9 @@ plot_lambda.glmsmurf <- function(x, xlab = NULL, ylab = NULL, lambda.opt = TRUE,
lambda.measures <- x$lambda.measures$mse
} else if (lambda.method %in% c("cv.dss", "cv.dss.1se", "oos.dss")) {
} else if (lambda.method %in% c("cv.dss", "cv1se.dss", "oos.dss")) {
if (lambda.method %in% c("cv.dss", "cv.dss.1se")) {
if (lambda.method %in% c("cv.dss", "cv1se.dss")) {
ylab.new <- "Dawid-Sebastiani Score (CV)"
} else {
......@@ -145,7 +145,7 @@ plot_lambda.glmsmurf <- function(x, xlab = NULL, ylab = NULL, lambda.opt = TRUE,
}
# One standard error rule
if (cv.1se & lambda.method %in% c("cv.dev.1se", "cv.mse.1se", "cv.dss.1se")) {
if (cv1se & lambda.method %in% c("cv1se.dev", "cv1se.mse", "cv1se.dss")) {
# Index of lambda with minimum average error measure
ind0 <- .which.min.last(rowMeans(lambda.measures))
......
......@@ -5,6 +5,12 @@
\section{Changes in version 0.4.0 (2018-yy-xx)}{
\subsection{Changes in \code{R}-code:}{
\itemize{
\item \code{glmsmurf}: Use "\code{cv1se}" to indicate selection of lambda using cross-validation with the one standard error rule. E.g. \code{"cv.dev.1se"} is renamed to \code{"cv1se.dev"}.
}
}
\subsection{Changes in documentation:}{
\itemize{
\item \code{glmsmurf}: Add note that selected value of lambda for out-of-sample selection and cross-validation is not (always) deterministic.
......
......@@ -58,7 +58,7 @@ formu <- rentm ~ p(area, pen = "gflasso") +
# The number of values of lambda to consider in cross-validation is
# set to 25 using the control argument (default is 50).
munich.fit.cv <- glmsmurf(formula = formu, family = gaussian(), data = rent,
pen.weights = "glm.stand", lambda = "cv.dev.1se",
pen.weights = "glm.stand", lambda = "cv1se.dev",
control = list(lambda.length = 25L))
......
......@@ -45,12 +45,12 @@ Offset(s) specified using the \code{formula} object will be ignored!}
\item \code{"cv.dev"} (cross-validation (CV); deviance),
\item \code{"cv.mse"} (CV; MSE),
\item \code{"cv.dss"} (CV; DSS),
\item \code{"cv.dev.1se"} (CV with one standard error (SE) rule; deviance),
\item \code{"cv.mse.1se"} (CV with one SE rule; MSE),
\item \code{"cv.dss.1se"} (CV with one SE rule; DSS).
\item \code{"cv1se.dev"} (CV with one standard error (SE) rule; deviance),
\item \code{"cv1se.mse"} (CV with one SE rule; MSE),
\item \code{"cv1se.dss"} (CV with one SE rule; DSS).
}
E.g. \code{"is.aic"} indicates in-sample selection of lambda with the AIC as measure.
When \code{lambda} is missing, it will be selected using cross-validation with the one standard error rule and the deviance as measure (\code{"cv.dev.1se"}).}
When \code{lambda} is missing, it will be selected using cross-validation with the one standard error rule and the deviance as measure (\code{"cv1se.dev"}).}
\item{lambda1}{The penalty parameter for the \eqn{L_1}-penalty in Sparse (Generalized) Fused Lasso or Sparse Graph-Guided Fused Lasso is \eqn{\lambda \times \lambda_1}.
A positive numeric with default 0 (no extra \eqn{L_1}-penalty).}
......
......@@ -8,7 +8,7 @@
plot_lambda(x, ...)
\method{plot_lambda}{glmsmurf}(x, xlab = NULL, ylab = NULL,
lambda.opt = TRUE, cv.1se = TRUE, log.lambda = TRUE, ...)
lambda.opt = TRUE, cv1se = TRUE, log.lambda = TRUE, ...)
}
\arguments{
\item{x}{An object for which the extraction of goodness-of-fit statistics or information criteria is meaningful.
......@@ -25,8 +25,8 @@ determined based on method that was used to select lambda.}
\item{lambda.opt}{Logical indicating if the optimal value of lambda should be indicated on the plot
by a vertical dashed line. Default is \code{TRUE}.}
\item{cv.1se}{Logical indicating if the standard errors should be indicated on the plot
when cross-validation with the one standard error rule is performed (e.g. "cv.dev.1se"). Default is \code{TRUE}.}
\item{cv1se}{Logical indicating if the standard errors should be indicated on the plot
when cross-validation with the one standard error rule is performed (e.g. "cv1se.dev"). Default is \code{TRUE}.}
\item{log.lambda}{Logical indicating if the logarithm of lambda is plotted on the x-axis, default is \code{TRUE}.}
}
......@@ -99,7 +99,7 @@ formu <- rentm ~ p(area, pen = "gflasso") +
# The number of values of lambda to consider in cross-validation is
# set to 25 using the control argument (default is 50).
munich.fit.cv <- glmsmurf(formula = formu, family = gaussian(), data = rent,
pen.weights = "glm.stand", lambda = "cv.dev.1se",
pen.weights = "glm.stand", lambda = "cv1se.dev",
control = list(lambda.length = 25L))
......
......@@ -78,7 +78,7 @@ munich.fit.cv <- suppressWarnings(glmsmurf(formu, family = gaussian(), data = re
# Selection of lambda (CV with 1SE rule)
munich.fit.cv1se <- suppressWarnings(glmsmurf(formu, family = gaussian(), data = rent,
pen.weights = "glm.stand", lambda = "cv.mse.1se",
pen.weights = "glm.stand", lambda = "cv1se.mse",
control = list(eps = 1e-5, lambda.length = 3L, k = 2L, ncores = 1L)))
......
......@@ -522,7 +522,7 @@ test_that("plot_lambda", {
expect_error(plot_lambda(munich.fit.cv, lambda.opt = FALSE), NA)
expect_error(plot_lambda(munich.fit.cv1se, lambda.opt = FALSE), NA)
expect_error(plot_lambda(munich.fit.cv1se, cv.1se = FALSE), NA)
expect_error(plot_lambda(munich.fit.cv1se, cv1se = FALSE), NA)
# Check if error for invalid method to select lambda
munich.fit.is2 <- munich.fit.is
......
......@@ -149,7 +149,7 @@ test_that("Test input for lambda", {
# Check if error for numeric vector
expect_error(glmsmurf(formu, data = rent, family = gaussian(), lambda = "a"),
paste0("'lambda' must be a numeric, NULL, or one of 'cv.dev', 'cv.mse', 'cv.dss',",
" 'cv.dev.1se', 'cv.mse.1se', 'cv.dss.1se', 'is.aic', 'is.bic', 'is.gcv',",
" 'cv1se.dev', 'cv1se.mse', 'cv1se.dss', 'is.aic', 'is.bic', 'is.gcv',",
" 'oos.dev', 'oos.mse' or 'oos.dss'."),
fixed = TRUE)
......@@ -170,7 +170,7 @@ test_that("Test input for lambda", {
# Check default
expect_equal(.check_input_lambda(),
"cv.dev.1se")
"cv1se.dev")
})
......
......@@ -420,7 +420,7 @@ test_that("Test lambda.method in output", {
expect_equal(munich.fit.is$lambda.method, "is.aic")
expect_equal(munich.fit.oos$lambda.method, "oos.dev")
expect_equal(munich.fit.cv$lambda.method, "cv.mse")
expect_equal(munich.fit.cv1se$lambda.method, "cv.mse.1se")
expect_equal(munich.fit.cv1se$lambda.method, "cv1se.mse")
})
......
......@@ -315,9 +315,9 @@ Alternatively, cross-validation can also be performed using the one standard err
\[\lambda_{\text{opt}} = \max\{\lambda_i | ae_{\lambda_i} \leq ae_{\lambda_0} + see_{\lambda_0}\}\]
with $ae_{\lambda}$ and $see_{\lambda}$ the average and standard error (respectively) of the error measure when using $\lambda$ as tuning parameter. Using the same error measures as before, $\lambda$ can thus also be determined using the one standard error rule for cross-validation:
* Deviance: `lambda = "cv.dev.1se"`,
* MSE: `lambda = "cv.mse.1se"`,
* DSS: `lambda = "cv.dss.1se"`.
* Deviance: `lambda = "cv1se.dev"`,
* MSE: `lambda = "cv1se.mse"`,
* DSS: `lambda = "cv1se.dss"`.
## Deterministic selection of lambda
......@@ -330,7 +330,7 @@ To select the optimal value for $\lambda$ in the example, we use stratified five
with the deviance as loss measure and the one standard error rule. The number of values of $\lambda$ to consider is set to 25 using the `control` argument.
```{r, eval = FALSE}
munich.fit.cv <- glmsmurf(formula = formu, family = gaussian(), data = rent,
pen.weights = "glm.stand", lambda = "cv.dev.1se",
pen.weights = "glm.stand", lambda = "cv1se.dev",
control = list(lambda.length = 25L))
```
The optimal value of $\lambda$ can then be obtained with
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment