Quickstart
Install beamfeat, fit a model and read what it prints. Every example runs as shown, and the outputs are from real runs. The Getting started tutorial covers the same ground in a notebook.
Install
pip install beamfeat # core: numpy, scikit-learn, joblib
pip install "beamfeat[units]" # + pint, for dimensional analysis
pip install "beamfeat[display]" # + sympy, for to_sympy() and latex()
pip install "beamfeat[all]" # + both, pandas and the test dependencies
See Installation for running the test suite or reproducing the benchmarks.
Sixty seconds to a vetted equation
import numpy as np
from beamfeat import BeamFeatRegressor
rng = np.random.default_rng(0)
X = rng.uniform(1, 6, (400, 4))
y = X[:, 0] * X[:, 1] + rng.normal(0, 0.05, 400)
model = BeamFeatRegressor(max_depth=2, beam_width=25, random_state=0).fit(X, y)
print(model.equation())
print(model.fdr_controlled_)
y = 0.9999*(x0 * x1) - 0.003943 [1 of 25 certified terms; parsimony=None prints all 25]
True
Three things matter. equation() is the fitted model itself — evaluate it on
raw feature values and you reproduce predict(). fdr_controlled_ states
whether the features carry the false-discovery-rate guarantee; check it before
treating them as statistically vetted. And the suffix says that those two do
not describe the same set of terms;
Reading a fit
explains it.
That last point has an attribute as well as a suffix, because a script never reads the printed string:
print(model.fdr_controlled_, "|", model.fdr_scope_)
True | screened set
fdr_controlled_ says whether there is a guarantee. fdr_scope_ says what it
is over: "screened set" when the printed terms were pruned from a larger
certified set, "printed equation" when the guarantee covers the terms you
are looking at, None when there is no guarantee to scope. Branch on
fdr_scope_, not on the equation text.
Column names flow into formulas
Fit on a DataFrame and formulas use your names:
import pandas as pd
df = pd.DataFrame({"mass": rng.uniform(1, 5, 300),
"vol": rng.uniform(1, 5, 300)})
target = df["mass"] / df["vol"] + rng.normal(0, 0.02, 300)
print(BeamFeatRegressor(random_state=0).fit(df, target).formulas())
['(mass / vol)']
Classification
BeamFeatClassifier prints the log-odds of the positive class, whose zero
level set is the decision boundary:
from beamfeat import BeamFeatClassifier
labels = (X[:, 0] * X[:, 1] > X[:, 2] * X[:, 3]).astype(int)
clf = BeamFeatClassifier(max_depth=2, random_state=0).fit(X, labels)
print(clf.equation(max_terms=3))
logit P(y = 1) = 1.678*((x0 / x2) - log(x3)) - 0.1561*((x2 * x3) - (x0 * x1)) - 1.014*((x2 / x1) + (x3 / x0)) + 1.101 [20 of 50 certified terms; parsimony=None prints all 50; parsimony_alpha=0.05 prints 2]
The fitted equation has 20 terms; max_terms=3 displays the three with the
largest standardised coefficients and holds the rest at their training mean.
With parsimony_alpha=0.05 the model itself has two terms, and its accuracy
on 2,000 new rows is about the same, 0.981 against 0.979:
short = BeamFeatClassifier(max_depth=2, random_state=0, parsimony_alpha=0.05).fit(X, labels)
print(short.equation())
logit P(y = 1) = - 0.526*((x2 * x3) - (x0 * x1)) - 1.005*((x2 / x0) + (x3 / x1)) + 2.455 [2 of 50 certified terms; parsimony=None prints all 50]
Next
- Choosing a setting: the default for prediction,
parsimony_alphafor a short equation,input_testfor an equation whose every column was tested, and the options for tall data, switches and weak terms. - User guide: reading a fit, the printed equation, the search options, data and prediction, and screening another tool's equation.
- Tutorials: four notebooks with real outputs.
- Statistical guarantees: what the guarantee covers, and what was measured.