Feature Selection Toolbox FST4
UTIA · Czech Academy of Sciences

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:

  1. 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.
  2. 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.
  3. Search. The search algorithm (--search) selects a subset maximizing the criterion (--criterion). --target-d N fixes 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 variants bb-basic/bb-improved/bb-fast/bb-bbpp.
  4. 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

KindNamesNotes
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.

Copyright © 2000–present ÚTIA, Institute of Information Theory and Automation of the Czech Academy of Sciences · Contacts · This site sets no cookies and uses no analytics.