Rules & Screening¶
FlagGAM turns each feature into a small set of binary "flags" — threshold, hinge, or
category conditions — through a univariate screening pass, then fits a linear/logistic
head on top of the resulting basis matrix Z(X). This page explains how that screening
pass works: the Univariate Flagging Algorithm (UFA), the multiple-testing correction
applied across candidates, and the support floor that keeps individual rules statistically
meaningful. See Algorithm for the full walkthrough, including the pipeline
schema and how the additive head is fit on top of the resulting basis matrix.
The Univariate Flagging Algorithm (UFA)¶
For each feature, UFA scans candidate cutoffs (numeric features) or levels (categorical features) and tests whether the outcome distribution differs between the "tail" (rows on one side of the cutoff, or in that category) and the "baseline" (everything else):
- Binary outcome — a two-sided two-proportion z-test compares the positive-class rate in the tail vs. the baseline. When any expected cell count in the 2x2 table falls below 5, the test automatically falls back to Fisher's exact test.
- Multiclass outcome — a Pearson chi-square test on the 2xK (tail/baseline x class) contingency table, since no single directional effect is defined for K > 2 classes.
- Regression outcome — a Welch t-test (unequal variances) on the continuous response, tail vs. baseline.
A candidate only becomes a basis function ("flag") if it survives screening: its p-value
(after FDR correction, below) must be at or under fdr_alpha, and it must satisfy the
support floor described below.
Candidates are ranked by effect size so that practically meaningful cuts are preferred over merely significant ones:
- Binary same-side selection ranks by absolute risk difference (
effect_size="risk_difference", the default) or by absolute log-odds ratio (effect_size="log_odds_ratio"). - Multiclass same-side selection ranks by Cramer's V of the 2xK contingency table.
- Regression screening ranks by absolute standardized mean difference (SMD).
Basis kinds¶
Each surviving candidate becomes one column of Z(X), tagged with a kind:
| Kind | Meaning |
|---|---|
threshold_low / threshold_high |
Step indicator: feature <= cutoff / >= cutoff |
hinge_low / hinge_high |
Ramp (hinge) function anchored at a cutoff |
trend |
Centered linear term for the feature |
category |
Indicator for one categorical level |
missing_indicator |
Indicator that the feature was missing for this row |
est.core_.bases_ holds the full list of fitted Basis objects (see the
Bases API); each has .feature, .kind, .name, and a .transform(x)
method, plus kind-specific attributes (.cutoff/.side for threshold/hinge bases,
.level for category bases, .mean for trend bases).
Multiple-testing correction (BH-FDR)¶
Screening a feature typically produces several candidate cutoffs, which inflates the
false-positive rate if each is tested at a flat significance threshold. FlagGAM applies
Benjamini-Hochberg (BH) FDR correction across a feature's candidates before filtering by
fdr_alpha (default 0.05), so the reported p_adj in export_rules() already accounts
for the number of candidates considered for that feature. Missing-indicator screening
applies the same BH correction, but across features (one candidate per feature) rather
than within a feature.
Support floor (min_support)¶
A candidate cutoff or level is only tested if both the tail and the baseline have at
least min_support observations — a symmetric floor that keeps both sides of every test
adequately powered, and prevents rules from being fit against a near-empty group. By
default (min_support="auto"), this floor is computed from the training size:
i.e. 2% of the training rows, floored at 20 and capped at 200. Pass an explicit integer to
override it. For categorical features, the "rest" group (all rows not in the level under
test) must also satisfy min_support.
Inspecting the result¶
Once fitted, export_rules() returns one row per surviving basis with its feature,
kind, rendered rule string, cutoff/level, support, effect_size, p_value,
p_adj, enriched_class (classification only), fitted weight, and whether the flag is
additive_interpretable. explain(X) decomposes individual predictions the same way,
listing the fired flags and their per-row contributions. See
Inspection for the full column reference.