rsoselect
Variable selection with the ridge selection operator (RSO) for linear, partially linear, and generalized partially linear models.
Ridge regression with an individual penalty per coefficient can select variables: if the penalty on a coefficient goes to infinity, that coefficient is exactly zero. RSO puts a budget on the inverse penalties and lets the data decide where to spend it (Wu, 2021). The same idea, applied to the inverse bandwidths of a kernel smoother, selects nonparametric predictors as well, so linear and nonlinear predictors are chosen in one optimization problem (Lu et al., 2024; Lu, Hu and Wu, 2025).
| model | class | paper |
|---|---|---|
| y = Xβ + ε | RSO |
Wu (2021), Technometrics |
| y = Xβ + f(Z) + ε | PLM |
Lu, Dong, Hu and Wu (2024), JCGS |
| g(E[y]) = Xβ + f(Z) | GPLM |
Lu, Hu and Wu (2025), Journal of Nonparametric Statistics |
Installation
pip install rsoselect # core
pip install "rsoselect[sklearn]" # with scikit-learn integration
From source:
git clone https://github.com/luyouhanzju/rsoselect.git
cd rsoselect
pip install -e .
Requires Python 3.9+, NumPy and SciPy. scikit-learn is optional (needed only for
criterion="cv" and for using RSO inside sklearn pipelines).
Quick start
from rsoselect import RSO, PLM, GPLM
# Linear model: drop-in replacement for sklearn's Ridge
m = RSO().fit(X, y)
m.support_ # selected predictors (boolean mask)
m.coef_, m.intercept_
m.predict(X_new)
# Partially linear model: X enters linearly, Z nonparametrically
m = PLM().fit(X, Z, y)
m.support_x_, m.support_z_
m.predict(X_new, Z_new)
# Generalized partially linear model (binomial, poisson or gaussian)
m = GPLM(family="binomial").fit(X, Z, y)
m.predict(X_new, Z_new) # probabilities
m.predict_eta(X_new, Z_new) # linear predictor
How it works
For a budget τ, RSO solves
min over gamma: RSS( beta(gamma) )
subject to: gamma_k >= 0, sum_k gamma_k = tau
beta(gamma) = argmin_b (1/n) ||y - X b||^2 + sum_k b_k^2 / gamma_k
so γk = 0 gives βk = 0 exactly. In the PLM and GPLM the
nonparametric part is a kernel smoother with inverse bandwidths λj
under a second budget ∑λj = τ2; λj = 0
removes Zj. The GPLM is fit by local scoring, and (γ, λ) minimize
the negative log-likelihood. All three models are optimized by the same modified
coordinate descent (rsoselect.mcd).
The budgets are tuned over a grid:
| model | criteria (default first) |
|---|---|
RSO |
"profile_bic" (OLS refit on the selected set), "naive_bic", "cv" |
PLM |
"profile_bic" (local linear refit, eq. 10), "naive_bic" (eq. 7) |
GPLM |
"refit_bic" (eq. 5.17), "naive_bic" (eq. 4.11) |
For time series, use RSO(criterion="cv", cv=TimeSeriesSplit(5)).
Main parameters
RSO
| parameter | default | meaning |
|---|---|---|
tau |
None |
fixed budget; None tunes over taus |
taus |
p * logspace(0.05, 50, 30) |
candidate budgets (X standardized) |
criterion |
"profile_bic" |
how tau is chosen |
refit |
True |
final coefficients by OLS on the selected predictors |
select_threshold |
1e-2 |
gamma_k above this means selected |
PLM / GPLM
| parameter | default | meaning |
|---|---|---|
taus1, taus2 |
log grids (12 x 8 / 8 x 5) | budgets for gamma and lambda |
criterion |
see table above | how the budgets are chosen |
refit |
True |
final fit without the ridge penalty on the selected model |
family (GPLM) |
"binomial" |
"binomial", "poisson", "gaussian" |
max_sweeps |
5 / 9 |
coordinate descent passes |
Shared optimizer settings: grid=(0, .2, .5, .8, 1), tol=1e-4, standardize=True.
After fitting, path_ holds every budget on the grid with its gamma, lambda,
selected sets and criterion values, which is enough to draw solution paths.
Reproducing the published results
The defaults implement the estimators as written in the papers. Setting
r_compat=True reproduces the original R implementation used for the numerical results
in the papers; the test suite checks this line by line against ports of the R functions.
The two modes differ in:
| default | r_compat=True |
|
|---|---|---|
| local constant kernel | product Gaussian | exp(-(sum_j lambda_j abs(dz_j))^2) |
| GPLM weights in the beta step | W |
sqrt(W / sum W) |
| GPLM weights in the smoother | sample weights w_k |
unweighted |
| GPLM BIC | -2 loglik + log(n) df |
-loglik + log(n) df |
| GPLM refit bandwidths | selected lambda |
uniform over selected predictors |
| standardization | X scaled, Z centered and scaled | none |
Tests
pip install -e ".[test]"
pytest
References
If you use this package, please cite:
- Wu, Y. (2021). Can't ridge regression perform variable selection? Technometrics, 63(2), 263–271. https://doi.org/10.1080/00401706.2020.1791254
- Lu, Y., Dong, Y., Hu, J. and Wu, Y. (2024). A unified approach to variable selection for partially linear models. Journal of Computational and Graphical Statistics, 33(1). https://doi.org/10.1080/10618600.2023.2216254
- Lu, Y., Hu, J. and Wu, Y. (2025). A new approach to select linear and nonparametric predictors simultaneously for generalised partially linear models. Journal of Nonparametric Statistics, 37(4), 1298–1316. https://doi.org/10.1080/10485252.2025.2556412
@article{wu2021ridge,
author = {Wu, Yichao},
title = {Can't Ridge Regression Perform Variable Selection?},
journal = {Technometrics},
volume = {63},
number = {2},
pages = {263--271},
year = {2021},
doi = {10.1080/00401706.2020.1791254}
}
@article{lu2024plm,
author = {Lu, Youhan and Dong, Yushen and Hu, Juan and Wu, Yichao},
title = {A Unified Approach to Variable Selection for Partially Linear Models},
journal = {Journal of Computational and Graphical Statistics},
volume = {33},
number = {1},
year = {2024},
doi = {10.1080/10618600.2023.2216254}
}
@article{lu2025gplm,
author = {Lu, Youhan and Hu, Juan and Wu, Yichao},
title = {A New Approach to Select Linear and Nonparametric Predictors Simultaneously
for Generalised Partially Linear Models},
journal = {Journal of Nonparametric Statistics},
volume = {37},
number = {4},
pages = {1298--1316},
year = {2025},
doi = {10.1080/10485252.2025.2556412}
}
An R implementation of linear RSO by other authors is available on CRAN as RSO.
License
BSD 3-Clause. See LICENSE.
Metadata
Release files for rsoselect 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| rsoselect-0.2.1.tar.gz | 25.2 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rsoselect-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 48.3 kB
Release files / rsoselect-0.2.1.tar.gz
| Download URL | rsoselect-0.2.1.tar.gz |
|---|---|
| Size | 25.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4c91779abb29159f1ac2ebc360574eaa614ce3bd19baed362aaf7f2b96851e94
|
|
BLAKE2b-256 checksum How to use checksums |
40b10e05366cd11601f48015bfb842ea4f09d1aca8eb549ef42a86a2302a7c9b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logRelease files / rsoselect-0.2.1-py3-none-any.whl
| Download URL | rsoselect-0.2.1-py3-none-any.whl |
|---|---|
| Size | 23.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0c60f226090e021529539532c332d3c1eb059041c8dfbc2cac8c3cf0d462b9f1
|
|
BLAKE2b-256 checksum How to use checksums |
492c3a13a3264cc4dabf8af4509e65c87e54d33ae2ea7c87785c8c5c5f6801e1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logSecurity for rsoselect 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for rsoselect-0.2.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.