Skip to content

Add within-group lengthscale shrinkage prior for the strength GP - #20

Merged
SebastianAment merged 1 commit into
mainfrom
within-group-lengthscale-prior
May 13, 2026
Merged

Add within-group lengthscale shrinkage prior for the strength GP#20
SebastianAment merged 1 commit into
mainfrom
within-group-lengthscale-prior

Conversation

@SebastianAment

Copy link
Copy Markdown
Contributor

In the strength GP fit on the public dataset, the Matern ARD lengthscales for Fly Ash and Coarse Aggregates rail to the upper cap (~1000): both features are under-sampled relative to Cement and Fine Aggregate, so the marginal likelihood is essentially flat in their lengthscale direction and the optimiser drifts to the constraint boundary. This makes the strength surface look insensitive to those two ingredients in the explorer UI, even though concrete chemistry clearly says it isn't.

This PR introduces WithinGroupShrinkagePrior — a soft hard-tying prior that ties Matern ARD lengthscales within material groups. The production setting (sigma=0.001) ties members of {Cement, Fly Ash, Slag} to a single binder lengthscale, and {Fine, Coarse} aggregates to a single aggregate lengthscale, encoding the domain prior that ingredients of the same material class should share kernel smoothness. The structural prior:

  • Beats the no-prior baseline on held-out LOO CV RMSE — 725 vs 772 psi on the 647 public strength rows, via the GP's closed-form LOO identity.
  • Encodes only group structure (a public, ASTM-defined fact about cementitious vs aggregate materials), not any numeric values.
  • Makes Fly Ash and Coarse Aggregate sliders responsive in the explorer UI: both lengthscales now sit at 4.79 and 6.67 respectively, well below the cap and within the same range as the previously-identifiable features.

Adds 11 regression tests in test/test_lengthscale_identifiability.py covering identifiability against the cap, within-group tying on both the committed and freshly-fit GP, prior installation by fit_strength_gp, an LOO-CV ceiling that catches the no-prior baseline, and unit tests for the prior class. A reproducible empirical sweep (scripts/lengthscale_prior_study.py) lets users re-run the variant comparison on their own machine. docs/model/{strength,compositions, test_vectors}.json are regenerated with the new fit; the JS GP inference and JS<->Python parity tests stay green. All LOO computation re-uses boxcrete.compute_loo_cv (now also re-exported from the package root).

See WithinGroupShrinkagePrior docstring in boxcrete/models.py for the full empirical comparison and methodology.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 13, 2026
@SebastianAment
SebastianAment force-pushed the within-group-lengthscale-prior branch 2 times, most recently from 05eb009 to f54fb2e Compare May 13, 2026 20:59
In the strength GP fit on the public dataset, the Matern ARD
lengthscales for Fly Ash and Coarse Aggregates rail to the upper
cap (~1000): both features are under-sampled relative to Cement and
Fine Aggregate, so the marginal likelihood is essentially flat in
their lengthscale direction and the optimiser drifts to the constraint
boundary. This makes the strength surface look insensitive to those
two ingredients in the explorer UI, even though concrete chemistry
clearly says it isn't.

This PR introduces `WithinGroupShrinkagePrior` — a soft hard-tying
prior that ties Matern ARD lengthscales within material groups. The
production setting (`sigma=0.001`) ties members of {Cement, Fly Ash,
Slag} to a single binder lengthscale, and {Fine, Coarse} aggregates
to a single aggregate lengthscale, encoding the domain prior that
ingredients of the same material class should share kernel smoothness.
The structural prior:

  * Beats the no-prior baseline on held-out LOO CV RMSE — 725 vs
    772 psi on the 647 public strength rows, via the GP's closed-form
    LOO identity.
  * Encodes only group structure (a public, ASTM-defined fact about
    cementitious vs aggregate materials), not any numeric values.
  * Makes Fly Ash and Coarse Aggregate sliders responsive in the
    explorer UI: both lengthscales now sit at 4.79 and 6.67
    respectively, well below the cap and within the same range as
    the previously-identifiable features.

