Skip to main content

Neural Symbolic Regression engine: GRU policy + REINFORCE + lambda-sweep Pareto front

Project description

nsr-engine

Neural Symbolic Regression engine: a GRU policy trained with risk-seeking REINFORCE (Petersen et al. 2021) that discovers closed-form mathematical expressions from data.

Single-objective training is turned into a Pareto front by sweeping a complexity penalty λ over a log-spaced grid and pooling all discovered expressions.

Install

pip install nsr-engine                  # core (numpy, pandas, torch)
pip install "nsr-engine[sympy]"         # + sympy for human-readable formulas
pip install "nsr-engine[memmap,sympy]"  # + pyarrow for out-of-core fit_memmap

From source:

git clone https://github.com/kpapmath/nsr-engine
cd nsr-engine
pip install -e ".[sympy,memmap,dev]"

Quick start

import pandas as pd
import numpy as np
from nsr_engine import NSREngine

rng = np.random.default_rng(0)
n = 5000
a = rng.standard_normal(n)
b = rng.standard_normal(n)
X = pd.DataFrame({"a": a, "b": b})
y = pd.Series(0.5 * a + 0.3 * b + 0.05 * rng.standard_normal(n))

engine = NSREngine(
    n_lambda=8,       # number of lambda values to sweep
    n_iters=300,      # REINFORCE iterations per lambda
    batch_size=64,    # expressions sampled per iteration
    max_len=10,       # maximum token sequence length
    score_metric="mse",  # "mse", "rmse", "mae", "mape", "mbd", "r2", or "adjusted_r2"
    random_state=42,
)
front = engine.fit(X, y)

print(front.to_frame())
print("elbow formula:", front.elbow().equation)

Full pipeline example

The repository includes a runnable end-to-end pipeline that generates data or loads a CSV, optionally runs holdout, K-fold, or time-series validation, trains the engine, prints the Pareto front, and selects the elbow formula.

python main.py

The example wrapper and package module entry point are equivalent:

python examples/full_pipeline.py
python -m nsr_engine.main

By default the example uses the entire dataset for the final fit (--validation-mode none). Add --validation-mode sequential for a single chronological train/test split:

python main.py --validation-mode sequential --train-frac 0.8 --test-frac 0.2

K-fold, expanding-window, walk-forward, and blocked time-series validation are also available:

python main.py --validation-mode k-fold --folds 5
python main.py --validation-mode expanding-window --folds 5
python main.py --validation-mode walk-forward --folds 5
python main.py --validation-mode blocked-time-series --folds 5

Validation modes:

Mode Behavior
none Fit the final Pareto front on all rows. This is the default.
sequential Chronological single train/test split; past rows train, immediately subsequent rows test.
holdout Single train/test split like sequential, but may be randomized with --shuffle.
k-fold K-fold validation; folds are ordered by default and randomized only with --shuffle.
expanding-window Expanding-window time-series validation; each fold adds more historical rows to training.
walk-forward Alias-style walk-forward mode using the same expanding training window behavior.
blocked-time-series Contiguous non-overlapping train/validation blocks; each validation block immediately follows its training block.

For a quicker smoke run:

python main.py --iters 20 --lambdas 3 --rows 1000

To run on your own CSV data, provide the target column and optionally a comma-separated feature list:

python main.py --input-csv data.csv --target-col y --feature-cols a,b,c

After installation, the same CLI is available as:

nsr-engine
nsr-engine --help

Every command-line input, with its default and available options, is documented in the CLI reference.

Pipeline case examples

Functional examples for each distinct pipeline path are split into standalone scripts. See docs/pipeline_examples.md for the full summary.

python examples/generated_train_test.py
python examples/generated_validation.py
python examples/csv_input.py
python examples/custom_metric_library.py
python examples/cached_run.py
python examples/memmap_out_of_core.py

The defaults are small CPU-sized smoke examples; increase --iters, --lambdas, and --rows for stronger searches.

Token grammar

Type Tokens
Binary ops + - * /
Unary ops square abs log (default)
Constants -1.0 -0.5 0.5 1.0 2.0
Variables column names of input X

Sequences are in prefix (Polish) notation; the arity-tracking constraint guarantees every sampled sequence is a valid, complete expression tree.

The default unary set is square, abs, log. Many more are available on opt-in via unary_ops=[...] (or --unary-ops): sqrt, cbrt, exp, log10, log2, sin, cos, tan, sinh, cosh, tanh, arcsin, arccos, arctan, arcsinh, arctanh, sigmoid, neg, sign, cube, and reciprocal. See the CLI reference for the full list and each operator's numeric behavior.

Out-of-core training

For datasets too large to fit in RAM, build a MemmapDataset from Parquet files and use fit_memmap:

from nsr_engine.memmap_store import build_memmap_dataset

store = build_memmap_dataset(
    files=list(Path("data/").glob("*.parquet")),
    feature_cols=["a", "b", "c"],
    target_col="y",
    memmap_path=Path("cache/train.mmap"),
)

front = engine.fit_memmap(store, train_lo=0, train_hi=store.n_rows)

Key parameters

Parameter Default Description
n_lambda 10 Lambda grid size
lambda_min / lambda_max 1e-4 / 1e-1 Lambda sweep range
n_iters 200 REINFORCE iters per lambda
batch_size 64 Expressions per iteration
max_len 15 Max token sequence length
elite_frac 0.05 Risk-seeking quantile ε
entropy_weight 0.005 Entropy bonus coefficient
standardize True Z-score features before training
affine_reward True Score residuals after a least-squares affine fit
score_metric "mse" Accuracy metric: "mse", "rmse", "mae", "mape", "mbd", "r2", or "adjusted_r2"
cache_dir None Cache lambda runs to disk (JSON)

Scoring metrics

score_metric controls how expressions are ranked after the optional affine fit b0 + b1 * expression.

Value Meaning Direction
"mse" Mean squared error Lower is better
"rmse" Root mean squared error Lower is better
"mae" Mean absolute error Lower is better
"mape" Mean absolute percentage error, reported as percent Lower is better
"mbd" Absolute mean bias deviation Lower is better
"r2" Coefficient of determination Higher is better
"adjusted_r2" Adjusted R squared using one effective predictor Higher is better

For r2 and adjusted_r2, front.to_frame() reports the actual R squared value while Pareto dominance maximizes it internally.

Reference

Petersen et al. (2021). Deep Symbolic Regression: Recovering Mathematical Expressions from Data via Risk-Seeking Policy Gradients. ICLR 2021.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nsr_engine-0.2.0.tar.gz (33.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nsr_engine-0.2.0-py3-none-any.whl (31.0 kB view details)

Uploaded Python 3

File details

Details for the file nsr_engine-0.2.0.tar.gz.

File metadata

  • Download URL: nsr_engine-0.2.0.tar.gz
  • Upload date:
  • Size: 33.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nsr_engine-0.2.0.tar.gz
Algorithm Hash digest
SHA256 cc8559aba385e6ee74740bcada36265bbc2dcdd30e9d86566e8c91e0ea1cf72b
MD5 360428588e62741cbbf95085754cd1ac
BLAKE2b-256 4d71b3bd2c843d733e10ab627b5593c1a70d00b19933fc3820ede8a074d53590

See more details on using hashes here.

Provenance

The following attestation bundles were made for nsr_engine-0.2.0.tar.gz:

Publisher: publish.yml on kpapmath/nsr-engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nsr_engine-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: nsr_engine-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 31.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nsr_engine-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 13deb4ceca7f03b2e3f7bce821f6e1aff2dbc0a3aafa3015d389c99cc08a83cb
MD5 ede4ef75f82e35da755b75f328d58337
BLAKE2b-256 fac212686a7e2097a57695de21da4c00889060b3a039a0c3ff531ca90b505afd

See more details on using hashes here.

Provenance

The following attestation bundles were made for nsr_engine-0.2.0-py3-none-any.whl:

Publisher: publish.yml on kpapmath/nsr-engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page