svemnet 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,30 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ schedule:
8
+ - cron: "17 6 3 * *" # monthly canary against latest deps
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ${{ matrix.os }}
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ os: [ubuntu-latest]
18
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
19
+ include:
20
+ - os: windows-latest
21
+ python-version: "3.13"
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ - uses: actions/setup-python@v5
25
+ with:
26
+ python-version: ${{ matrix.python-version }}
27
+ - name: Install
28
+ run: python -m pip install -e ".[test]"
29
+ - name: Test
30
+ run: python -m pytest tests -q
@@ -0,0 +1,39 @@
1
+ name: Release to PyPI
2
+
3
+ # Releasing is: git tag v0.1.0 && git push origin v0.1.0
4
+ # Requires a PyPI "trusted publisher" configured for this repository and a
5
+ # GitHub environment named "pypi" (see RELEASING.md).
6
+
7
+ on:
8
+ push:
9
+ tags: ["v*"]
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.12"
19
+ - name: Build sdist and wheel
20
+ run: |
21
+ python -m pip install build
22
+ python -m build
23
+ - uses: actions/upload-artifact@v4
24
+ with:
25
+ name: dist
26
+ path: dist/
27
+
28
+ publish:
29
+ needs: build
30
+ runs-on: ubuntu-latest
31
+ environment: pypi
32
+ permissions:
33
+ id-token: write # PyPI trusted publishing
34
+ steps:
35
+ - uses: actions/download-artifact@v4
36
+ with:
37
+ name: dist
38
+ path: dist/
39
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,12 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .venv/
5
+ venv/
6
+ build/
7
+ dist/
8
+ .pytest_cache/
9
+ .coverage
10
+ htmlcov/
11
+ .ipynb_checkpoints/
12
+ validation/output/
@@ -0,0 +1,47 @@
1
+ cff-version: 1.2.0
2
+ message: >-
3
+ If you use this software, please cite the SVEMnet paper (preferred
4
+ citation below) for the software and Lemkus et al. (2021) for the SVEM
5
+ method.
6
+ type: software
7
+ title: "svemnet: Self-Validated Ensemble Models (SVEM) for Python"
8
+ authors:
9
+ - family-names: Karl
10
+ given-names: Andrew T.
11
+ email: akarl@asu.edu
12
+ orcid: "https://orcid.org/0000-0002-5933-8706"
13
+ license: MIT
14
+ repository-code: "https://github.com/akarl46556/svemnet-python"
15
+ keywords:
16
+ - SVEM
17
+ - self-validated ensemble models
18
+ - design of experiments
19
+ - lasso
20
+ - elastic net
21
+ - forward selection
22
+ - chemometrics
23
+ preferred-citation:
24
+ type: article
25
+ title: "SVEMnet: Self-Validated Ensemble Models in R"
26
+ authors:
27
+ - family-names: Karl
28
+ given-names: Andrew T.
29
+ journal: "Chemometrics and Intelligent Laboratory Systems"
30
+ year: 2026
31
+ doi: 10.1016/j.chemolab.2026.105660
32
+ references:
33
+ - type: article
34
+ title: "Self-Validated Ensemble Models for design of experiments"
35
+ authors:
36
+ - family-names: Lemkus
37
+ given-names: Trent
38
+ - family-names: Gotwalt
39
+ given-names: Christopher
40
+ - family-names: Ramsey
41
+ given-names: Philip
42
+ - family-names: Weese
43
+ given-names: Maria L.
44
+ journal: "Chemometrics and Intelligent Laboratory Systems"
45
+ volume: 219
46
+ year: 2021
47
+ doi: 10.1016/j.chemolab.2021.104439
svemnet-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andrew T. Karl
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
svemnet-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,168 @@
1
+ Metadata-Version: 2.4
2
+ Name: svemnet
3
+ Version: 0.1.0
4
+ Summary: Self-Validated Ensemble Models (SVEM) for small-sample design-of-experiments regression: SVEM lasso / elastic net and SVEM forward selection with validation-weighted information criteria.
5
+ Project-URL: Homepage, https://github.com/akarl46556/svemnet-python
6
+ Project-URL: Source, https://github.com/akarl46556/svemnet-python
7
+ Project-URL: Issues, https://github.com/akarl46556/svemnet-python/issues
8
+ Project-URL: R package (CRAN), https://CRAN.R-project.org/package=SVEMnet
9
+ Project-URL: SVEMnet paper (Karl 2026), https://doi.org/10.1016/j.chemolab.2026.105660
10
+ Project-URL: SVEM method paper (Lemkus 2021), https://doi.org/10.1016/j.chemolab.2021.104439
11
+ Project-URL: Whole-model test (Karl 2024), https://doi.org/10.1016/j.chemolab.2024.105122
12
+ Author-email: "Andrew T. Karl" <akarl@asu.edu>
13
+ License-Expression: MIT
14
+ License-File: LICENSE
15
+ Keywords: DOE,JMP,SVEM,SVEMnet,chemometrics,design of experiments,elastic net,forward selection,fractional random weights,lasso,self-validated ensemble,small sample
16
+ Classifier: Development Status :: 4 - Beta
17
+ Classifier: Intended Audience :: Science/Research
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Scientific/Engineering
25
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
26
+ Requires-Python: >=3.10
27
+ Requires-Dist: numpy>=1.24
28
+ Requires-Dist: scikit-learn>=1.6
29
+ Provides-Extra: formula
30
+ Requires-Dist: formulaic>=1.1; extra == 'formula'
31
+ Requires-Dist: pandas>=2.0; extra == 'formula'
32
+ Provides-Extra: test
33
+ Requires-Dist: formulaic>=1.1; extra == 'test'
34
+ Requires-Dist: pandas>=2.0; extra == 'test'
35
+ Requires-Dist: pytest>=8; extra == 'test'
36
+ Description-Content-Type: text/markdown
37
+
38
+ # svemnet — Self-Validated Ensemble Models (SVEM) for Python
39
+
40
+ **SVEM regression for small-sample design of experiments (DOE):** lasso /
41
+ elastic-net and forward-selection ensembles tuned by validation-weighted
42
+ information criteria, with bootstrap prediction intervals.
43
+
44
+ `svemnet` is the Python implementation of the Self-Validated Ensemble Model
45
+ method (Lemkus, Gotwalt, Ramsey, and Weese 2021) by the author of the
46
+ [R package SVEMnet](https://CRAN.R-project.org/package=SVEMnet). SVEM is
47
+ designed for the small-*n*, wide-model regime typical of designed
48
+ experiments — mixture formulations, process optimization, chemometrics —
49
+ where cross-validation is unstable: instead of holding data out, every run
50
+ appears in *both* the training and validation roles through anti-correlated
51
+ fractional random weights, and predictions are ensembled across bootstrap
52
+ replicates.
53
+
54
+ ## Install
55
+
56
+ ```bash
57
+ pip install svemnet # core: numpy + scikit-learn
58
+ pip install "svemnet[formula]" # + R-style formula interface (formulaic, pandas)
59
+ ```
60
+
61
+ ## Quickstart (formula interface, closest to R / JMP)
62
+
63
+ ```python
64
+ import pandas as pd
65
+ import svemnet
66
+
67
+ df = pd.read_csv("experiment.csv") # columns: y, X1, X2, X3, ...
68
+
69
+ # SVEM with lasso / elastic-net base learners (the SVEMnet default)
70
+ model = svemnet.svem("y ~ (X1 + X2 + X3)**2 + I(X1**2)", df, seed=1)
71
+ preds = model.predict(new_df)
72
+
73
+ # SVEM with forward-selection base learners
74
+ model = svemnet.svem("y ~ (X1 + X2 + X3)**2", df, method="forward", seed=1)
75
+ model.selection_frequencies # per-term bootstrap selection rates
76
+ model.coef_table() # coefficients + % bootstraps nonzero
77
+
78
+ # Bootstrap percentile intervals
79
+ out = model.predict(new_df, interval=True, level=0.90)
80
+ out["fit"], out["lwr"], out["upr"]
81
+
82
+ # Deterministic forward selection by AICc (single-model benchmark)
83
+ bench = svemnet.forward_aicc("y ~ (X1 + X2 + X3)**2", df)
84
+ bench.selected_terms
85
+ ```
86
+
87
+ Categorical predictors: mark them as pandas `Categorical` (or leave them as
88
+ strings) and they are treatment-coded automatically, like R factors. Their
89
+ contrast columns enter and leave forward-selection paths **together** as
90
+ whole effects.
91
+
92
+ `(X1 + X2 + X3)**2` expands to main effects plus two-way interactions,
93
+ matching R's `(X1 + X2 + X3)^2`. The helper
94
+ `svemnet.response_surface_formula("y", continuous=["X1","X2"], nominal=["F"])`
95
+ builds standard response-surface formulas.
96
+
97
+ ## Quickstart (scikit-learn interface)
98
+
99
+ ```python
100
+ from svemnet import SVEMRegressor
101
+
102
+ est = SVEMRegressor(method="forward", n_boot=200, random_state=0)
103
+ est.fit(X, y) # numeric matrix, no intercept column
104
+ y_pred = est.predict(X_new)
105
+ y_pred, intervals = est.predict_interval(X_new, confidence_level=0.9)
106
+ ```
107
+
108
+ `SVEMRegressor` is a conformant scikit-learn estimator: it works in
109
+ `Pipeline`, `cross_val_score`, and `GridSearchCV`, and handles categoricals
110
+ the scikit-learn way (`ColumnTransformer` / `OneHotEncoder`).
111
+
112
+ ## Coming from R SVEMnet or JMP
113
+
114
+ | R SVEMnet | svemnet (Python) |
115
+ |---|---|
116
+ | `SVEMnet(y ~ ..., data)` | `svemnet.svem("y ~ ...", df)` |
117
+ | `svem_forward(y ~ ..., data)` | `svemnet.svem("y ~ ...", df, method="forward")` |
118
+ | `forward_aicc(y ~ ..., data)` | `svemnet.forward_aicc("y ~ ...", df)` |
119
+ | `predict(fit, newdata, se.fit=, interval=)` | `model.predict(new_df, se_fit=, interval=)` |
120
+ | `coef(fit)` / `svem_nonzero(fit)` | `model.coef_table()` |
121
+ | `bigexp_terms(...)` | `svemnet.response_surface_formula(...)` |
122
+ | `objective = "wAIC"/"wBIC"/"wSSE"` | same |
123
+ | `weight_scheme = "SVEM"/"FRW_plain"/"Identity"` | same |
124
+ | `debias = TRUE` at predict | `debias=True` at fit or predict |
125
+
126
+ The Gaussian fitting mathematics match the published SVEM conventions used
127
+ by the R package: anti-correlated FRW train/validation weights rescaled to
128
+ mean one, validation-weighted wSSE/wAIC/wBIC path selection with the Kish
129
+ effective-sample-size admissibility guardrail, intercept-only fallback,
130
+ coefficient averaging across the ensemble, and optional linear debiasing.
131
+ The forward-selection engines here and the R functions `forward_aicc()` /
132
+ `svem_forward()` (SVEMnet ≥ 3.5.0) are ports of the same reference
133
+ implementation and validate against each other numerically. The lasso /
134
+ elastic-net base learners use scikit-learn's coordinate descent rather than
135
+ glmnet, so individual path fits can differ slightly in lambda gridding;
136
+ ensemble predictions agree closely in practice.
137
+
138
+ **Scope.** This package is intentionally minimal: Gaussian responses,
139
+ lasso/elastic-net and forward-selection base learners, prediction with
140
+ bootstrap uncertainty. For binomial responses, whole-model significance
141
+ testing, mixture-constrained random-search optimization, and
142
+ Thompson-sampling batch design, use the
143
+ [R package SVEMnet](https://CRAN.R-project.org/package=SVEMnet); JMP Pro
144
+ users have SVEM built into Generalized Regression.
145
+
146
+ ## References
147
+
148
+ - Lemkus, T., Gotwalt, C., Ramsey, P., & Weese, M. L. (2021). Self-Validated
149
+ Ensemble Models for design of experiments. *Chemometrics and Intelligent
150
+ Laboratory Systems*, 219, 104439.
151
+ [doi:10.1016/j.chemolab.2021.104439](https://doi.org/10.1016/j.chemolab.2021.104439)
152
+ - Karl, A. T. (2024). A randomized permutation whole-model test for SVEM.
153
+ *Chemometrics and Intelligent Laboratory Systems*, 249, 105122.
154
+ [doi:10.1016/j.chemolab.2024.105122](https://doi.org/10.1016/j.chemolab.2024.105122)
155
+ - Karl, A. T. (2026). SVEMnet: Self-Validated Ensemble Models in R.
156
+ *Chemometrics and Intelligent Laboratory Systems*.
157
+ [doi:10.1016/j.chemolab.2026.105660](https://doi.org/10.1016/j.chemolab.2026.105660)
158
+ - Xu, L., Gotwalt, C., Hong, Y., King, C. B., & Meeker, W. Q. (2020).
159
+ Applications of the fractional-random-weight bootstrap. *The American
160
+ Statistician*, 74(4), 345–358.
161
+ [doi:10.1080/00031305.2020.1731599](https://doi.org/10.1080/00031305.2020.1731599)
162
+
163
+ If you use this package in published work, please cite Lemkus et al. (2021)
164
+ for the method and Karl (2026) for the software.
165
+
166
+ ## License
167
+
168
+ MIT. Copyright (c) 2026 Andrew T. Karl.
@@ -0,0 +1,131 @@
1
+ # svemnet — Self-Validated Ensemble Models (SVEM) for Python
2
+
3
+ **SVEM regression for small-sample design of experiments (DOE):** lasso /
4
+ elastic-net and forward-selection ensembles tuned by validation-weighted
5
+ information criteria, with bootstrap prediction intervals.
6
+
7
+ `svemnet` is the Python implementation of the Self-Validated Ensemble Model
8
+ method (Lemkus, Gotwalt, Ramsey, and Weese 2021) by the author of the
9
+ [R package SVEMnet](https://CRAN.R-project.org/package=SVEMnet). SVEM is
10
+ designed for the small-*n*, wide-model regime typical of designed
11
+ experiments — mixture formulations, process optimization, chemometrics —
12
+ where cross-validation is unstable: instead of holding data out, every run
13
+ appears in *both* the training and validation roles through anti-correlated
14
+ fractional random weights, and predictions are ensembled across bootstrap
15
+ replicates.
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ pip install svemnet # core: numpy + scikit-learn
21
+ pip install "svemnet[formula]" # + R-style formula interface (formulaic, pandas)
22
+ ```
23
+
24
+ ## Quickstart (formula interface, closest to R / JMP)
25
+
26
+ ```python
27
+ import pandas as pd
28
+ import svemnet
29
+
30
+ df = pd.read_csv("experiment.csv") # columns: y, X1, X2, X3, ...
31
+
32
+ # SVEM with lasso / elastic-net base learners (the SVEMnet default)
33
+ model = svemnet.svem("y ~ (X1 + X2 + X3)**2 + I(X1**2)", df, seed=1)
34
+ preds = model.predict(new_df)
35
+
36
+ # SVEM with forward-selection base learners
37
+ model = svemnet.svem("y ~ (X1 + X2 + X3)**2", df, method="forward", seed=1)
38
+ model.selection_frequencies # per-term bootstrap selection rates
39
+ model.coef_table() # coefficients + % bootstraps nonzero
40
+
41
+ # Bootstrap percentile intervals
42
+ out = model.predict(new_df, interval=True, level=0.90)
43
+ out["fit"], out["lwr"], out["upr"]
44
+
45
+ # Deterministic forward selection by AICc (single-model benchmark)
46
+ bench = svemnet.forward_aicc("y ~ (X1 + X2 + X3)**2", df)
47
+ bench.selected_terms
48
+ ```
49
+
50
+ Categorical predictors: mark them as pandas `Categorical` (or leave them as
51
+ strings) and they are treatment-coded automatically, like R factors. Their
52
+ contrast columns enter and leave forward-selection paths **together** as
53
+ whole effects.
54
+
55
+ `(X1 + X2 + X3)**2` expands to main effects plus two-way interactions,
56
+ matching R's `(X1 + X2 + X3)^2`. The helper
57
+ `svemnet.response_surface_formula("y", continuous=["X1","X2"], nominal=["F"])`
58
+ builds standard response-surface formulas.
59
+
60
+ ## Quickstart (scikit-learn interface)
61
+
62
+ ```python
63
+ from svemnet import SVEMRegressor
64
+
65
+ est = SVEMRegressor(method="forward", n_boot=200, random_state=0)
66
+ est.fit(X, y) # numeric matrix, no intercept column
67
+ y_pred = est.predict(X_new)
68
+ y_pred, intervals = est.predict_interval(X_new, confidence_level=0.9)
69
+ ```
70
+
71
+ `SVEMRegressor` is a conformant scikit-learn estimator: it works in
72
+ `Pipeline`, `cross_val_score`, and `GridSearchCV`, and handles categoricals
73
+ the scikit-learn way (`ColumnTransformer` / `OneHotEncoder`).
74
+
75
+ ## Coming from R SVEMnet or JMP
76
+
77
+ | R SVEMnet | svemnet (Python) |
78
+ |---|---|
79
+ | `SVEMnet(y ~ ..., data)` | `svemnet.svem("y ~ ...", df)` |
80
+ | `svem_forward(y ~ ..., data)` | `svemnet.svem("y ~ ...", df, method="forward")` |
81
+ | `forward_aicc(y ~ ..., data)` | `svemnet.forward_aicc("y ~ ...", df)` |
82
+ | `predict(fit, newdata, se.fit=, interval=)` | `model.predict(new_df, se_fit=, interval=)` |
83
+ | `coef(fit)` / `svem_nonzero(fit)` | `model.coef_table()` |
84
+ | `bigexp_terms(...)` | `svemnet.response_surface_formula(...)` |
85
+ | `objective = "wAIC"/"wBIC"/"wSSE"` | same |
86
+ | `weight_scheme = "SVEM"/"FRW_plain"/"Identity"` | same |
87
+ | `debias = TRUE` at predict | `debias=True` at fit or predict |
88
+
89
+ The Gaussian fitting mathematics match the published SVEM conventions used
90
+ by the R package: anti-correlated FRW train/validation weights rescaled to
91
+ mean one, validation-weighted wSSE/wAIC/wBIC path selection with the Kish
92
+ effective-sample-size admissibility guardrail, intercept-only fallback,
93
+ coefficient averaging across the ensemble, and optional linear debiasing.
94
+ The forward-selection engines here and the R functions `forward_aicc()` /
95
+ `svem_forward()` (SVEMnet ≥ 3.5.0) are ports of the same reference
96
+ implementation and validate against each other numerically. The lasso /
97
+ elastic-net base learners use scikit-learn's coordinate descent rather than
98
+ glmnet, so individual path fits can differ slightly in lambda gridding;
99
+ ensemble predictions agree closely in practice.
100
+
101
+ **Scope.** This package is intentionally minimal: Gaussian responses,
102
+ lasso/elastic-net and forward-selection base learners, prediction with
103
+ bootstrap uncertainty. For binomial responses, whole-model significance
104
+ testing, mixture-constrained random-search optimization, and
105
+ Thompson-sampling batch design, use the
106
+ [R package SVEMnet](https://CRAN.R-project.org/package=SVEMnet); JMP Pro
107
+ users have SVEM built into Generalized Regression.
108
+
109
+ ## References
110
+
111
+ - Lemkus, T., Gotwalt, C., Ramsey, P., & Weese, M. L. (2021). Self-Validated
112
+ Ensemble Models for design of experiments. *Chemometrics and Intelligent
113
+ Laboratory Systems*, 219, 104439.
114
+ [doi:10.1016/j.chemolab.2021.104439](https://doi.org/10.1016/j.chemolab.2021.104439)
115
+ - Karl, A. T. (2024). A randomized permutation whole-model test for SVEM.
116
+ *Chemometrics and Intelligent Laboratory Systems*, 249, 105122.
117
+ [doi:10.1016/j.chemolab.2024.105122](https://doi.org/10.1016/j.chemolab.2024.105122)
118
+ - Karl, A. T. (2026). SVEMnet: Self-Validated Ensemble Models in R.
119
+ *Chemometrics and Intelligent Laboratory Systems*.
120
+ [doi:10.1016/j.chemolab.2026.105660](https://doi.org/10.1016/j.chemolab.2026.105660)
121
+ - Xu, L., Gotwalt, C., Hong, Y., King, C. B., & Meeker, W. Q. (2020).
122
+ Applications of the fractional-random-weight bootstrap. *The American
123
+ Statistician*, 74(4), 345–358.
124
+ [doi:10.1080/00031305.2020.1731599](https://doi.org/10.1080/00031305.2020.1731599)
125
+
126
+ If you use this package in published work, please cite Lemkus et al. (2021)
127
+ for the method and Karl (2026) for the software.
128
+
129
+ ## License
130
+
131
+ MIT. Copyright (c) 2026 Andrew T. Karl.
@@ -0,0 +1,66 @@
1
+ # Release checklist (for Andrew)
2
+
3
+ One-time setup, then each release is just a git tag.
4
+
5
+ ## One-time setup
6
+
7
+ 1. **Create the GitHub repository** (suggested name: `svemnet-python`, owner:
8
+ your GitHub account). Then the URLs below already point at `akarl46556`:
9
+ - `pyproject.toml` (`[project.urls]`)
10
+ - `CITATION.cff` (`repository-code`)
11
+ 2. **Push this repo**:
12
+ ```bash
13
+ git remote add origin https://github.com/akarl46556/svemnet-python.git
14
+ git push -u origin main
15
+ ```
16
+ CI (`.github/workflows/ci.yml`) runs the test suite on Python 3.10–3.13
17
+ (Linux) and 3.13 (Windows) on every push to `main` and on every pull
18
+ request, plus a monthly cron canary against the latest
19
+ numpy/scikit-learn.
20
+ 3. **PyPI trusted publisher** (no API tokens needed):
21
+ - Create/log into your account on https://pypi.org.
22
+ - Go to *Your projects → Publishing → Add a new pending publisher* and
23
+ register: project name `svemnet`, owner `akarl46556`, repository
24
+ `svemnet-python`, workflow `release.yml`, environment `pypi`.
25
+ - In the GitHub repo: *Settings → Environments → New environment* named
26
+ `pypi` (optionally require your review before deployments).
27
+ 4. **Cross-link from the R package** (optional but recommended): add a line
28
+ to the CRAN SVEMnet DESCRIPTION/README pointing to
29
+ `https://pypi.org/project/svemnet/`.
30
+
31
+ ## Each release
32
+
33
+ ```bash
34
+ # bump version in pyproject.toml and src/svemnet/__init__.py, commit, then:
35
+ git tag v0.1.0
36
+ git push origin v0.1.0
37
+ ```
38
+
39
+ The `release.yml` workflow builds the sdist/wheel and publishes to PyPI via
40
+ trusted publishing.
41
+
42
+ ## Re-running the R cross-validation
43
+
44
+ With the SVEMnet R package (>= 3.5.0) installed:
45
+
46
+ ```bash
47
+ Rscript validation/run_r_reference.R validation/output
48
+ python validation/compare_python.py validation/output
49
+ ```
50
+
51
+ Tier 1 (deterministic forward selection) and Tier 2 (SVEM forward with
52
+ injected FRW uniforms) must match R exactly; Tier 3 (lasso, cross-solver)
53
+ is statistical. See `validation/output/VALIDATION_REPORT.md`.
54
+
55
+ ## Later milestones (optional, low urgency)
56
+
57
+ - **conda-forge** (once the API feels stable): submit a grayskull-generated
58
+ recipe to conda-forge/staged-recipes; afterwards maintenance is merging
59
+ autotick-bot PRs.
60
+ - **JOSS paper** (6–12 months out): JOSS requires ~6 months of public
61
+ development history and demonstrated reuse; a JOSS DOI gives Python users
62
+ a natural citation target.
63
+ - **Scope guard**: the package is deliberately minimal (Gaussian; lasso/enet
64
+ + forward SVEM; prediction with bootstrap uncertainty). Point requests for
65
+ binomial, whole-model testing, optimization, etc. at the R package rather
66
+ than growing this one.