Adds 11 regression tests in `test/test_lengthscale_identifiability.py`
covering identifiability against the cap, within-group tying on both
the committed and freshly-fit GP, prior installation by
`fit_strength_gp`, an LOO-CV ceiling that catches the no-prior baseline,
and unit tests for the prior class. A reproducible empirical sweep
(`scripts/lengthscale_prior_study.py`) lets users re-run the variant
comparison on their own machine. `docs/model/{strength,compositions,
test_vectors}.json` are regenerated with the new fit; the JS GP
inference and JS<->Python parity tests stay green. All LOO computation
re-uses `boxcrete.compute_loo_cv` (now also re-exported from the
package root).

See `WithinGroupShrinkagePrior` docstring in `boxcrete/models.py` for
the full empirical comparison and methodology.
@SebastianAment
SebastianAment force-pushed the within-group-lengthscale-prior branch from f54fb2e to d617837 Compare May 13, 2026 21:08
@SebastianAment
SebastianAment merged commit 1017d7e into main May 13, 2026
19 checks passed
@SebastianAment
SebastianAment deleted the within-group-lengthscale-prior branch May 13, 2026 21:21
SebastianAment added a commit that referenced this pull request May 13, 2026
Brings every PR-blocking GitHub Actions check under a single `make` invocation
so contributors can reproduce CI locally before pushing.

Why
---
The Tests workflow installs `black` via `pip install black` (latest
available), which silently drifted from contributors' environments and
caused two force-pushes on #20 to chase formatting fixes the local
`black` couldn't see. CI also has four other workflows (js-sync, e2e,
notebooks, lighthouse) with no documented local equivalent.

What
----
* `Makefile` with one target per workflow:
  - `lint` / `test-py` / `test-js` / `test-notebook-fmt` (fast)
  - `test-notebooks` / `test-e2e` / `test-lighthouse` (slow)
  - `check` = lint + fast tests; `check-all` = full CI parity.
* `.pre-commit-config.yaml` runs the same black + flake8 checks that
  CI does, automatically on every commit.
* `pyproject.toml`: black bumped from `>=23.0.0` to `==26.3.1` (the
  current CI version) and `pre-commit` added to `[dev]` extras.
* `.github/workflows/tests.yml`: lint job now `pip install -e ".[dev]"`
  so CI uses the pinned version too — eliminates the drift class of
  failure.
* `CONTRIBUTING.md`: one-time setup, daily-use, before-push, and a
  per-target table mapping each Make target to its CI workflow.

Bumping black requires updating .pre-commit-config.yaml + pyproject.toml
+ running `make lint` in lockstep.
SebastianAment added a commit that referenced this pull request May 13, 2026
Brings every PR-blocking GitHub Actions check under a single `make` invocation
so contributors can reproduce CI locally before pushing.

Why
---
The Tests workflow installs `black` via `pip install black` (latest
available), which silently drifted from contributors' environments and
caused two force-pushes on #20 to chase formatting fixes the local
`black` couldn't see. CI also has four other workflows (js-sync, e2e,
notebooks, lighthouse) with no documented local equivalent.

What
----
* `Makefile` with one target per workflow:
  - `lint` / `test-py` / `test-js` / `test-notebook-fmt` (fast)
  - `test-notebooks` / `test-e2e` / `test-lighthouse` (slow)
  - `check` = lint + fast tests; `check-all` = full CI parity.
* `.pre-commit-config.yaml` runs the same black + flake8 checks that
  CI does, automatically on every commit.
* `pyproject.toml`: black bumped from `>=23.0.0` to `==26.3.1` (the
  current CI version) and `pre-commit` added to `[dev]` extras.
* `.github/workflows/tests.yml`: lint job now `pip install -e ".[dev]"`
  so CI uses the pinned version too — eliminates the drift class of
  failure.
* `CONTRIBUTING.md`: one-time setup, daily-use, before-push, and a
  per-target table mapping each Make target to its CI workflow.

Bumping black requires updating .pre-commit-config.yaml + pyproject.toml
+ running `make lint` in lockstep.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant