API reference
Estimators
Bases: RegressorMixin, _BeamFeatBase
Constructs features, then fits a linear model on them.
The linear model is the point: its coefficients combine with the feature
formulas to give a closed-form expression for the fitted relationship,
available via :meth:equation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
alpha
|
float
|
Ridge regularisation strength for the downstream model. |
1.0
|
Other arguments match :class:BeamFeatTransformer.
Attributes:
| Name | Type | Description |
|---|---|---|
features_ |
Selected expressions. |
|
feature_formulas_ |
Their formula strings. |
|
model_ |
The fitted downstream linear model. |
|
coef_ |
Coefficients of the downstream model. |
|
intercept_ |
Intercept of the downstream model. |
equation(precision=4, max_terms=None)
Return the fitted model as a readable closed-form equation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
precision
|
int
|
Decimal places for the coefficients. |
4
|
max_terms
|
int | None
|
If set, include only the largest-magnitude terms. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
A string such as |
fit(X, y)
Construct features and fit the downstream model.
predict(X)
Predict using the constructed features and fitted model.
Bases: ClassifierMixin, _BeamFeatBase
Constructs features, then fits a logistic model on them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
C
|
float
|
Inverse regularisation strength for the downstream model. |
1.0
|
Other arguments match :class:BeamFeatTransformer.
Attributes:
| Name | Type | Description |
|---|---|---|
features_ |
Selected expressions. |
|
classes_ |
Class labels seen during fit. |
|
model_ |
The fitted downstream logistic model. |
decision_function(X)
Return the model's decision scores.
equation(precision=4, max_terms=None)
Return the fitted classifier as a readable log-odds equation.
For binary problems the single line gives the log-odds of the
positive class (classes_[1]): logit P(y = c1) = ..., so the
decision boundary is the zero level set of the right-hand side. For
multiclass problems one line is returned per class; these are the
softmax scores of the fitted multinomial model, and the predicted
class is the argmax across lines.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
precision
|
int
|
Decimal places for the coefficients. |
4
|
max_terms
|
int | None
|
If set, include only the largest-magnitude terms per line. |
None
|
fit(X, y)
Construct features and fit the downstream classifier.
predict(X)
Predict class labels.
predict_proba(X)
Predict class probabilities.
Bases: TransformerMixin, _BeamFeatBase
Constructs and selects features, for use inside a pipeline.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scorer
|
str | Scorer
|
Scoring strategy for the search. A name
( |
'correlation'
|
selector
|
str | Selector | None
|
FDR-controlled selector, or |
'permutation'
|
problem_type
|
str
|
|
'regression'
|
max_depth
|
int
|
Maximum expression depth. |
2
|
beam_width
|
int
|
Expressions retained at each search depth. |
50
|
max_features
|
int | None
|
Cap on features returned by the search, before selection. |
None
|
target_fdr
|
float
|
Nominal false discovery rate for the selector. |
0.1
|
unary_ops
|
tuple[str, ...]
|
Unary operators to apply. |
DEFAULT_UNARY
|
binary_ops
|
tuple[str, ...]
|
Binary operators to apply. |
DEFAULT_BINARY
|
redundancy_threshold
|
float
|
Absolute correlation above which a candidate is treated as a duplicate. |
0.95
|
include_originals
|
bool
|
Whether input columns compete alongside constructed expressions. |
True
|
units
|
dict[str, Any] | None
|
Optional mapping of input column name to pint quantity. Supplying units restricts the search to dimensionally valid expressions. |
None
|
random_state
|
int | None
|
Seed. Fitting is deterministic given this. |
0
|
verbose
|
int
|
If positive, log search progress. |
0
|
Attributes:
| Name | Type | Description |
|---|---|---|
features_ |
Selected :class: |
|
feature_formulas_ |
Their formula strings. |
|
search_result_ |
The :class: |
|
selection_result_ |
The :class: |
|
n_features_out_ |
Number of features produced. |
fit(X, y=None)
Construct and select features from the training data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
|
required | |
y
|
Target. Required, since both search and selection are supervised. |
None
|
Returns:
| Type | Description |
|---|---|
|
|
transform(X)
Evaluate the selected expressions on new data.
Selection
False-discovery-rate controlled feature selection.
Feature construction proposes far more candidates than any dataset can support, so selection is where spurious features are either excluded or silently admitted. This module provides selectors that control the false discovery rate — the expected proportion of selected features that are spurious — and is explicit about the assumptions under which each guarantee holds.
:class:PermutationSelector (default)
An exact permutation test of marginal association, corrected for
multiplicity. The test statistic is a fixed function of the data
(|Pearson correlation| for regression, eta-squared for classification),
so permuting the target yields exact p-values for the null hypothesis
that a feature is marginally independent of the target (Phipson & Smyth,
2010). Multiplicity is handled by Benjamini-Hochberg, valid under
positive regression dependence, or Benjamini-Yekutieli, valid under
arbitrary dependence (Benjamini & Yekutieli, 2001). This class defaults
to the former; the estimators default to the latter, since engineered
candidates share parents and positive dependence cannot be assumed.
The marginal null composes correctly with constructed features: two
near-duplicate expressions of one true signal are *both* genuinely
associated with the target, so selecting both is not a false discovery
under this null. De-duplication is the job of the redundancy pass, not
the error-control procedure.
:class:KnockoffSelector
The knockoff filter. Two constructions are provided and routed
automatically:
- **Fixed-X** (Barber & Candès, 2015), used when ``n >= 2p``. Treats the
design as fixed and makes *no distributional assumption about the
features* — deterministic engineered columns are fine. The guarantee
requires the linear model ``y = X beta + noise`` with Gaussian,
homoskedastic noise. On near-singular designs the construction remains
valid but its power degrades toward zero, because the knockoffs become
nearly identical to the originals.
- **Model-X Gaussian** (Candès et al., 2018), used when ``n < 2p``.
Requires the features to be jointly Gaussian, which engineered
features are not; a warning is recorded when the design is visibly
degenerate.
Selective inference caveat. Every guarantee above is for testing a
candidate set that is fixed before seeing the data used for testing. If
candidates were chosen by a search on the same data — chosen, in part,
because they correlate with this sample's target — the p-values are
optimistically biased and the nominal FDR is not guaranteed. The estimators
in :mod:beamfeat.estimators therefore hold out a split of the training
data for selection by default; see selection_holdout.
References
Barber, R. F. & Candès, E. J. (2015). Controlling the false discovery rate via knockoffs. Annals of Statistics, 43(5), 2055-2085.
Benjamini, Y. & Hochberg, Y. (1995). Controlling the false discovery rate. JRSS-B, 57(1), 289-300.
Benjamini, Y. & Yekutieli, D. (2001). The control of the false discovery rate in multiple testing under dependency. Annals of Statistics, 29(4), 1165-1188.
Candès, E., Fan, Y., Janson, L. & Lv, J. (2018). Panning for gold: model-X knockoffs. JRSS-B, 80(3), 551-577.
Phipson, B. & Smyth, G. K. (2010). Permutation p-values should never be zero. Stat. Appl. Genet. Mol. Biol., 9(1), Article 39.
KnockoffSelector
Bases: Selector
Knockoff filter with automatic fixed-X / model-X routing.
Fixed-X (Barber & Candès, 2015) is used when n >= 2p. The design
is treated as fixed, so no assumption about the distribution of the
features is required — deterministic engineered columns are admissible.
The finite-sample FDR guarantee (with offset=1) requires the linear
model y = X beta + eps with i.i.d. Gaussian noise. On a near-singular
design the construction is still valid but the equicorrelated s
shrinks toward zero, the knockoffs become nearly identical to the
originals, and power degrades toward zero; a warning records this.
Model-X Gaussian (Candès et al., 2018) is used when n < 2p, where
the fixed-X construction does not exist. It requires the features to be
jointly Gaussian, an assumption engineered features violate; a warning is
recorded when the design is visibly degenerate. Prefer
:class:PermutationSelector in that regime.
Power and the offset. offset=1 requires
(1 + #negatives)/#positives <= target_fdr, unsatisfiable with fewer
than 1/target_fdr features regardless of signal; measured on a
25-feature Gaussian design at level 0.1, offset=1 recovered almost
nothing while offset=0 recovered everything. offset=1 remains the
default because it is the stated finite-sample guarantee; a warning fires
when the design is too narrow for it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_fdr
|
float
|
Nominal false discovery rate. |
0.1
|
problem_type
|
ProblemType
|
|
'regression'
|
random_state
|
int | None
|
Seed (used by the model-X sampler and the orthogonal complement basis). |
0
|
offset
|
Offset
|
|
1
|
shrinkage
|
float
|
Ridge term added to the covariance diagonal for numerical stability. |
1e-06
|
construction
|
Literal['auto', 'fixed', 'gaussian']
|
|
'auto'
|
warn_on_violation
|
bool
|
Whether to check assumptions and record findings. |
True
|
PermutationSelector
Bases: Selector
Exact permutation test of marginal association, with FDR correction.
Statistic. For regression, the absolute Pearson correlation between
each feature and the target; for classification, eta-squared (the
between-class share of each feature's variance). Both are fixed functions
of (X_j, y), which is the condition for a permutation test to be
exact: comparing the observed statistic to the same statistic computed on
(X_j, pi(y)) over random permutations pi yields a valid p-value
for the null that X_j is marginally independent of y, via the
add-one estimator (1 + #exceedances) / (B + 1) (Phipson & Smyth,
2010). Statistics that re-tune themselves on the observed target — a
cross-validated lasso penalty, for instance — do not satisfy this
condition unless the tuning is repeated inside every permutation.
What the null means for constructed features. Marginal independence is the appropriate null here: an expression that genuinely co-varies with the target is a true discovery even if another selected expression carries the same information. Redundancy among true discoveries is resolved by the redundancy pass in the search, not by the error-control procedure.
Multiplicity. Benjamini-Hochberg by default, which controls FDR under
positive regression dependence; set correction="by" for the
Benjamini-Yekutieli procedure, valid under arbitrary dependence at the
cost of a log(m)-factor in power.
Resolution. The smallest attainable p-value is 1/(B + 1), and
Benjamini-Hochberg requires the leading feature to reach
target_fdr / m. B therefore must be at least m / target_fdr -
1 for selection to be possible at all, and one further null exceedance
doubles the requirement. When auto_permutations is on (default), B is
raised to ceil(2 m / target_fdr) — satisfiable with headroom for a
single exceedance — capped at max_permutations. Because the statistic
is a single matrix product, even B = 100000 costs well under a second
at typical sizes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_fdr
|
float
|
Nominal false discovery rate. |
0.1
|
problem_type
|
ProblemType
|
|
'regression'
|
random_state
|
int | None
|
Seed for the permutation draws. |
0
|
n_permutations
|
int
|
Minimum number of permutations. |
2000
|
auto_permutations
|
bool
|
Raise B to the satisfiability bound when needed. |
True
|
max_permutations
|
int
|
Hard cap on B. |
100000
|
correction
|
Literal['bh', 'by']
|
|
'bh'
|
SelectionResult
dataclass
Outcome of a selection run.
Attributes:
| Name | Type | Description |
|---|---|---|
selected |
ndarray
|
Indices of the selected features, ascending. |
statistics |
ndarray
|
Importance statistic per feature. For the permutation
selector this is |
p_values |
ndarray | None
|
Exact permutation p-values, where the method produces them. |
threshold |
float
|
The data-dependent cut applied to :attr: |
target_fdr |
float
|
The nominal FDR level requested. |
n_candidates |
int
|
Number of features considered. |
method |
str
|
Name of the selector used. |
warnings_raised |
list[str]
|
Assumption or configuration issues detected. |
n_selected
property
Number of features selected.
mask()
Boolean mask over the candidate features.
summary()
Human-readable summary of the run.
Selector
Bases: ABC
Base class for FDR-controlled selectors.
select(features, target)
abstractmethod
Select features controlling the FDR at :attr:target_fdr.
knockoff_threshold(statistics, target_fdr, offset=1)
Data-dependent threshold of the knockoff filter.
Finds the smallest positive cut t at which
(offset + #{W_j <= -t}) / #{W_j >= t} <= target_fdr. offset=1
gives knockoff+ (finite-sample FDR control); offset=0 controls a
modified FDR.
make_selector(selector, target_fdr=0.1, problem_type='regression', random_state=0, **kwargs)
Resolve a selector name or instance into a :class:Selector.
Search
Guided beam search for feature construction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scorer
|
str | Scorer
|
Scoring strategy. Either a name ( |
'correlation'
|
problem_type
|
ProblemType
|
|
'regression'
|
max_depth
|
int
|
Maximum expression depth. Depth 1 permits single transforms and pairwise combinations of inputs; each further depth composes on the results of the last. |
2
|
beam_width
|
int
|
Expressions retained at each depth. This is the parameter
that bounds cost: total work is roughly
|
50
|
max_features
|
int | None
|
Maximum features returned. Defaults to |
None
|
unary_ops
|
Sequence[str]
|
Unary operators to apply. Defaults to log, sqrt, reciprocal, square, and abs. |
DEFAULT_UNARY
|
binary_ops
|
Sequence[str]
|
Binary operators to apply. Defaults to mul, div, add, sub. |
DEFAULT_BINARY
|
redundancy_threshold
|
float
|
Absolute correlation above which a candidate is considered a duplicate of one already in the beam and dropped. |
0.95
|
include_originals
|
bool
|
Whether input columns are eligible for the final result alongside constructed expressions. |
True
|
max_candidates_per_depth
|
int
|
Hard ceiling on candidates constructed at one depth, as a guard against a wide beam and many operators producing an unaffordable round. Candidates beyond the ceiling are not proposed; the beam is traversed in score order so the truncation falls on the least promising parents. |
200000
|
random_state
|
int | None
|
Seed passed to the scorer. Search itself is deterministic. |
0
|
verbose
|
int
|
If positive, log progress at each depth. |
0
|
Attributes:
| Name | Type | Description |
|---|---|---|
result_ |
SearchResult | None
|
:class: |
run(data, target, columns=None, units=None, evaluator=None)
Execute the search.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Any
|
Mapping of column name to array, or a 2-D array. Ignored if
|
required |
target
|
ndarray
|
Target vector, one entry per row. |
required |
columns
|
Sequence[str] | None
|
Column names, when |
None
|
units
|
dict[str, Any] | None
|
Optional mapping of column name to pint quantity. Supplying units restricts the search to dimensionally valid expressions. |
None
|
evaluator
|
Evaluator | None
|
A pre-built :class: |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
SearchResult
|
class: |
Expressions
Lazily evaluates nodes against a data matrix, caching by structural key.
The cache is bounded and least-recently-used. Leaf columns are pinned and never evicted, since they are the base of every expression. Intermediate results are evicted under memory pressure and recomputed if needed again.
Numerical failures are recorded in :attr:log and reported by returning
None from :meth:evaluate; they never propagate as exceptions and are
never silently discarded.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Mapping[str, ndarray] | ndarray
|
Mapping of column name to 1-D array, or a 2-D array with
|
required |
columns
|
Sequence[str] | None
|
Column names, required when |
None
|
units
|
Mapping[str, Any] | None
|
Optional mapping of column name to pint quantity. |
None
|
dtype
|
dtype | type
|
Working dtype. Defaults to float64; float32 halves memory but makes overflow substantially more likely in deep expressions. |
float64
|
cache_size
|
int
|
Maximum number of non-leaf arrays held in the cache. |
4096
|
variance_tol
|
float
|
Results with variance below this are excluded as constant. |
1e-10
|
columns
property
Names of the available input columns.
dtype
property
Working dtype for evaluation.
n_rows
property
Number of rows in the data.
cache_info()
Return current cache occupancy and capacity.
clear_cache()
Evict all cached intermediate results. Leaves are retained.
evaluate(node, apply_filters=True)
Compute the values of node, using and updating the cache.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node
|
Node
|
The expression to evaluate. |
required |
apply_filters
|
bool
|
Whether to apply the search-time admissibility
filters — zero variance, and the operators' domain predicates.
These express whether a candidate is worth exploring, and
they are data-dependent: a column that varies across a training
set may be constant within some subset of it. At transform time
that must not change the result, so :meth: |
True
|
Returns:
| Type | Description |
|---|---|
ndarray | None
|
A 1-D array of length :attr: |
ndarray | None
|
excluded. When |
ndarray | None
|
attr: |
evaluate_many(nodes)
Evaluate several nodes, returning only those that survived.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nodes
|
Sequence[Node]
|
Expressions to evaluate. |
required |
Returns:
| Type | Description |
|---|---|
list[Node]
|
A tuple of (surviving nodes, matrix with one column per surviving |
ndarray
|
node in the same order). If nothing survives, the matrix has shape |
tuple[list[Node], ndarray]
|
|
leaf_nodes()
Return leaf nodes for every input column, with units attached.
transform_values(node)
Compute node without applying search-time admissibility filters.
Use this when replaying an already-selected expression on new data. Applying the search filters here would make the output depend on which rows are present — a subset in which some column happens to be constant would silently yield a different answer than the full data.
Returns:
| Type | Description |
|---|---|
ndarray | None
|
The computed values, or |
ndarray | None
|
be evaluated (overflow, or a non-finite result). |