Using FST4 from the command line
Since version 4.0 the whole toolbox is usable without writing any C++:
the fst4 executable selects the data file, splitters, scaler,
criterion, search algorithm, result tracking and the run protocol via
command-line flags or a config file. This page walks the essentials; the
complete flag reference is the FST4 CLI page
(shipped in the distribution as doc/FST4_CLI.md), and the
C++ library API is documented in the
API Reference. For a narrative, example-driven
introduction read the FST4 introduction first.
Build
Requirements: a C++17 compiler (GCC, MinGW-W64 or MSVC) and CMake 3.16+. No external libraries are needed — Boost is gone since FST4, and LibSVM and Eigen are optional extensions.
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel --target fst4
A default build uses fixed, CPU-independent release
flags, so seeded results reproduce machine-to-machine; the distribution's
regression baselines are captured under exactly these flags. See
README.md in the package for platform notes (Windows/MinGW,
macOS, Linux, Visual C++).
First selection in one command
The classic filter workflow — the demo10 protocol: Generalized Mahalanobis filter, Sequential Forward Selection to 7 features on a 50/50 data split, validated by 3-NN on the held-out part:
./fst4 --data data/wdbc_30.trn --criterion gmahalanobis --search sfs --target-d 7 --validate knn
Or the same run from a config file (all 51 shipped demo scenarios come as such files — see Demos):
./fst4 --config demos/demo10.cfg
Two commands tell you what is available and what everything means:
./fst4 --list # the component registry, with validity notes
./fst4 --help # the full flag reference
The run shape
Every run follows the protocol shared by all FST demos since FST3:
- Split the data. The outer splitter (
--splitter) divides the data; its train part feeds feature selection, its test part is reserved for final validation. Splitters:5050,cv,holdout,resub,leave1out,randrand,randfix. - Optionally nest. With
--splitter2(e.g.cv) the criterion is estimated on inner splits of the outer train part — the classic nested-splitter protocol that keeps the final test data untouched during selection. - Search. The search algorithm (
--search) selects a subset maximizing the criterion (--criterion).--target-d Nfixes the subset size; 0 lets wrapper criteria optimize it. Searches:bif,sfs/sbs,sffs/sbfs,sfrs/sbrs,os,dos,exhaustive,montecarlo, and the four optimal Branch & Bound variantsbb-basic/bb-improved/bb-fast/bb-bbpp. - Validate.
--validate clf[,clf2]trains each named classifier on the outer train part and tests it on the held-out test part (same= the wrapper criterion's own classifier).
Alternative run protocols replace step 3: --repeat-over-splits
(one search per outer split — the stability-evaluation protocol),
--restarts-nonimproving N (random-restart search),
--regr-multipliers (regression kernel sweep). Around the
search: --search2 bif (ranking-seeded search),
--svm-optimize / --rbfsvm-optimize (SVM parameter
tuning), --bias-estimate, --classify-samples, and
the --regularize-* post-search sweep. Cross-scenario
comparison: --compare-config FILE runs a second scenario and
reports feature-preference similarity between the two (the demo55
protocol).
Criteria at a glance
| Kind | Names | Notes |
|---|---|---|
| Filters (normal model) | bhattacharyya, divergence, gmahalanobis |
Two-class, monotonic — the Branch & Bound companions. Fail loudly on constant features. |
| Filters (multinomial) | multinom-bhattacharyya, multinom-mi |
Count/text data; multinom-mi is a per-feature MI ranking sum for BIF-style term ranking. |
| Wrappers | wrapper-knn, wrapper-bayes, wrapper-logreg, wrapper-rf, wrapper-linsvm, wrapper-rbfsvm, wrapper-lda, wrapper-multinom, wrapper-svm |
Classifier-accuracy based. All 4.2 additions (RF, linear SVM, RBF SVM, LDA) are dependency-free and deterministic — bit-identical at any --threads. wrapper-svm needs the optional LibSVM. |
| Regression wrappers | wrapper-regressor, wrapper-ridge |
Dependent variable is the class label (“regression simulating classification”); R²/RMSE/MAE metrics available. |
| External | wrapper-extern, extern-value |
Bring your own classifier (TRAIN/TEST line protocol) or your own criterion — or, with --features N --extern-no-data, optimize a pure black-box set function with no data file at all. User-supplied code execution; reproducibility guarantees end at the bridge. |
Every classification wrapper accepts --wrapper-metric
(balanced accuracy, F1, macro-F1, AUC — exact binary AUC on two classes,
one-vs-rest macro AUC beyond) and --class-weights for
cost-sensitive selection; regression wrappers take
r2/neg-rmse/neg-mae.
Data formats
Three input formats: trn (the FST flat text format),
arff (Weka, dense and sparse), and csv/tsv
— the simplest Excel-export path, with delimiter and header auto-detection
(European semicolon + decimal-comma exports load with zero flags), the
class column defaulting to the last (--csv-class overrides by
index or header name), and loud missing-value handling
(--csv-missing-to keeps incomplete rows;
--missing-value substitutes per-feature training averages).
--data - reads the dataset from standard input, making
fst4 a filter in both directions. Scaling:
--scaler to01|white, with --scaler-fit train for
leakage-free per-split normalization.
Results, reports, pipes
Results go to stdout as text (default), JSON or CSV
(--output); in the machine formats all progress prose is
routed to stderr, so stdout stays clean for pipelines. The JSON output
echoes the fully resolved invocation including the seed — any published
result is reproducible from its own output file.
# criterion value only
./fst4 --config demos/demo10.cfg --output json | jq .result.value
# live improvements while the search runs (JSON lines on stderr)
./fst4 ... --progress json 2>&1 >/dev/null | jq .
# dataset in on stdin, result out on stdout — fst4 as a filter
zcat data.trn.gz | ./fst4 --data - --format trn --criterion gmahalanobis --search sfs --target-d 7 --output json
--report detailed adds the research sections: the
criterion-vs-holdout overfitting curve over subset size, tabular ROC and PR
curves, confusion matrices, and tuned hyperparameters.
--dump-scores FILE writes per-sample holdout predictions and
scores; --curves-svg FILE renders the curves as a
self-contained SVG.
Reproducibility
Determinism is a contract, not a hope: --threads defaults
to 1 and every search, evaluator and wrapper produces results bit-identical
to sequential at any thread count; --seed 1 reproduces the
historical unseeded demos exactly; seeded runs reproduce seed-for-seed
across Windows, macOS and Linux; --stable-output strips
timings so runs are byte-comparable. The distribution's own release gate is
a suite of 112 golden scenarios verified byte-exact on all three
platforms.
Next steps: browse the demo configs — every published FST3 example plus the FST4-native additions, each a ready-to-run config file — look up any flag in the FST4 CLI reference, or dive into the API Reference if you are integrating the C++ library directly.