Migrating from sparse-ho¶
sparho is a clean-break successor to
sparse-ho, not a drop-in replacement.
There is no compat module — porting code is a manual rewrite. This page
is the translation table.
The shape of the rewrite¶
sparse-ho’s outer call took four objects:
sparse_ho.grad_search(algo, criterion, model, optimizer, X, y, alpha0, monitor)
sparho rolls algo (hypergradient) and optimizer (outer step rule) into
the search function itself, and folds model (which estimator) into the
Solver adapter you pass:
sparho.hoag_search(
problem, # ← Problem(datafit, penalty, X, y)
hp0=alpha0, # ← in log α space internally; pass α > 0
solver=..., # ← was `model` + adapter choice
criterion=..., # ← was `criterion`
hypergrad=..., # ← was `algo`, default `implicit_forward`
)
monitor becomes the return value: result.history is an immutable tuple
of IterationRecords. Use grad_search instead of hoag_search for the
naive fixed-lr outer loop (sparse-ho’s GradientDescent optimizer).
Translation table¶
Models → Problem + adapter¶
sparse-ho |
sparho |
Notes |
|---|---|---|
|
|
Default. Use |
|
|
|
|
|
sparse-ho’s |
|
|
Per-feature α. |
|
not yet at v0.1 |
Open a discussion if you need it. |
|
|
sparse-ho’s |
|
not at v0.1 |
|
|
not at v0.1 |
The hypergradient is closed-form; out of scope. |
Algorithms → hypergrad=¶
sparse-ho |
sparho |
Notes |
|---|---|---|
|
|
The only mode at v0.1. |
|
not at v0.1 |
Deferred. |
|
not at v0.1 |
Unrolled modes deferred. |
Criteria¶
sparse-ho |
sparho |
Notes |
|---|---|---|
|
|
int32 indices required. |
|
|
|
|
|
sparho’s |
|
not at v0.1 |
SVM/SVR family deferred. |
|
not at v0.1 |
SURE deferred — see “Out of scope” in |
Optimizers → search function¶
sparse-ho optimizer |
sparho equivalent |
Notes |
|---|---|---|
|
|
Plain GD baseline. |
|
|
sparho’s recommended default — Lipschitz-adaptive steps + inner-tolerance scheduling. The original Armijo |
|
not at v0.1 |
Owner-paper features; depend on |
Monitor → SearchResult.history¶
sparse-ho’s Monitor mutated as the loop ran:
monitor = Monitor()
sparse_ho.grad_search(algo, crit, model, opt, X, y, alpha0, monitor)
alphas, mses = monitor.alphas, monitor.objs
sparho returns an immutable SearchResult:
result = sparho.hoag_search(problem, hp0=alpha0, solver=..., criterion=...)
alphas = [r.hyperparam for r in result.history]
mses = [r.value for r in result.history]
best_alpha = result.best_hyperparam
best_coef = result.best_coef # refit on the full problem
A worked example¶
sparse-ho:
from celer import Lasso as CelerLasso
from sklearn.datasets import make_regression
from sparse_ho import grad_search
from sparse_ho.algo import ImplicitForward
from sparse_ho.criterion import HeldOutMSE
from sparse_ho.models import Lasso
from sparse_ho.optimizers import LineSearch
from sparse_ho.utils import Monitor
X, y = make_regression(n_samples=300, n_features=100, noise=1.0, random_state=0)
idx_train, idx_val = np.arange(200), np.arange(200, 300)
model = Lasso(X, y, estimator=CelerLasso(fit_intercept=False))
algo = ImplicitForward(criterion="HO")
criterion = HeldOutMSE(idx_train, idx_val)
optimizer = LineSearch(n_outer=30)
monitor = Monitor()
grad_search(algo, criterion, model, optimizer, X, y, alpha0=1e-2, monitor=monitor)
print(monitor.alphas[-1], monitor.objs[-1])
sparho:
import numpy as np
from sklearn.datasets import make_regression
from sparho import HeldOutMSE, L1, Problem, SquaredLoss, hoag_search
from sparho.adapters.celer import CelerLasso
X, y = make_regression(n_samples=300, n_features=100, noise=1.0, random_state=0)
idx_train = np.arange(200, dtype=np.int32)
idx_val = np.arange(200, 300, dtype=np.int32)
result = hoag_search(
Problem(SquaredLoss(), L1(), X, y),
hp0=1e-2,
solver=CelerLasso(tol=1e-8),
criterion=HeldOutMSE(idx_train, idx_val),
n_iter=30,
)
print(result.best_hyperparam, result.history[-1].value)
Behavior differences to know about¶
αlives in log space. Bothgrad_searchandhoag_searchstep inθ = log α;hp0must be strictly positive. The chain ruledC/dθ = dC/dα · αis applied internally. sparse-ho left this to the user vialog_alpha_max.Full-data refit at the end.
SearchResult.best_coefis the inner solver run on the fullProblematbest_hyperparam. sparse-ho leftmonitor.alphas[-1]as the only output; a refit was on the user.Sparse-X is CSC, not CSR. Convert before constructing
Problem.No
Monitor. The history is immutable. If you need streaming observation, wrap the criterion (or the solver) yourself.No
surecriterion. Dropped at v0.1; the v0.1 audience tunes validation, not unsupervised SURE. Revisit if asked.No grid-search fallback. sparse-ho had a grid
ho.grid_search; sparho doesn’t ship one. Usesklearn.linear_model.LassoCVif you want a grid baseline.
What’s not yet ported¶
These were sparse-ho features that v0.1 deliberately leaves on the floor.
Some are slated for v0.2 (skein adapter, more datafits/penalties); others
are out of scope (SVM/SVR, imaging operators). See ROADMAP.md for the
full picture.