pybiglasso 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.
- pybiglasso-0.1.0/.gitignore +34 -0
- pybiglasso-0.1.0/.pre-commit-config.yaml +49 -0
- pybiglasso-0.1.0/AGENTS.md +118 -0
- pybiglasso-0.1.0/CLAUDE.md +1 -0
- pybiglasso-0.1.0/LICENSE +674 -0
- pybiglasso-0.1.0/Makefile +76 -0
- pybiglasso-0.1.0/PKG-INFO +422 -0
- pybiglasso-0.1.0/README.md +385 -0
- pybiglasso-0.1.0/benchmarks/out_of_core.py +288 -0
- pybiglasso-0.1.0/benchmarks/path.py +512 -0
- pybiglasso-0.1.0/benchmarks/plot.py +84 -0
- pybiglasso-0.1.0/benchmarks/profile_fit.py +18 -0
- pybiglasso-0.1.0/benchmarks/run-extra.sh +34 -0
- pybiglasso-0.1.0/benchmarks/run-path.sh +49 -0
- pybiglasso-0.1.0/benchmarks/start-path.sh +10 -0
- pybiglasso-0.1.0/docker/r-biglasso.Dockerfile +10 -0
- pybiglasso-0.1.0/examples/quickstart.py +58 -0
- pybiglasso-0.1.0/pyproject.toml +78 -0
- pybiglasso-0.1.0/scripts/check_wheel.py +10 -0
- pybiglasso-0.1.0/scripts/make_r_fixtures.py +72 -0
- pybiglasso-0.1.0/src/pybiglasso/__init__.py +24 -0
- pybiglasso-0.1.0/src/pybiglasso/binomial.py +1027 -0
- pybiglasso-0.1.0/src/pybiglasso/common.py +126 -0
- pybiglasso-0.1.0/src/pybiglasso/path.py +240 -0
- pybiglasso-0.1.0/src/pybiglasso/sklearn.py +282 -0
- pybiglasso-0.1.0/src/pybiglasso/viz.py +53 -0
- pybiglasso-0.1.0/tests/fixtures/r_biglasso.json.gz +0 -0
- pybiglasso-0.1.0/tests/r/fit_biglasso.R +126 -0
- pybiglasso-0.1.0/tests/rcompare.py +447 -0
- pybiglasso-0.1.0/tests/test_biglasso.py +302 -0
- pybiglasso-0.1.0/tests/test_default_enet.py +178 -0
- pybiglasso-0.1.0/tests/test_kernels.py +228 -0
- pybiglasso-0.1.0/tests/test_out_of_core.py +160 -0
- pybiglasso-0.1.0/tests/test_sklearn.py +122 -0
- pybiglasso-0.1.0/tests/test_solver_regressions.py +199 -0
- pybiglasso-0.1.0/tests/test_vs_r.py +74 -0
- pybiglasso-0.1.0/uv.lock +2859 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
.venv/
|
|
8
|
+
.pytest_cache/
|
|
9
|
+
.coverage
|
|
10
|
+
htmlcov/
|
|
11
|
+
.ipynb_checkpoints/
|
|
12
|
+
|
|
13
|
+
# editors and OS
|
|
14
|
+
*~
|
|
15
|
+
*.swp
|
|
16
|
+
.DS_Store
|
|
17
|
+
|
|
18
|
+
# project specific
|
|
19
|
+
py-vs-r*/
|
|
20
|
+
scratch/
|
|
21
|
+
scratch*
|
|
22
|
+
benchmarks/results/*.tmp
|
|
23
|
+
benchmarks/results/tmp/
|
|
24
|
+
# stored R output for the test suite (a global *.gz ignore would hide it)
|
|
25
|
+
!tests/fixtures/*.json.gz
|
|
26
|
+
benchmarks/results/*.aborted.*
|
|
27
|
+
benchmarks/results/*.failed.*
|
|
28
|
+
# Beads / Dolt files (added by bd init); beads stays local, untracked
|
|
29
|
+
.beads/
|
|
30
|
+
.dolt/
|
|
31
|
+
*.db
|
|
32
|
+
.beads-credential-key
|
|
33
|
+
.beads/proxieddb/
|
|
34
|
+
*.gate.lock*
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v6.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: check-added-large-files
|
|
6
|
+
args: [--maxkb=2000]
|
|
7
|
+
- id: check-case-conflict
|
|
8
|
+
- id: check-json
|
|
9
|
+
- id: check-merge-conflict
|
|
10
|
+
- id: check-toml
|
|
11
|
+
- id: check-yaml
|
|
12
|
+
- id: debug-statements
|
|
13
|
+
- id: detect-aws-credentials
|
|
14
|
+
args: [--allow-missing-credentials]
|
|
15
|
+
- id: detect-private-key
|
|
16
|
+
- id: end-of-file-fixer
|
|
17
|
+
- id: mixed-line-ending
|
|
18
|
+
args: [--fix=lf]
|
|
19
|
+
- id: name-tests-test
|
|
20
|
+
args: [--pytest-test-first]
|
|
21
|
+
# Helpers the tests import, not tests themselves
|
|
22
|
+
exclude: ^tests/(rcompare\.py|r/)
|
|
23
|
+
- id: trailing-whitespace
|
|
24
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
25
|
+
rev: v0.17.1
|
|
26
|
+
hooks:
|
|
27
|
+
- id: ruff
|
|
28
|
+
args: [--fix, --exit-non-zero-on-fix]
|
|
29
|
+
- id: ruff-format
|
|
30
|
+
# ruff-pre-commit 0.17 formats Markdown code blocks too; keep it to code.
|
|
31
|
+
types_or: [python, pyi, jupyter]
|
|
32
|
+
- repo: https://github.com/crate-ci/typos
|
|
33
|
+
rev: v1.46.0
|
|
34
|
+
hooks:
|
|
35
|
+
- id: typos
|
|
36
|
+
files: \.(md|txt)$
|
|
37
|
+
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
|
|
38
|
+
rev: v2.16.0
|
|
39
|
+
hooks:
|
|
40
|
+
- id: pretty-format-toml
|
|
41
|
+
args: [--autofix, --indent, '2']
|
|
42
|
+
# Pin the formatter: an unpinned one varies with when each machine's hook
|
|
43
|
+
# environment was built (toml-sort 0.24 and 0.25 space inline tables
|
|
44
|
+
# differently). The weekly update-pre-commit-hooks workflow bumps this pin.
|
|
45
|
+
additional_dependencies: [toml-sort==0.25.0]
|
|
46
|
+
# Lockfiles are machine-written; reformatting them only makes churn.
|
|
47
|
+
exclude: ^uv\.lock$
|
|
48
|
+
- id: pretty-format-yaml
|
|
49
|
+
args: [--autofix, --indent, '2']
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# pybiglasso — Contributor & Agent Guide
|
|
2
|
+
|
|
3
|
+
Guidance for anyone working in this repo, human or AI coding agent. This is the
|
|
4
|
+
canonical guide; `CLAUDE.md` is a symlink to this file so tool-specific loaders
|
|
5
|
+
pick up the same content. It follows the [AGENTS.md](https://agents.md) convention.
|
|
6
|
+
|
|
7
|
+
## Working in this repo
|
|
8
|
+
|
|
9
|
+
- **`main` is protected** — changes land through a pull request, not direct pushes.
|
|
10
|
+
- **Branch for each change**, and keep PRs focused.
|
|
11
|
+
- **Never force-push** `main` or any branch with an open PR.
|
|
12
|
+
- Never bypass pre-commit hooks with `--no-verify`; fix the underlying issue instead.
|
|
13
|
+
- Issues are tracked locally with beads (`bd`); `.beads/` is untracked and stays
|
|
14
|
+
on this machine.
|
|
15
|
+
|
|
16
|
+
## Matching R biglasso is the contract
|
|
17
|
+
|
|
18
|
+
pybiglasso is a port of R biglasso's logistic solver, and matches it to
|
|
19
|
+
floating-point precision: coefficients, lambda grid, centering and scaling,
|
|
20
|
+
strong-rule rejections, and the iteration count at every lambda. A change that
|
|
21
|
+
moves any of these, on a case where R's behavior is intended, is a regression.
|
|
22
|
+
|
|
23
|
+
Where R's behavior looks unintended, pybiglasso may differ, but only like this:
|
|
24
|
+
|
|
25
|
+
1. Mark the code with a comment beginning `Differs from R biglasso`, saying what R
|
|
26
|
+
does and why this differs. Keep the change as small and plain as possible.
|
|
27
|
+
2. Add an entry to the README's "Differences from R biglasso" section, in a
|
|
28
|
+
courteous register: state what R does and what pybiglasso does, without
|
|
29
|
+
verdicts.
|
|
30
|
+
3. Where feasible, keep R's behavior reachable with `r_compatible=True`.
|
|
31
|
+
4. Back the difference with a check that doesn't depend on R (optimality
|
|
32
|
+
conditions, another solver, an invariance).
|
|
33
|
+
|
|
34
|
+
## Expected values come from outside pybiglasso
|
|
35
|
+
|
|
36
|
+
Never run pybiglasso to generate or adjust expected values. Passing tests are
|
|
37
|
+
not evidence that their expectations are correct, and tolerances are not tuned
|
|
38
|
+
to observed output.
|
|
39
|
+
|
|
40
|
+
- **R output**: `tests/fixtures/r_biglasso.json.gz` holds R biglasso's results for
|
|
41
|
+
the comparison grid. Regenerate it only with `make fixtures`, which builds the
|
|
42
|
+
pinned R image (`FIXTURES_R` in the Makefile) and refuses output from any other
|
|
43
|
+
biglasso version (`FIXTURES_BIGLASSO` in `scripts/make_r_fixtures.py`). When
|
|
44
|
+
adding a case to `tests/rcompare.py`, check that the old code fails it if it is
|
|
45
|
+
meant to catch a regression.
|
|
46
|
+
- **Independent checks**: KKT conditions computed from first principles
|
|
47
|
+
(`tests/test_default_enet.py`), scikit-learn's saga solver, and invariances
|
|
48
|
+
such as shifting X.
|
|
49
|
+
|
|
50
|
+
## Dependency & toolchain versions
|
|
51
|
+
|
|
52
|
+
- **Python (uv)**: loose `pyproject.toml` constraints for users, and a committed
|
|
53
|
+
`uv.lock` that pins development and CI only (it never ships). CI installs from
|
|
54
|
+
the lock as committed (`UV_LOCKED=1`), and a latest-deps job tests the newest
|
|
55
|
+
versions `pyproject.toml` allows, which is what a new install gets.
|
|
56
|
+
- **R**: the R comparison runs in a container (`docker/r-biglasso.Dockerfile`),
|
|
57
|
+
pinned by R version; packages come from that R release's P3M snapshot.
|
|
58
|
+
- Supported Pythons are those not yet at end of life.
|
|
59
|
+
|
|
60
|
+
## Development Commands
|
|
61
|
+
|
|
62
|
+
- `make test` — fast suite, against stored R output (no R needed)
|
|
63
|
+
- `make test-r` — the same grid live against R, in a container
|
|
64
|
+
(`CONTAINER=podman` works too; `R_VERSION=latest` for current CRAN)
|
|
65
|
+
- `make soak` — larger memory-mapped problems against live R; for a big machine
|
|
66
|
+
- `make fixtures` — regenerate the stored R output (see above)
|
|
67
|
+
- `make run-hooks-all-files` — every pre-commit hook on every file
|
|
68
|
+
- `make profile` — where a fit spends its time (Python 3.15's sampling profiler)
|
|
69
|
+
- `benchmarks/run-path.sh`, `benchmarks/run-extra.sh` — the README's benchmarks
|
|
70
|
+
|
|
71
|
+
## Quality Gates
|
|
72
|
+
|
|
73
|
+
1. `make run-hooks-all-files`
|
|
74
|
+
2. `make test`
|
|
75
|
+
3. `make test-r`, for any change to the solver or the R comparison
|
|
76
|
+
|
|
77
|
+
## Python Style
|
|
78
|
+
|
|
79
|
+
- Use modern type hints (PEP 604 unions with `|`, generics without `typing` module)
|
|
80
|
+
- Prefer `pathlib.Path` over `os.path`
|
|
81
|
+
- Comment the why, not the what
|
|
82
|
+
- Use descriptive variable names over comments
|
|
83
|
+
- Keep functions focused and small
|
|
84
|
+
- Prefer explicit imports over star imports
|
|
85
|
+
|
|
86
|
+
## Architecture
|
|
87
|
+
|
|
88
|
+
- `src/pybiglasso/binomial.py` — the solver: `biglasso()`, the driver
|
|
89
|
+
(`binomial_hsr`, `_fit_lambda`), and one numba kernel per step. The README's
|
|
90
|
+
"How the code is organized" maps each kernel to R biglasso's C++.
|
|
91
|
+
- `src/pybiglasso/path.py` — `BiglassoPath`, the fitted path: prediction, scoring,
|
|
92
|
+
dataframe export
|
|
93
|
+
- `src/pybiglasso/sklearn.py` — `BiglassoClassifier`, `BiglassoClassifierCV`
|
|
94
|
+
- `tests/rcompare.py`, `tests/r/fit_biglasso.R` — the R comparison harness
|
|
95
|
+
- `benchmarks/` — in-memory and out-of-core benchmarks; results in
|
|
96
|
+
`benchmarks/results/`
|
|
97
|
+
|
|
98
|
+
## Key Patterns
|
|
99
|
+
|
|
100
|
+
- **Out of core**: X is read a column at a time, through the memmap, and never
|
|
101
|
+
loaded or copied; row subsets are index arrays into the same X.
|
|
102
|
+
- **Numba compiles each array type separately** (a read-only memmap is not a
|
|
103
|
+
writable array), so warm-ups must use the same type as the fit.
|
|
104
|
+
- **Reproducibility**: kernels sum in a fixed order (`dot`, `seqsum`), so results
|
|
105
|
+
are bit-identical at any thread count; don't replace them with `@` or `.sum()`.
|
|
106
|
+
|
|
107
|
+
## Public history
|
|
108
|
+
|
|
109
|
+
The repository is public. Keep internal and machine-identifying material out of
|
|
110
|
+
commits: no hostnames, home-directory paths, or employer-internal code or
|
|
111
|
+
templates. Benchmarks record the CPU and versions, not the host.
|
|
112
|
+
|
|
113
|
+
## Code Review Focus
|
|
114
|
+
|
|
115
|
+
- Agreement with R, and the iteration counts in particular
|
|
116
|
+
- Any new departure from R follows the rules above
|
|
117
|
+
- Memory: nothing that loads or copies X
|
|
118
|
+
- Thread-count reproducibility
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
AGENTS.md
|