The source files for all examples can be found in /examples.
Lasso
This example uses the LassoSolver
to solve a lasso regression problem. We also show how to use the MLSolver
.
The lasso regression problem is
\[\begin{array}{ll} \text{minimize} & (1/2)\|Ax - b\|_2^2 + \lambda \|x\|_1. \end{array}\]
using GeNIOS
using Random, LinearAlgebra, SparseArrays
Generating the problem data
Random.seed!(1)
m, n = 200, 400
A = randn(m, n)
A .-= sum(A, dims=1) ./ m
normalize!.(eachcol(A))
xstar = sprandn(n, 0.1)
b = A*xstar + 1e-3*randn(m)
λ = 0.05*norm(A'*b, Inf)
0.14048198582260793
LassoSolver interface
The easiest interface for this problem is the LassoSolver
, where we just need to specify the regularization parameter (in addition to the problem data).
λ1 = λ
solver = GeNIOS.LassoSolver(λ1, A, b)
res = solve!(solver; options=GeNIOS.SolverOptions(use_dual_gap=true, dual_gap_tol=1e-4, verbose=true))
rmse = sqrt(1/m*norm(A*solver.zk - b, 2)^2)
println("Final RMSE: $(round(rmse, digits=8))")
Starting setup...
Setup in 0.101s
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Iteration Objective RMSE Dual Gap r_primal r_dual ρ Time
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
0 1.995e+01 3.158e-01 9.256e+00 Inf Inf 1.000e+00 0.000
1 1.995e+01 3.158e-01 9.256e+00 0.000e+00 1.058e+01 1.000e+00 0.078
20 4.260e+00 5.491e-02 5.403e-02 2.000e-02 6.603e-02 1.000e+00 0.084
40 4.260e+00 5.409e-02 2.114e-04 1.546e-04 2.842e-04 1.000e+00 0.091
42 4.260e+00 5.409e-02 8.546e-05 8.677e-05 1.527e-04 1.000e+00 0.092
SOLVED in 0.092s, 42 iterations
Total time: 0.193s
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Final RMSE: 0.07649858
MLSolver interface
Under the hood, this is just a wrapper around the MLSolver
interface. This interface is more general, and allows us to specify the per-sample loss used in the machine learning problem. Specifically, it solves problems with the form
\[\begin{array}{ll} \text{minimize} & \sum_{i=1}^N f(a_i^Tx - b_i) + \lambda_1 \|x\|_1 + (\lambda_2/2) \|x\|_2^2. \end{array}\]
It's easy to see that the lasso problem is a special case.
f(x) = 0.5*x^2
fconj(x) = 0.5*x^2
λ1 = λ
λ2 = 0.0
solver = GeNIOS.MLSolver(f, λ1, λ2, A, b; fconj=fconj)
res = solve!(solver; options=GeNIOS.SolverOptions(relax=true, use_dual_gap=true, dual_gap_tol=1e-3, verbose=true))
rmse = sqrt(1/m*norm(A*solver.zk - b, 2)^2)
println("Final RMSE: $(round(rmse, digits=8))")
Starting setup...
Setup in 0.108s
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Iteration Objective RMSE Dual Gap r_primal r_dual ρ Time
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
0 1.995e+01 3.158e-01 9.256e+00 Inf Inf 1.000e+00 0.000
1 1.995e+01 3.158e-01 9.256e+00 0.000e+00 1.058e+01 1.000e+00 0.132
20 4.260e+00 5.491e-02 5.403e-02 2.000e-02 6.603e-02 1.000e+00 0.138
36 4.260e+00 5.408e-02 8.625e-04 4.108e-04 1.712e-03 1.000e+00 0.143
SOLVED in 0.143s, 36 iterations
Total time: 0.251s
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Final RMSE: 0.076475
Note that we also defined the conjugate function of $f$, defined as
\[f^*(y) = \sup_x \{yx - f(x)\},\]
which allows us to use the dual gap as a stopping criterion (see our paper for a derivation). Specifying the conjugate function is optional, and the solver will fall back to using the primal and dual residuals if it is not specified.
This page was generated using Literate.jl.