Repository navigation
Conversation
…++ call and no output capture
… during a varsel(), cv_varsel() or project() call
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was assisted by Claude.
Summary
This PR builds on #581. After that PR, the IRLS fits of a non-Gaussian GLM projection take about 35 % of the time of
cv_varsel(validate_search = TRUE). About 40 % goes to R code inproj_to_submodl()anddivmin()that builds, for each projection, the submodel formula (update(),flatten_formula()), a data frame with one response column per draw, the draw-wise formulas (validate_response_formula()) and the model matrix (model.frame(),model.matrix()). For one candidate with 5 terms and 20 clusters, these steps took 1.4 ms of 5.3 ms. They depend only on the predictor terms, the number of draws and the reference data, not on the projected draws. A validated LOO search projects onto almost the same term sets in each fold, and the evaluation projects onto the same submodels.This PR caches these objects during a call of
varsel(),cv_varsel()orproject():proj_to_submodl()keeps a store per reference model (identified by the environment ofrefmodel$fetch_data) with the key (predictor terms, number of draws). On a miss, it computes the entry with the existing code. On a hit, it calls the multi-draw fitters ofdivmin()(newdivmin_multi(), whichdivmin()now also uses) directly with the cached model matrix and the projected drawsp_ref$mu.proj_to_submodl()uses the fast path only for the traditional projection withrefmodel$div_minimizer=divmin(), the defaultprojpred.glm_fitter, noNAinp_ref$mu, and no arguments ofdivmin()itself in.... In all other cases, it runs the existing code.projpred.proj_cache = FALSEswitches the cache off.divmin_multi()callscheck_conv()only if a draw has a message, becausecheck_conv_s()returnsTRUEforsubfitobjects.Results
The results are the same as without the cache: in the bench below, the rankings, the suggested sizes and the CV ranking proportions are identical, and the largest relative difference in the ELPD estimates is 1.9e-16.
Bench as in #581. Times in seconds. The first speedup compares this PR with #581. The second compares this PR together with #581 and #574 (on which #581 builds) with master.
A single
varsel()search repeats few term sets, so the cache gives little there: in this bench,varsel()with this PR ran 0.9 to 1.2 times as fast as with #581 alone.Tests
The test suite passes with
NOT_CRAN=true: 263 tests, 55 934 expectations, 0 failures, 0 errors, the same 4 warnings as master. Tested with this change applied to master 73cf0ee (projpred 2.11.0.9000) together with #574 and #581, R 4.6.1, rstanarm 2.32.2, brms 2.23.0, on CSC Roihu (Linux, AMD EPYC).New test in
tests/testthat/test_varsel.R:varsel()with the cache switched off gives the same results as the setup'svarsel()calls (cache on) for the GLM setups of the gaussian, Bernoulli, binomial and poisson families;cv_varsel(method = "forward", validate_search = TRUE, nloo = 5)gives the same results with and without the cache for two Bernoulli/binomial/poisson GLM setups; the cache is empty after the calls. The test fails on master (option and functions do not exist; the depth check errors).Overlap with other PRs
divmin(), the resolution is the same as in Faster GLM submodel fits for non-Gaussian families #581:capt_fun(soutdmin <- do.call(sdivmin, c(list(...), dot_args))).proj_to_submodl(), keep the cached fast path of this PR. In the fallback, multiplyprojpred_ws_augby the observation weights as Leave the left-out observation out of the fold projections in validated LOO CV #580 does, and passprojpred_ws_auginstead ofp_ref$mu. The fast path does not apply to the augmented-data projection, so the fast path needs no change.