diff --git a/.github/workflows/R-CMD-check.yml b/.github/workflows/R-CMD-check.yml index 5f2d726f..1c413f21 100644 --- a/.github/workflows/R-CMD-check.yml +++ b/.github/workflows/R-CMD-check.yml @@ -32,7 +32,7 @@ jobs: uses: actions/checkout@v2 - name: Setup R - uses: r-lib/actions/setup-r@master + uses: r-lib/actions/setup-r@v2 with: r-version: ${{ matrix.config.r }} diff --git a/DESCRIPTION b/DESCRIPTION index 63c65a99..a6621fb2 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -68,5 +68,5 @@ LinkingTo: Rcpp, RcppEigen VignetteBuilder: knitr -RoxygenNote: 7.1.2 +RoxygenNote: 7.2.0 Roxygen: list(markdown = TRUE) diff --git a/NAMESPACE b/NAMESPACE index 4976c069..495ea7e5 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -16,7 +16,6 @@ export(make_copy_map) export(make_design_matrix) export(make_reduced_basis_map) export(squash_hal_fit) -import(Rcpp) importFrom(Matrix,tcrossprod) importFrom(Rcpp,sourceCpp) importFrom(assertthat,assert_that) @@ -27,13 +26,9 @@ importFrom(data.table,setorder) importFrom(glmnet,cv.glmnet) importFrom(glmnet,glmnet) importFrom(methods,is) -importFrom(methods,new) importFrom(origami,cross_validate) -importFrom(origami,fold_index) importFrom(origami,folds2foldvec) importFrom(origami,make_folds) -importFrom(origami,training) -importFrom(origami,validation) importFrom(stats,aggregate) importFrom(stats,as.formula) importFrom(stats,coef) diff --git a/R/RcppExports.R b/R/RcppExports.R index bd17cee2..aaedb7ca 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -51,16 +51,6 @@ apply_copy_map <- function(X, copy_map) { .Call('_hal9001_apply_copy_map', PACKAGE = 'hal9001', X, copy_map) } -#' Prediction from a Lassi Model -#' -#' @param X A sparse matrix of HAL basis functions. -#' @param beta A vector of coefficient values for the HAL basis functions. -#' @param intercept A numeric value giving the intercept of the HAL model. -#' -lassi_predict <- function(X, beta, intercept) { - .Call('_hal9001_lassi_predict', PACKAGE = 'hal9001', X, beta, intercept) -} - #' Sort Basis Functions #' #' Build a sorted list of unique basis functions based on columns, where each diff --git a/R/cv_lasso.R b/R/cv_lasso.R index 44233825..a7fece86 100644 --- a/R/cv_lasso.R +++ b/R/cv_lasso.R @@ -1,55 +1,3 @@ -#' Single Lasso estimation for cross-validation with Origami -#' -#' Fits Lasso regression over a single fold of a cross-validated data set. This -#' is meant to be called using \code{\link[origami]{cross_validate}}, which is -#' done through \code{\link{cv_lasso}}. Note that this procedure is NOT meant -#' to be invoked by itself. INTERNAL USE ONLY. -#' -#' @param fold A \code{fold} object produced by a call to \code{make_folds} -#' from the \pkg{origami}. -#' @param data A \code{dgCMatrix} object containing the outcome values (Y) in -#' its first column and vectors corresponding to the basis functions of HAL in -#' all other columns. Consult the description of HAL regression for details. -#' @param lambdas A \code{numeric} vector corresponding to a sequence of lambda -#' values obtained by fitting the Lasso on the full data. -#' @param center binary. If \code{TRUE}, covariates are centered. This is much -#' slower, but matches the \code{glmnet} implementation. Default \code{FALSE}. -#' -#' @importFrom origami training validation fold_index -lassi_origami <- function(fold, data, lambdas, center = FALSE) { - # make sure data is an (augmented) sparse matrix of basis functions - stopifnot(class(data) == "dgCMatrix") - - # split data for V-fold cross-validation - train_data <- origami::training(data) - valid_data <- origami::validation(data) - - # wrangle objects to clearer forms - train_x_basis <- train_data[, -1] - valid_x_basis <- valid_data[, -1] - train_y <- train_data[, 1] - valid_y <- valid_data[, 1] - - # compute the predicted betas for the given training and validation sets - lassi_fit <- lassi( - x = train_x_basis, y = train_y, lambdas = lambdas, - center = center - ) - pred_mat <- predict(lassi_fit, valid_x_basis) - - # compute the MSE for the given training and validation sets - mses <- apply(pred_mat, 2, function(preds) { - mean((preds - valid_y)^2) - }) - - # the only output needed is the lambda-wise MSE over each fold - mses_out <- matrix(mses, nrow = 1) - out <- list(mses = mses_out) - return(out) -} - -############################################################################### - #' Cross-validated Lasso on Indicator Bases #' #' Fits Lasso regression using a customized procedure, with cross-validation diff --git a/R/cv_lasso_early_stopping.R b/R/cv_lasso_early_stopping.R deleted file mode 100644 index a8423f63..00000000 --- a/R/cv_lasso_early_stopping.R +++ /dev/null @@ -1,97 +0,0 @@ -#' Cross-validated LASSO on Indicator Bases -#' -#' Fits the LASSO regression using a customized procedure with cross-validation -#' based on \pkg{origami} -#' -#' @param x_basis A \code{dgCMatrix} object corresponding to a sparse matrix of -#' the basis functions generated for the HAL algorithm. -#' @param y A \code{numeric} vector of the observed outcome variable values. -#' @param n_lambda A \code{numeric} scalar indicating the number of values of -#' the L1 regularization parameter (lambda) to be obtained from fitting the -#' LASSO to the full data. Cross-validation is used to select an optimal -#' lambda (that minimizes the risk) from among these. -#' @param n_folds A \code{numeric} scalar for the number of folds to be used in -#' the cross-validation procedure to select an optimal value of lambda. -#' -#' @importFrom origami make_folds cross_validate -#' @importFrom stats sd -cv_lasso_early_stopping <- function(x_basis, y, n_lambda = 100, n_folds = 10) { - # first, need to run lasso on the full data to get a sequence of lambdas - lasso_init <- lassi(y = y, x = x_basis, nlambda = n_lambda, center = FALSE) - lambdas_init <- lasso_init$lambdas - - # next, set up a cross-validated lasso using the sequence of lambdas - folds <- origami::make_folds(x_basis, V = n_folds) - - # track separately for folds = xscale, beta, resid, intercept - fold <- folds[[1]] - setup_fold_data <- function(fold, x_basis, y) { - x_train <- training(x_basis) - y_train <- training(y) - x_valid <- validation(x_basis) - y_valid <- validation(y) - - intercept <- mean(y_train) - resid <- y_train - intercept - xcenter <- rep(0, ncol(x_basis)) - xscale <- calc_xscale(x_train, xcenter) - beta <- rep(0, ncol(x_basis)) - - fold_data <- list( - x_train = x_train, x_valid = x_valid, y_valid = y_valid, - intercept = intercept, resid = resid, xscale = xscale, xcenter = xcenter, - beta = beta - ) - - return(list(fold_data = fold_data)) - } - - all_fold_data <- cross_validate(setup_fold_data, folds, x_basis, y, - .combine = FALSE - )$fold_data - - cv_lassi_step <- function(fold, all_fold_data, lambda) { - fold_data <- fold_index(all_fold_data)[[1]] - n_updates <- with(fold_data, fit_lassi_step( - x_train, resid, beta, lambda, - xscale, xcenter, intercept, - FALSE - )) - preds <- with(fold_data, as.vector(x_valid %*% (beta / xscale)) + - intercept) - mse <- with(fold_data, mean((preds - y_valid)^2)) - return(list(fold_data = fold_data, mse = mse)) - } - - null_mse <- NULL - min_mse <- Inf - step_mses <- rep(Inf, n_lambda) - for (lambda_step in seq_along(lambdas_init)) { - lambda <- lambdas_init[lambda_step] - step_results <- lapply(folds, cv_lassi_step, all_fold_data, lambda) - all_fold_data <- lapply(step_results, `[[`, "fold_data") - step_mse <- mean(sapply(step_results, `[[`, "mse")) - # step_results <- cross_validate(cv_lassi_step, folds, all_fold_data, - # lambda, .combine = FALSE) - # all_fold_data <- step_results$fold_data - - if (is.null(null_mse)) { - # null_mse is the first mse (i.e. for the null model) - null_mse <- step_mse - } - - if (step_mse < min_mse) { - min_mse <- step_mse - } - - # compute increase above minimum as percentage of total range - ratio <- (step_mse - min_mse) / (null_mse - min_mse) - - # cat(sprintf("lambda: %f, mse: %f, ratio: %f\n", lambda, step_mse, ratio)) - if (is.finite(ratio) && (ratio > 0.1)) { - break - } - step_mses[lambda_step] <- step_mse - } - return(step_mses) -} diff --git a/R/lassi.R b/R/lassi.R deleted file mode 100644 index 6fa3986d..00000000 --- a/R/lassi.R +++ /dev/null @@ -1,97 +0,0 @@ -#' Rcpp module: lassi_fit_module -#' @import Rcpp -#' @name lassi_fit_module -NULL -loadModule("lassi_module", TRUE) - -#' Custom Lasso implementation for matrices of indicator functions -#' -#' @param x The covariate matrix -#' @param y The outcome vector -#' @param lambdas A sequence of values for the L1 regularization parameter -#' (lambda) to be used in fitting the LASSO. Defaults to \code{NULL}. -#' @param nlambda number of lambdas to fit. -#' @param lambda_min_ratio ratio of largest to smallest lambda to fit. -#' @param center ... -#' -#' @importFrom methods new -#' -#' @keywords internal -lassi <- function(x, y, lambdas = NULL, nlambda = 100, - lambda_min_ratio = 0.01, center = FALSE) { - if (!is.null(lambdas)) { - nlambda <- length(lambdas) - } - - # initialize object - lassi_object <- methods::new(Lassi, x, y, nlambda, lambda_min_ratio, center) - - if (!is.null(lambdas)) { - lassi_object$lambdas <- lambdas - } - - # initialize step counter - step_counts <- rep(0, nlambda) - - # iterative procedure for active step convergence - for (i in (seq_len(nlambda) - 1)) { - full_steps <- lassi_object$lassi_fit_cd(i, FALSE, 1) - if (full_steps > 0) { - active_steps <- lassi_object$lassi_fit_cd(i, TRUE, 1000) - } else { - active_steps <- 0 - } - step_counts[i + 1] <- active_steps - } - - beta_mat <- as.matrix(lassi_object$beta_mat) - intercepts <- lassi_object$intercepts - beta_mat <- beta_mat / lassi_object$xscale - if (center) { - intercepts <- intercepts - crossprod(lassi_object$xcenter, beta_mat) - } - - chichignoud_criterion <- NULL - - # create output object - out <- list(beta_mat, intercepts, - lambdas = lassi_object$lambdas, - step_counts, chichignoud_criterion - ) - names(out) <- c( - "beta_mat", "intercepts", "lambdas", "steps", - "chichignoud_criterion" - ) - class(out) <- "lassi" - return(out) -} - -#' Predict Method for Lasso on Indicator Bases -#' -#' @param fit ... -#' @param new_x_basis ... -#' @param lambdas ... -#' -#' @keywords internal -predict.lassi <- function(fit, new_x_basis, lambdas = NULL) { - if (is.null(lambdas)) { - lambdas <- fit$lambdas - } - - if (!all(lambdas %in% fit$lambdas)) { - stop("Attempting to predict for a lambda that was not fit.") - } - - preds <- matrix(0, nrow = nrow(new_x_basis), ncol = length(lambdas)) - - for (i in seq_along(lambdas)) { - lambda <- lambdas[i] - beta_col <- which(lambda == fit$lambdas) - beta <- fit$beta_mat[, beta_col] - intercept <- fit$intercepts[beta_col] - pred_col <- lassi_predict(new_x_basis, beta, intercept) - preds[, i] <- pred_col - # find corresponding betas - } - return(preds) -} diff --git a/README.md b/README.md index cb168d68..e8ed0d6a 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Phillips](https://github.com/rachaelvp), [Lars van der Laan](https://github.com/Larsvanderlaan), and [Mark van der Laan](https://vanderlaan-lab.org/) ------ +------------------------------------------------------------------------ ## What’s `hal9001`? @@ -49,7 +49,7 @@ variations of HAL regression are used to estimate nuisance parameters (e.g., van der Laan, Benkeser, and Cai 2019; Ertefaie, Hejazi, and van der Laan 2020). ------ +------------------------------------------------------------------------ ## Installation @@ -67,14 +67,14 @@ GitHub via [`remotes`](https://CRAN.R-project.org/package=remotes): remotes::install_github("tlverse/hal9001") ``` ------ +------------------------------------------------------------------------ ## Issues If you encounter any bugs or have any specific feature requests, please [file an issue](https://github.com/tlverse/hal9001/issues). ------ +------------------------------------------------------------------------ ## Example @@ -85,7 +85,7 @@ predictions via Highly Adaptive Lasso regression: # load the package and set a seed library(hal9001) #> Loading required package: Rcpp -#> hal9001 v0.4.3: The Scalable Highly Adaptive Lasso +#> hal9001 v0.4.5: The Scalable Highly Adaptive Lasso #> note: fit_hal defaults have changed. See ?fit_hal for details set.seed(385971) @@ -100,20 +100,20 @@ hal_fit <- fit_hal(X = x, Y = y, yolo = TRUE) #> [1] "I'm sorry, Dave. I'm afraid I can't do that." hal_fit$times #> user.self sys.self elapsed user.child sys.child -#> enumerate_basis 0.008 0.00 0.008 0 0 -#> design_matrix 0.003 0.00 0.003 0 0 -#> reduce_basis 0.000 0.00 0.000 0 0 -#> remove_duplicates 0.000 0.00 0.000 0 0 -#> lasso 3.012 0.01 3.023 0 0 -#> total 3.024 0.01 3.035 0 0 +#> enumerate_basis 0.008 0.001 0.009 0 0 +#> design_matrix 0.003 0.000 0.003 0 0 +#> reduce_basis 0.000 0.000 0.000 0 0 +#> remove_duplicates 0.000 0.000 0.001 0 0 +#> lasso 1.690 0.036 1.764 0 0 +#> total 1.702 0.037 1.778 0 0 # training sample prediction preds <- predict(hal_fit, new_data = x) mean(hal_mse <- (preds - y)^2) -#> [1] 0.03754093 +#> [1] 0.03667466 ``` ------ +------------------------------------------------------------------------ ## Contributions @@ -122,37 +122,35 @@ our [contribution guidelines](https://github.com/tlverse/hal9001/blob/master/CONTRIBUTING.md) prior to submitting a pull request. ------ +------------------------------------------------------------------------ ## Citation After using the `hal9001` R package, please cite both of the following: -``` - @software{coyle2022hal9001-rpkg, - author = {Coyle, Jeremy R and Hejazi, Nima S and Phillips, Rachael V - and {van der Laan}, Lars and {van der Laan}, Mark J}, - title = {{hal9001}: The scalable highly adaptive lasso}, - year = {2022}, - url = {https://doi.org/10.5281/zenodo.3558313}, - doi = {10.5281/zenodo.3558313} - note = {{R} package version 0.4.2} - } - - @article{hejazi2020hal9001-joss, - author = {Hejazi, Nima S and Coyle, Jeremy R and {van der Laan}, Mark - J}, - title = {{hal9001}: Scalable highly adaptive lasso regression in - {R}}, - year = {2020}, - url = {https://doi.org/10.21105/joss.02526}, - doi = {10.21105/joss.02526}, - journal = {Journal of Open Source Software}, - publisher = {The Open Journal} - } -``` - ------ + @software{coyle2022hal9001-rpkg, + author = {Coyle, Jeremy R and Hejazi, Nima S and Phillips, Rachael V + and {van der Laan}, Lars and {van der Laan}, Mark J}, + title = {{hal9001}: The scalable highly adaptive lasso}, + year = {2022}, + url = {https://doi.org/10.5281/zenodo.3558313}, + doi = {10.5281/zenodo.3558313} + note = {{R} package version 0.4.2} + } + + @article{hejazi2020hal9001-joss, + author = {Hejazi, Nima S and Coyle, Jeremy R and {van der Laan}, Mark + J}, + title = {{hal9001}: Scalable highly adaptive lasso regression in + {R}}, + year = {2020}, + url = {https://doi.org/10.21105/joss.02526}, + doi = {10.21105/joss.02526}, + journal = {Journal of Open Source Software}, + publisher = {The Open Journal} + } + +------------------------------------------------------------------------ ## License @@ -162,13 +160,13 @@ Hejazi](https://nimahejazi.org) The contents of this repository are distributed under the GPL-3 license. See file `LICENSE` for details. ------ +------------------------------------------------------------------------ ## References -
Site built with pkgdown 2.0.2.
+Site built with pkgdown 2.0.3.
hal9001
+ hal9001
vignettes/intro_hal9001.Rmd
intro_hal9001.Rmd
The highly adaptive Lasso (HAL) is a flexible machine learning algorithm that nonparametrically estimates a function based on available data by embedding a set of input observations and covariates in an extremely high-dimensional space (i.e., generating basis functions from the available data). For an input data matrix of \(n\) observations and \(d\) covariates, the maximum number of zero-order basis functions generated is approximately \(n \cdot 2^{d - 1}\). To select a set of basis functions from among the (possibly reduced/screener) set that’s generated, the lasso is employed. The hal9001
R package (Hejazi, Coyle, and van der Laan 2020; Coyle, Hejazi, and van der Laan, n.d.) provides an efficient implementation of this routine, relying on the glmnet
R package (Friedman, Hastie, and Tibshirani 2010) for compatibility with the canonical Lasso implementation and using lasso regression with an input matrix composed of basis functions. Consult Benkeser and van der Laan (2016), (???), van der Laan (2017) for detailed theoretical descriptions of HAL and its various optimality properties.
The highly adaptive Lasso (HAL) is a flexible machine
+learning algorithm that nonparametrically estimates a function based on
+available data by embedding a set of input observations and covariates
+in an extremely high-dimensional space (i.e., generating basis functions
+from the available data). For an input data matrix of \(n\) observations and \(d\) covariates, the maximum number of
+zero-order basis functions generated is approximately \(n \cdot 2^{d - 1}\). To select a set of
+basis functions from among the (possibly reduced/screener) set that’s
+generated, the lasso is employed. The hal9001
R package
+(Hejazi, Coyle, and van der Laan 2020; Coyle,
+Hejazi, and van der Laan, n.d.) provides an efficient
+implementation of this routine, relying on the glmnet
R
+package (Friedman, Hastie, and Tibshirani
+2010) for compatibility with the canonical Lasso implementation
+and using lasso regression with an input matrix composed of basis
+functions. Consult Benkeser and van der Laan
+(2016), (vdl2015generally?), van der Laan (2017) for detailed theoretical
+descriptions of HAL and its various optimality properties.
HAL uses the popular glmnet
R package for the lasso step:
HAL uses the popular glmnet
R package for the lasso
+step:
hal_fit <- fit_hal(X = x, Y = y)
hal_fit$times
## user.self sys.self elapsed user.child sys.child
-## enumerate_basis 0.017 0.000 0.017 0 0
-## design_matrix 0.090 0.000 0.091 0 0
+## enumerate_basis 0.017 0.000 0.018 0 0
+## design_matrix 0.082 0.003 0.086 0 0
## reduce_basis 0.000 0.000 0.000 0 0
## remove_duplicates 0.000 0.000 0.000 0 0
-## lasso 3.832 0.008 3.840 0 0
-## total 3.940 0.008 3.948 0 0
+## lasso 2.284 0.072 2.399 0 0
+## total 2.384 0.075 2.503 0 0
While the raw output object may be examined, it has (usually large) slots that make quick examination challenging. The summary
method provides an interpretable table of basis functions with non-zero coefficients. All terms (i.e., including the terms with zero coefficient) can be included by setting only_nonzero_coefs
to FALSE
when calling summary
on a hal9001
model object.
While the raw output object may be examined, it has (usually large)
+slots that make quick examination challenging. The summary
+method provides an interpretable table of basis functions with non-zero
+coefficients. All terms (i.e., including the terms with zero
+coefficient) can be included by setting only_nonzero_coefs
+to FALSE
when calling summary
on a
+hal9001
model object.
##
@@ -237,7 +262,11 @@ Summarizing the model## [ I(x1 >= 0.594)*(x1 - 0.594)^1 ] * [ I(x3 >= -3.289)*(x3 - -3.289)^1 ]
## [ I(x1 >= -0.685)*(x1 - -0.685)^1 ] * [ I(x3 >= -3.289)*(x3 - -3.289)^1 ]
## term
-Note the length and width of these tables! The R environment might not be the optimal location to view the summary. Tip: Tables can be exported from R to LaTeX with the xtable
R package. Here’s an example: print(xtable(summary(fit)$table, type = "latex"), file = "haltbl_meow.tex")
.
Note the length and width of these tables! The R environment might
+not be the optimal location to view the summary. Tip: Tables can be
+exported from R to LaTeX with the xtable
R package. Here’s
+an example: print(xtable(summary(fit)$table, type = "latex"), file
+= "haltbl_meow.tex")
.
As described in Benkeser and van der Laan (2016), the HAL algorithm operates by first constructing a set of basis functions and subsequently fitting a Lasso model with this set of basis functions as the design matrix. Several approaches are considered for reducing this set of basis functions: 1. Removing duplicated basis functions (done by default in the fit_hal
function), 2. Removing basis functions that correspond to only a small set of observations; a good rule of thumb is to scale with \(\frac{1}{\sqrt{n}}\), and that is the default.
The second of these two options may be modified by specifying the reduce_basis
argument to the fit_hal
function:
As described in Benkeser and van der Laan
+(2016), the HAL algorithm operates by first constructing a set of
+basis functions and subsequently fitting a Lasso model with this set of
+basis functions as the design matrix. Several approaches are considered
+for reducing this set of basis functions: 1. Removing duplicated basis
+functions (done by default in the fit_hal
function), 2.
+Removing basis functions that correspond to only a small set of
+observations; a good rule of thumb is to scale with \(\frac{1}{\sqrt{n}}\), and that is the
+default.
The second of these two options may be modified by specifying the
+reduce_basis
argument to the fit_hal
+function:
hal_fit_reduced <- fit_hal(X = x, Y = y, reduce_basis = 0.1)
hal_fit_reduced$times
## user.self sys.self elapsed user.child sys.child
-## enumerate_basis 0.013 0.000 0.014 0 0
-## design_matrix 0.084 0.000 0.084 0 0
+## enumerate_basis 0.026 0.005 0.031 0 0
+## design_matrix 0.080 0.002 0.082 0 0
## reduce_basis 0.000 0.000 0.000 0 0
## remove_duplicates 0.000 0.000 0.000 0 0
-## lasso 3.763 0.008 3.771 0 0
-## total 3.860 0.008 3.869 0 0
-In the above, all basis functions with fewer than 10% of observations meeting the criterion imposed are automatically removed prior to the Lasso step of fitting the HAL regression. The results appear below
+## lasso 1.951 0.063 2.030 0 0 +## total 2.057 0.070 2.143 0 0 +In the above, all basis functions with fewer than 10% of observations +meeting the criterion imposed are automatically removed prior to the +Lasso step of fitting the HAL regression. The results appear below
summary(hal_fit_reduced)$table
## coef
@@ -350,12 +391,42 @@ Reducing basis functions## 34: [ I(x3 >= -3.289)*(x3 - -3.289)^1 ]
## 35: [ I(x1 >= -3.224)*(x1 - -3.224)^1 ] * [ I(x2 >= -3.038)*(x2 - -3.038)^1 ] * [ I(x3 >= 1.202)*(x3 - 1.202)^1 ]
## term
-Other approaches exist for reducing the set of basis functions before they are actually created, which is essential for most real-world applications with HAL. Currently, we provide this “pre-screening” via num_knots
argument in hal_fit
. The num_knots
argument is akin to binning: it increases the coarseness of the approximation. num_knots
allows one to specify the number of knot points used to generate the basis functions for each/all interaction degree(s). This reduces the total number of basis functions generated, and thus the size of the optimization problem, and it can dramatically decrease runtime. One can pass in a vector of length max_degree
to num_knots
, specifying the number of knot points to use by interaction degree for each basis function. Thus, one can specify if interactions of higher degrees (e.g., two- or three- way interactions) should be more coarse. Increasing the coarseness of more complex basis functions helps prevent a combinatorial explosion of basis functions, which can easily occur when basis functions are generated for all possible knot points. We will show an example with num_knots
in the section that follows.
Other approaches exist for reducing the set of basis functions
+before they are actually created, which is essential for most
+real-world applications with HAL. Currently, we provide this
+“pre-screening” via num_knots
argument in
+hal_fit
. The num_knots
argument is akin to
+binning: it increases the coarseness of the approximation.
+num_knots
allows one to specify the number of knot points
+used to generate the basis functions for each/all interaction degree(s).
+This reduces the total number of basis functions generated, and thus the
+size of the optimization problem, and it can dramatically decrease
+runtime. One can pass in a vector of length max_degree
to
+num_knots
, specifying the number of knot points to use by
+interaction degree for each basis function. Thus, one can specify if
+interactions of higher degrees (e.g., two- or three- way interactions)
+should be more coarse. Increasing the coarseness of more complex basis
+functions helps prevent a combinatorial explosion of basis functions,
+which can easily occur when basis functions are generated for all
+possible knot points. We will show an example with
+num_knots
in the section that follows.
One might wish to enforce smoothness on the functional form of the HAL fit. This can be done using the smoothness_orders
argument. Setting smoothness_orders = 0
gives a piece-wise constant fit (via zero-order basis functions), allowing for discontinuous jumps in the function. This is useful if one does not want to assume any smoothness or continuity of the “true” function. Setting smoothness_orders = 1
gives a piece-wise linear fit (via first-order basis functions), which is continuous and mostly differentiable. In general, smoothness_orders = k
corresponds to a piece-wise polynomial fit of degree \(k\). Mathematically, smoothness_orders = k
corresponds with finding the best fit under the constraint that the total variation of the function’s \(k^{\text{th}}\) derivative is bounded by some constant, which is selected with cross-validation.
One might wish to enforce smoothness on the functional form of the
+HAL fit. This can be done using the smoothness_orders
+argument. Setting smoothness_orders = 0
gives a piece-wise
+constant fit (via zero-order basis functions), allowing for
+discontinuous jumps in the function. This is useful if one does not want
+to assume any smoothness or continuity of the “true” function. Setting
+smoothness_orders = 1
gives a piece-wise linear fit (via
+first-order basis functions), which is continuous and mostly
+differentiable. In general, smoothness_orders = k
+corresponds to a piece-wise polynomial fit of degree \(k\). Mathematically,
+smoothness_orders = k
corresponds with finding the best fit
+under the constraint that the total variation of the function’s \(k^{\text{th}}\) derivative is bounded by
+some constant, which is selected with cross-validation.
Let’s see this in action.
set.seed(98109)
@@ -393,7 +464,16 @@ Specifying smoothness of the HAL
long <- melt(dt, id = "x")
ggplot(long, aes(x = x, y = value, group = variable)) + geom_line()
Comparing the mean squared error (MSE) between the predictions and the true (denoised) outcome, the first- and second- order smoothed HAL is able to recover from the coarseness of the basis functions caused by the small num_knots
argument. Also, the HAL with second-order smoothness is able to fit the true function very well (as expected, since sin(x) is a very smooth function). The main benefit of imposing higher-order smoothness is that fewer knot points are required for a near-optimal fit. Therefore, one can safely pass a smaller value to num_knots
for a big decrease in runtime without sacrificing performance.
Comparing the mean squared error (MSE) between the predictions and
+the true (denoised) outcome, the first- and second- order smoothed HAL
+is able to recover from the coarseness of the basis functions caused by
+the small num_knots
argument. Also, the HAL with
+second-order smoothness is able to fit the true function very well (as
+expected, since sin(x) is a very smooth function). The main benefit of
+imposing higher-order smoothness is that fewer knot points are required
+for a near-optimal fit. Therefore, one can safely pass a smaller value
+to num_knots
for a big decrease in runtime without
+sacrificing performance.
mean((pred_0 - ytrue)^2)
## [1] 0.00732315
@@ -422,7 +502,17 @@
plot(x, pred_smooth_2, main = "Second order smoothness fit")
In general, if the basis functions are not coarse, then the performance for different smoothness orders is similar. Notice how the runtime is a fair bit slower when more knot points are considered. In general, we recommend either zero- or first- order smoothness. Second-order smoothness tends to be less robust and suffers from extrapolation on new data. One can also use cross-validation to data-adaptively choose the optimal smoothness (invoked in fit_hal
by setting adaptive_smoothing = TRUE
). Comparing the following simulation and the previous one, the HAL with second-order smoothness performed better when there were fewer knot points.
In general, if the basis functions are not coarse, then the
+performance for different smoothness orders is similar. Notice how the
+runtime is a fair bit slower when more knot points are considered. In
+general, we recommend either zero- or first- order smoothness.
+Second-order smoothness tends to be less robust and suffers from
+extrapolation on new data. One can also use cross-validation to
+data-adaptively choose the optimal smoothness (invoked in
+fit_hal
by setting adaptive_smoothing = TRUE
).
+Comparing the following simulation and the previous one, the HAL with
+second-order smoothness performed better when there were fewer knot
+points.
set.seed(98109)
n_covars <- 1
@@ -467,7 +557,19 @@ Specifying smoothness of the HAL
Formula interface
-One might wish to specify the functional form of the HAL fit further. This can be done using the formula interface. Specifically, the formula interface allows one to specify monotonicity constraints on components of the HAL fit. It also allows one to specify exactly which basis functions (e.g., interactions) one wishes to model. The formula_hal
function generates a formula
object from a user-supplied character string, and this formula
object contains the necessary specification information for fit_hal
and glmnet
. The formula_hal
function is intended for use within fit_hal
, and the user-supplied character string is inputted into fit_hal
. Here, we call formula_hal
directly for illustrative purposes.
+One might wish to specify the functional form of the HAL fit further.
+This can be done using the formula interface. Specifically, the formula
+interface allows one to specify monotonicity constraints on components
+of the HAL fit. It also allows one to specify exactly which basis
+functions (e.g., interactions) one wishes to model. The
+formula_hal
function generates a formula
+object from a user-supplied character string, and this
+formula
object contains the necessary specification
+information for fit_hal
and glmnet
. The
+formula_hal
function is intended for use within
+fit_hal
, and the user-supplied character string is inputted
+into fit_hal
. Here, we call formula_hal
+directly for illustrative purposes.
set.seed(98109)
num_knots <- 100
@@ -479,7 +581,13 @@ Formula interfaceX <- data.frame(x1 = x1, x2 = x2, A = A)
Y <- rowMeans(sin(X)) + rnorm(n_obs, mean = 0, sd = 0.2)
We can specify an additive model in a number of ways.
-The formula below includes the outcome, but formula_hal
doesn’t fit a HAL model, and doesn’t need the outcome (actually everything before “\(\tilde\)” is ignored in formula_hal
). This is why formula_hal
takes the input X
matrix of covariates, and not X
and Y
. In what follows, we include formulas with and without “y” in the character string.
+The formula below includes the outcome, but formula_hal
+doesn’t fit a HAL model, and doesn’t need the outcome (actually
+everything before “\(\tilde\)” is
+ignored in formula_hal
). This is why
+formula_hal
takes the input X
matrix of
+covariates, and not X
and Y
. In what follows,
+we include formulas with and without “y” in the character string.
# The `h` function is used to specify the basis functions for a given term
# h(x1) generates one-way basis functions for the variable x1
@@ -519,7 +627,12 @@ Formula interfaceformula <- formula_hal(
Y ~ h(x1, k=1) + h(x2, k=1) + h(A, k=1), X = X, smoothness_orders = 1, num_knots = 10
)
-The .
argument. We can generate an additive model for all or a subset of variables using the .
variable and .
argument of h
. By default, .
in h(.)
is treated as a wildcard and basis functions are generated by replacing the .
with all variables in X
.
+The .
argument. We can generate an additive model for
+all or a subset of variables using the .
variable and
+.
argument of h
. By default, .
in
+h(.)
is treated as a wildcard and basis functions are
+generated by replacing the .
with all variables in
+X
.
smoothness_orders <- 1
num_knots <- 5
@@ -560,7 +673,10 @@ Formula interfaceformula2 <- h(.) + h(., .)+ h(.,.,.)
length(formula1$basis_list ) == length(formula2$basis_list)
## [1] TRUE
-Sometimes, one might want to build an additive model, but include all two-way interactions with one variable (e.g., treatment “A”). This can be done in a variety of ways. The .
argument allows you to specify a subset of variables.
+Sometimes, one might want to build an additive model, but include all
+two-way interactions with one variable (e.g., treatment “A”). This can
+be done in a variety of ways. The .
argument allows you to
+specify a subset of variables.
# Write it all out
formula <- h(x1) + h(x2) + h(A) + h(A, x1) + h(A,x2)
@@ -581,7 +697,15 @@ Formula interfaceformula2 <- h(A,., . = c("x1"))
length(formula1$basis_list) == length(formula2$basis_list)
## [1] FALSE
-A key feature of the HAL formula is monotonicity constraints. Specifying these constraints is achieved by specifying the monotone
argument of h
. Note if smoothness_orders = 0 then this is a monotonicity constrain on the function, but if if smoothness_orders = 1 then this is a monotonicity constraint on the function’s derivative (e.g. a convexity constraint). We can also specify that certain terms are not penalized in the LASSO/glmnet using the pf
argument of h
(stands for penalty factor).
+A key feature of the HAL formula is monotonicity
+constraints. Specifying these constraints is achieved by
+specifying the monotone
argument of h
. Note if
+smoothness_orders = 0 then this is a monotonicity constrain on the
+function, but if if smoothness_orders = 1 then this is a monotonicity
+constraint on the function’s derivative (e.g. a convexity constraint).
+We can also specify that certain terms are not penalized in the
+LASSO/glmnet using the pf
argument of h
+(stands for penalty factor).
# An additive monotone increasing model
formula <- formula_hal(
@@ -614,7 +738,9 @@ Formula interface# intraction glm
formula <- h(., ., s = 1, k = 1, pf = 0) + h(., s = 1, k = 1, pf = 0)
# Running HAL with this formula will be equivalent to running glm with the formula Y ~ .^2
-Now, that we’ve illustrated the options with formula_hal
, let’s show how to fit a HAL model with the specified formula.
+Now, that we’ve illustrated the options with
+formula_hal
, let’s show how to fit a HAL model with the
+specified formula.
# get formula object
fit <- fit_hal(
@@ -641,23 +767,34 @@ Formula interface
-References
+References
-
-
-Benkeser, David, and Mark J van der Laan. 2016. “The Highly Adaptive Lasso Estimator.” In 2016 IEEE International Conference on Data Science and Advanced Analytics (DSAA). IEEE. https://doi.org/10.1109/dsaa.2016.93.
+
+
+Benkeser, David, and Mark J van der Laan. 2016. “The Highly
+Adaptive Lasso Estimator.” In 2016 IEEE
+International Conference on Data Science and Advanced Analytics
+(DSAA). IEEE. https://doi.org/10.1109/dsaa.2016.93.
-
-Coyle, Jeremy R, Nima S Hejazi, and Mark J van der Laan. n.d. hal9001
: The Scalable Highly Adaptive Lasso (version 0.2.7). https://doi.org/10.5281/zenodo.3558313.
+
+Coyle, Jeremy R, Nima S Hejazi, and Mark J van der Laan. n.d.
+hal9001
: The Scalable Highly Adaptive
+Lasso (version 0.2.7). https://doi.org/10.5281/zenodo.3558313.
-
-Friedman, Jerome, Trevor Hastie, and Rob Tibshirani. 2010. “Regularization Paths for Generalized Linear Models via Coordinate Descent.” Journal of Statistical Software 33 (1): 1.
+
+Friedman, Jerome, Trevor Hastie, and Rob Tibshirani. 2010.
+“Regularization Paths for Generalized Linear Models via Coordinate
+Descent.” Journal of Statistical Software 33 (1): 1.
-
-Hejazi, Nima S, Jeremy R Coyle, and Mark J van der Laan. 2020. “hal9001: Scalable Highly Adaptive Lasso Regression in R.” Journal of Open Source Software 5 (53): 2526. https://doi.org/10.21105/joss.02526.
+
+Hejazi, Nima S, Jeremy R Coyle, and Mark J van der Laan. 2020.
+“hal9001: Scalable Highly Adaptive
+Lasso Regression in R.” Journal of Open Source
+Software 5 (53): 2526. https://doi.org/10.21105/joss.02526.
-
-van der Laan, Mark J. 2017. “Finite Sample Inference for Targeted Learning.” https://arxiv.org/abs/1708.09502.
+
+van der Laan, Mark J. 2017. “Finite Sample Inference for
+Targeted Learning.” https://arxiv.org/abs/1708.09502.
@@ -680,7 +817,7 @@ References
-Site built with pkgdown 2.0.2.
+Site built with pkgdown 2.0.3.
diff --git a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-13-1.png b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-13-1.png
index 66b130d2..32553fc6 100644
Binary files a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-13-1.png and b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-13-1.png differ
diff --git a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-2-1.png b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-2-1.png
index 3a44677f..7df64e57 100644
Binary files a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-2-1.png and b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-2-1.png differ
diff --git a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-1.png b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-1.png
index 31549fde..d12920ac 100644
Binary files a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-1.png and b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-1.png differ
diff --git a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-2.png b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-2.png
index ca8b1175..8f6da37c 100644
Binary files a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-2.png and b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-2.png differ
diff --git a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-3.png b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-3.png
index a4695e82..6b1c3032 100644
Binary files a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-3.png and b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-3.png differ
diff --git a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-4.png b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-4.png
index e359a501..957b9b53 100644
Binary files a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-4.png and b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-3-4.png differ
diff --git a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-5-1.png b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-5-1.png
index ca8b1175..8f6da37c 100644
Binary files a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-5-1.png and b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-5-1.png differ
diff --git a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-5-2.png b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-5-2.png
index a4695e82..6b1c3032 100644
Binary files a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-5-2.png and b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-5-2.png differ
diff --git a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-5-3.png b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-5-3.png
index 0c6c2172..f2a89afe 100644
Binary files a/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-5-3.png and b/docs/articles/intro_hal9001_files/figure-html/unnamed-chunk-5-3.png differ
diff --git a/docs/authors.html b/docs/authors.html
index 22290116..b4c87ab8 100644
--- a/docs/authors.html
+++ b/docs/authors.html
@@ -103,7 +103,7 @@ Citation
Coyle J, Hejazi N, Phillips R, van der Laan L, van der Laan M (2022).
hal9001: The scalable highly adaptive lasso.
-doi: 10.5281/zenodo.3558313, R package version 0.4.3, https://github.com/tlverse/hal9001.
+doi:10.5281/zenodo.3558313, R package version 0.4.3, https://github.com/tlverse/hal9001.
@Manual{,
title = {{hal9001}: The scalable highly adaptive lasso},
@@ -116,7 +116,7 @@ Citation
Hejazi N, Coyle J, van der Laan M (2020).
“hal9001: Scalable highly adaptive lasso regression in R.”
Journal of Open Source Software.
-doi: 10.21105/joss.02526, https://doi.org/10.21105/joss.02526.
+doi:10.21105/joss.02526, https://doi.org/10.21105/joss.02526.
@Article{,
title = {{hal9001}: Scalable highly adaptive lasso regression in {R}},
@@ -139,7 +139,7 @@ Citation
diff --git a/docs/index.html b/docs/index.html
index 8e7e4609..4faf8401 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -128,7 +128,7 @@ Example
# load the package and set a seed
library(hal9001)
#> Loading required package: Rcpp
-#> hal9001 v0.4.3: The Scalable Highly Adaptive Lasso
+#> hal9001 v0.4.5: The Scalable Highly Adaptive Lasso
#> note: fit_hal defaults have changed. See ?fit_hal for details
set.seed(385971)
@@ -143,17 +143,17 @@ Example
#> [1] "I'm sorry, Dave. I'm afraid I can't do that."
hal_fit$times
#> user.self sys.self elapsed user.child sys.child
-#> enumerate_basis 0.008 0.00 0.008 0 0
-#> design_matrix 0.003 0.00 0.003 0 0
-#> reduce_basis 0.000 0.00 0.000 0 0
-#> remove_duplicates 0.000 0.00 0.000 0 0
-#> lasso 3.012 0.01 3.023 0 0
-#> total 3.024 0.01 3.035 0 0
+#> enumerate_basis 0.008 0.001 0.009 0 0
+#> design_matrix 0.003 0.000 0.003 0 0
+#> reduce_basis 0.000 0.000 0.000 0 0
+#> remove_duplicates 0.000 0.000 0.001 0 0
+#> lasso 1.690 0.036 1.764 0 0
+#> total 1.702 0.037 1.778 0 0
# training sample prediction
preds <- predict(hal_fit, new_data = x)
mean(hal_mse <- (preds - y)^2)
-#> [1] 0.03754093
+#> [1] 0.03667466
@@ -166,27 +166,27 @@ ContributionsCitation
After using the hal9001
R package, please cite both of the following:
- @software{coyle2022hal9001-rpkg,
- author = {Coyle, Jeremy R and Hejazi, Nima S and Phillips, Rachael V
- and {van der Laan}, Lars and {van der Laan}, Mark J},
- title = {{hal9001}: The scalable highly adaptive lasso},
- year = {2022},
- url = {https://doi.org/10.5281/zenodo.3558313},
- doi = {10.5281/zenodo.3558313}
- note = {{R} package version 0.4.2}
- }
-
- @article{hejazi2020hal9001-joss,
- author = {Hejazi, Nima S and Coyle, Jeremy R and {van der Laan}, Mark
- J},
- title = {{hal9001}: Scalable highly adaptive lasso regression in
- {R}},
- year = {2020},
- url = {https://doi.org/10.21105/joss.02526},
- doi = {10.21105/joss.02526},
- journal = {Journal of Open Source Software},
- publisher = {The Open Journal}
- }
+@software{coyle2022hal9001-rpkg,
+ = {Coyle, Jeremy R and Hejazi, Nima S and Phillips, Rachael V
+ author
+ and {van der Laan}, Lars and {van der Laan}, Mark J},= {{hal9001}: The scalable highly adaptive lasso},
+ title = {2022},
+ year = {https://doi.org/10.5281/zenodo.3558313},
+ url = {10.5281/zenodo.3558313}
+ doi = {{R} package version 0.4.2}
+ note
+ }
+@article{hejazi2020hal9001-joss,
+ = {Hejazi, Nima S and Coyle, Jeremy R and {van der Laan}, Mark
+ author
+ J},= {{hal9001}: Scalable highly adaptive lasso regression in
+ title
+ {R}},= {2020},
+ year = {https://doi.org/10.21105/joss.02526},
+ url = {10.21105/joss.02526},
+ doi = {Journal of Open Source Software},
+ journal = {The Open Journal}
+ publisher }
@@ -199,27 +199,27 @@ License
References
-
-
-Benkeser, David, and Mark J van der Laan. 2016. “The Highly Adaptive Lasso Estimator.” In 2016 IEEE International Conference on Data Science and Advanced Analytics (DSAA). IEEE. https://doi.org/10.1109/dsaa.2016.93.
+
+
+Benkeser, David, and Mark J van der Laan. 2016. “The Highly Adaptive Lasso Estimator.” In 2016 IEEE International Conference on Data Science and Advanced Analytics (DSAA). IEEE. https://doi.org/10.1109/dsaa.2016.93.
-
-Bibaut, Aurélien F, and Mark J van der Laan. 2019. “Fast Rates for Empirical Risk Minimization over Càdlàg Functions with Bounded Sectional Variation Norm.” https://arxiv.org/abs/1907.09244.
+
+Bibaut, Aurélien F, and Mark J van der Laan. 2019. “Fast Rates for Empirical Risk Minimization over Càdlàg Functions with Bounded Sectional Variation Norm.” https://arxiv.org/abs/1907.09244.
-
-Ertefaie, Ashkan, Nima S Hejazi, and Mark J van der Laan. 2020. “Nonparametric Inverse Probability Weighted Estimators Based on the Highly Adaptive Lasso.” https://arxiv.org/abs/2005.11303.
+
+Ertefaie, Ashkan, Nima S Hejazi, and Mark J van der Laan. 2020. “Nonparametric Inverse Probability Weighted Estimators Based on the Highly Adaptive Lasso.” https://arxiv.org/abs/2005.11303.
-
-van der Laan, Mark J. 2017a. “A Generally Efficient Targeted Minimum Loss Based Estimator Based on the Highly Adaptive Lasso.” The International Journal of Biostatistics. https://doi.org/10.1515/ijb-2015-0097.
+
+van der Laan, Mark J. 2017a. “A Generally Efficient Targeted Minimum Loss Based Estimator Based on the Highly Adaptive Lasso.” The International Journal of Biostatistics. https://doi.org/10.1515/ijb-2015-0097.
-
-———. 2017b. “Finite Sample Inference for Targeted Learning.” https://arxiv.org/abs/1708.09502.
+
+———. 2017b. “Finite Sample Inference for Targeted Learning.” https://arxiv.org/abs/1708.09502.
-
-van der Laan, Mark J, David Benkeser, and Weixin Cai. 2019. “Efficient Estimation of Pathwise Differentiable Target Parameters with the Undersmoothed Highly Adaptive Lasso.” https://arxiv.org/abs/1908.05607.
+
+van der Laan, Mark J, David Benkeser, and Weixin Cai. 2019. “Efficient Estimation of Pathwise Differentiable Target Parameters with the Undersmoothed Highly Adaptive Lasso.” https://arxiv.org/abs/1908.05607.
-
-van der Laan, Mark J, and Aurélien F Bibaut. 2017. “Uniform Consistency of the Highly Adaptive Lasso Estimator of Infinite-Dimensional Parameters.” https://arxiv.org/abs/1709.06256.
+
+van der Laan, Mark J, and Aurélien F Bibaut. 2017. “Uniform Consistency of the Highly Adaptive Lasso Estimator of Infinite-Dimensional Parameters.” https://arxiv.org/abs/1709.06256.
@@ -295,7 +295,7 @@ Dev status
diff --git a/docs/news/index.html b/docs/news/index.html
index f0ccb7cd..880a8638 100644
--- a/docs/news/index.html
+++ b/docs/news/index.html
@@ -107,7 +107,7 @@ hal9001 0.2.5
diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml
index 264ee722..ce08e0d7 100644
--- a/docs/pkgdown.yml
+++ b/docs/pkgdown.yml
@@ -1,9 +1,9 @@
-pandoc: '2.5'
-pkgdown: 2.0.2
+pandoc: 2.17.0.1
+pkgdown: 2.0.3
pkgdown_sha: ~
articles:
intro_hal9001: intro_hal9001.html
-last_built: 2022-02-09T21:19Z
+last_built: 2022-11-04T20:06Z
urls:
reference: https://tlverse.org/hal9001/reference
article: https://tlverse.org/hal9001/articles
diff --git a/docs/reference/SL.hal9001.html b/docs/reference/SL.hal9001.html
index d0527f27..d10342df 100644
--- a/docs/reference/SL.hal9001.html
+++ b/docs/reference/SL.hal9001.html
@@ -144,7 +144,7 @@ Value
diff --git a/docs/reference/apply_copy_map.html b/docs/reference/apply_copy_map.html
index 17e5a645..609faab4 100644
--- a/docs/reference/apply_copy_map.html
+++ b/docs/reference/apply_copy_map.html
@@ -120,7 +120,7 @@ Examples
diff --git a/docs/reference/as_dgCMatrix.html b/docs/reference/as_dgCMatrix.html
index 1f6afbb7..19770364 100644
--- a/docs/reference/as_dgCMatrix.html
+++ b/docs/reference/as_dgCMatrix.html
@@ -95,7 +95,7 @@ Value
diff --git a/docs/reference/basis_list_cols.html b/docs/reference/basis_list_cols.html
index bbd64ea6..25e30700 100644
--- a/docs/reference/basis_list_cols.html
+++ b/docs/reference/basis_list_cols.html
@@ -122,7 +122,7 @@ Value
diff --git a/docs/reference/basis_of_degree.html b/docs/reference/basis_of_degree.html
index 5c4e015f..9e6d0da5 100644
--- a/docs/reference/basis_of_degree.html
+++ b/docs/reference/basis_of_degree.html
@@ -121,7 +121,7 @@ Value
cv_lasso()
Cross-validated Lasso on Indicator Bases
Cross-validated LASSO on Indicator Bases
index_first_copy()
Find Copies of Columns
Rcpp module: lassi_fit_module
Single Lasso estimation for cross-validation with Origami
Prediction from a Lassi Model
1e-7) {
-
- update_resid(j, beta_diff);
- beta[j] = new_beta;
- updates++;
- }
-
- double something = beta_diff * beta_diff;
- if(something>max_update){
- max_update=something;
- }
-
- if(std::abs(update) > lambda){
- if(step_num<2){
- // if not already, put in active set
- variable_state[j]=2;
- }
-
- } else {
- //put in strong if not currently and criteria met
- if(step_num==0){
-
- //update strong
- if(std::abs(update) > strong_criterion){
- variable_state[j]=1;
- }
-
- //update safe
- //we need to start checking this predictor again
- //when lambda gets smaller than safe_lambda
- double rnorm=std::sqrt(rss)/n;
- safe_lambda[j]=lambda*((rnorm+std::abs(update))/(rnorm+lambda));
- // Rcout << "rnorm: " << rnorm << " update: " << update << " current: "
- // << lambda << " next_safe: "<< safe_lambda[j] << std::endl;
- }
- }
- }
- }
-
- if(max_update