2 User guide
This guide explains the model concepts behind the bindings. It grows one section at a time as each model lands; each section pairs with a runnable example in Examples.
2.1 The elastic-net model
glmnet fits a linear model by minimizing a penalized least-squares objective. For a response y and predictors X (with n observations), it solves
min_{β₀,β} 1/(2n) ‖y − β₀ − Xβ‖² + λ [ α‖β‖₁ + (1−α)/2 ‖β‖₂² ]
over the intercept β₀ and coefficients β. Two knobs control the penalty:
α (the mixing parameter), in [0,1]. α=0 is the pure ridge (L2) penalty; α=1 is the pure lasso (L1) penalty; values in between blend the two (the elastic net).
λ (the penalty strength), ≥ 0. Larger λ shrinks coefficients more; λ=0 recovers the unpenalized fit (ordinary least squares).
So the four core models this package exposes are one routine called with different parameters:
Model |
| α |
| λ |
OLS |
| (any) |
| 0 |
Ridge |
| 0 |
| > 0 |
Lasso |
| 1 |
| > 0 |
Elastic net |
| 0 < α < 1 |
| > 0 |
2.2 Fitting a model
elnet-fit is the one entry point behind every model; the four core cases have convenience wrappers. A fit takes the predictor matrix as a list of rows and the response as a list, and returns an elnet-result:
(require glmnet) (define X '((1.0 2.0) (2.0 1.0) (3.0 4.0) (4.0 3.0) (5.0 6.0))) (define y '(1.0 4.0 3.0 6.0 5.0)) (define fit (ols X y)) (elnet-result-intercept fit) (elnet-result-coefficients fit)
ols is just elnet-fit with #:lambda 0.0. The penalized models pass #:alpha and a positive #:lambda, and each has a convenience wrapper: ridge (α = 0), lasso (α = 1), and elastic-net (an explicit #:alpha). See Ordinary least squares (λ = 0), Ridge regression (L2, α = 0), Lasso (L1, α = 1), and Elastic net (0 < α < 1) for worked examples, and API reference for the full keyword list.
2.3 Standardization and intercept
By default glmnet standardizes each predictor column to unit variance before fitting and reports coefficients on the original scale, and it fits an unpenalized intercept. These match the conventions in the R package’s vignette and are the defaults the bindings expose.
2.4 Classification: the binomial family
The models above fit a numeric response with the Gaussian elnet solver. For binary classification, the binomial family fits a two-class logistic model with glmnet’s lognet solver instead: the response y is a 0/1 class label, and the model predicts the log-odds of class 1,
log( P(y=1) / P(y=0) ) = β₀ + Xβ,
minimizing the penalized binomial deviance under the same elastic-net penalty. The α and λ knobs mean exactly what they do for the Gaussian models, so #:alpha 1.0 is the sparse (lasso) logistic and #:alpha 0.0 the ridge logistic.
(require glmnet) (define X '((1.0 5.0) (2.0 4.0) (5.0 1.0) (4.0 2.0))) (define y '(0 0 1 1)) (define fit (logistic-fit X y #:lambda 0.05)) (logistic-result-coefficients fit) ; class-1 probabilities, then hard 0/1 labels: (logistic-predict-proba fit X) (logistic-predict fit X)
logistic-fit returns a logistic-result whose
logistic-result-dev-ratio is the fraction of null deviance explained —
2.5 Multiclass classification: the multinomial family
The binomial family handles two classes; the multinomial family handles K > 2. It is the same lognet solver with the class count set above 1, so the elastic-net penalty is unchanged. The response is an integer class label in {0, …, K−1}, and the fit returns K intercepts and K coefficient vectors (the symmetric parameterization):
(require glmnet) (define X '((1.0 1.0) (5.0 1.0) (3.0 5.0) (2.0 2.0) (6.0 1.0) (4.0 6.0))) (define y '(0 1 2 0 1 2)) (define fit (multinomial-fit X y #:lambda 0.05)) ; K coefficient vectors, one per class: (multinomial-result-coefficients fit) (multinomial-predict-proba fit X) (multinomial-predict fit X)
Class probabilities are the softmax over the K linear predictors ηk = a0k + x·βk: multinomial-predict-proba returns the per-row distributions (each summing to 1) and multinomial-predict returns the argmax class. As with the other families, #:alpha 1.0 is the sparse (lasso) fit and #:alpha 0.0 the ridge fit. See Multinomial classification (K classes).
2.6 Survival analysis: the Cox family
The families above all predict from a feature vector to a label or a number. The Cox family instead models survival data: each observation has a follow-up time and a 0/1 event indicator (1 = the event happened, 0 = right-censored). It fits Cox’s proportional-hazards model, in which the hazard is
h(t | x) = h₀(t) · exp(x·β),
so there is no intercept (the baseline hazard h₀ is left
unspecified) and a positive coefficient raises the hazard —
(require glmnet) (define X '((0.5 1.0) (2.0 2.0) (3.5 1.0) (4.0 2.0))) (define times '(12.0 8.0 4.0 3.0)) ; 0 = right-censored, 1 = event observed (define statuses '(0 1 1 1)) (define fit (cox-fit X times statuses #:lambda 0.1)) (cox-result-coefficients fit) (cox-relative-risk fit X)
cox-fit returns a cox-result with
cox-result-coefficients (no intercept) and
cox-result-dev-ratio (the fraction of null partial-likelihood deviance
explained). cox-relative-risk gives exp(x·β) —
2.7 Count data: the Poisson family
The Poisson family models count responses —
μ = exp(β₀ + Xβ),
and a positive coefficient multiplies the expected count. Poisson has an intercept, and the elastic-net penalty is unchanged.
(require glmnet) (define X '((1.0 2.0) (3.0 1.0) (5.0 2.0) (8.0 1.0))) ; non-negative counts (define y '(1 2 4 11)) (define fit (poisson-fit X y #:lambda 0.1)) (poisson-result-coefficients fit) (poisson-predict-mean fit X)
poisson-fit returns a poisson-result with an poisson-result-intercept, poisson-result-coefficients (on the log-mean scale), and poisson-result-dev-ratio. poisson-predict-mean applies the log link to give the fitted rate exp(β₀ + x·β) for new predictors. As elsewhere, #:alpha 1.0 is the lasso and #:alpha 0.0 the ridge. See Poisson regression (counts).
2.8 Multiple responses: the multi-response Gaussian family
The Gaussian models above fit one numeric response. The multi-response
Gaussian family (mgaussian-fit) fits several at once: the response is a
matrix Y with one column per response. It uses a grouped lasso
across the responses —
(require glmnet) (define X '((1.0 2.0) (3.0 1.0) (5.0 2.0) (6.0 1.0))) ; two responses, one column each (define Y '((3.0 9.0) (7.0 7.0) (11.0 5.0) (13.0 4.0))) (define fit (mgaussian-fit X Y #:lambda 0.1)) (mgaussian-result-coefficients fit) (mgaussian-predict fit X)
mgaussian-fit returns a mgaussian-result with mgaussian-result-intercepts (one per response), mgaussian-result-coefficients (a vector of per-response coefficient vectors), and mgaussian-result-r-squared. mgaussian-predict returns the per-response predictions a0r + x·βr for each row. As elsewhere, #:alpha 1.0 is the (grouped) lasso and #:alpha 0.0 the ridge. See Multi-response Gaussian (grouped).
2.9 The precision contract
The vendored Fortran declares its arrays as single-precision real, but the entire elastic-net ABI is treated as double precision: the native library is compiled with -fdefault-real-8 so the default real is 8 bytes. This is what R’s glmnet and Julia’s glmnet_jll do as well. The package asserts the flag took effect at load time (see Getting started).
2.10 Rebuilding the native library
Using the package needs no Fortran toolchain. To rebuild libglmnetcompat from source (for development or a new platform):
# via Nix (runs the Fortran ctest suite too) |
nix build .#native |
|
# or directly with CMake + gfortran |
cmake -S fortran -B fortran/build -DBUILD_TESTING=ON |
cmake --build fortran/build |
ctest --test-dir fortran/build --output-on-failure |