Shrinkage

Elastic net

Elastic net combines sparse selection with quadratic shrinkage. Its rounded diamond retains corners on the coordinate axes. Supply the two strengths independently with ElasticNet::new(l1, l2). Setting either strength to zero recovers ridge or lasso, respectively.

R(β)=λ1∥β∥1+λ22∥β∥22. R(\beta) = \lambda_1\|\beta\|_1 + \frac{\lambda_2}{2}\|\beta\|_2^2.

Constraint region

Feasible region for elastic net; the shaded set includes its boundary.

λ1=0.5\lambda_1 = 0.5 and λ2=1\lambda_2 = 1: 0.5∥β∥1+0.5∥β∥22≤10.5\|\beta\|_1 + 0.5\|\beta\|_2^2 \leq 1. See the plot conventions for the fixed budget and coefficient scale.

Use the penalty

use shrinkage::{ElasticNet, Penalty, ProximalPenalty};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let penalty = ElasticNet::from_alpha(0.5, 0.7);
    let coefficients = [2.0, -1.0];
    println!("Penalty: {}", penalty.value(&coefficients)?);
    let mut shrunk = [0.0; 2];
    penalty.prox(&coefficients, 1.0, &mut shrunk)?;
    println!("Proximal result: {shrunk:?}");
    Ok(())
}

Alternatively, ElasticNet::from_alpha(lambda, alpha) uses λ1=λα\lambda_1 = \lambda\alpha and λ2=λ(1−α)\lambda_2 = \lambda(1 - \alpha), where 0≤α≤10 \leq \alpha \leq 1. The proximal map soft-thresholds at sλ1s\lambda_1 and then divides by 1+sλ21 + s\lambda_2. Fits support proximal gradient and IRLS.

API: shrinkage::ElasticNet.