Online per-feature statistics for budgeted (sampled) sequential steps — discounted batch-standardized DAF contrast. More...
#include <result_weighter_sampled.hpp>
Classes | |
| struct | FeatureStat |
| Per-feature accumulators, one instance per feature index, updated by flush_batch(). m_is/m_isnot are adaptive-rate running means of the batch z-score, one side for evaluations in which the feature was selected ('is') and one for evaluations in which it was not ('isnot'); score() in STATS_ZCONTRAST mode returns their difference. raw_sum_is/raw_cnt_is accumulate the STATS_RAWMEAN statistic instead. n_is/n_isnot count how many evaluations landed on each side — also the exploration counts exposed via count_is()/count_isnot(). More... | |
| struct | BatchEntry |
| One buffered, not-yet-flushed criterion evaluation: its raw value, the cardinality of the evaluated subset, and the list of selected feature indices — everything flush_batch() needs to z-standardize the batch and fold it into the accumulators. More... | |
Public Types | |
| enum | StatsMode { STATS_ZCONTRAST , STATS_RAWMEAN } |
| Selects which statistic score(f) reports: STATS_ZCONTRAST (default) is the batch-standardized DAF-style contrast m_is-m_isnot described above; STATS_RAWMEAN is the 1/|S|-size-weighted mean of raw criterion values over 'is' contexts only (the simpler baseline statistic; the fst4 tool selects it with --step-stats rawmean). | |
| typedef std::shared_ptr< SUBSET > | PSubset |
| shared-ownership handle to the evaluated Subset passed into add() | |
Public Member Functions | |
| Result_Weighter_Sampled (const IDXTYPE horizon=100, const StatsMode mode=STATS_ZCONTRAST) | |
| Construct with the given adaptive-rate horizon and scoring mode; all statistics start at zero and are properly sized on the first add() or an explicit reset(). | |
| void | reset (const DIMTYPE n) |
(Re)dimension to n features and zero all statistics, the pending batch and the counters. Also clears the frozen flag. NOT thread-safe and NOT mutex-protected: call it only when no add() can run concurrently (add() itself calls it once, under the lock, on the very first use). | |
| DIMTYPE | get_n () const |
| current feature-space dimensionality (0 until the first add() or reset()) | |
| StatsMode | get_mode () const |
| the configured StatsMode (see StatsMode) | |
| IDXTYPE | get_horizon () const |
| the (clamped, >=1) adaptive-rate horizon supplied at construction | |
| bool | add (const RETURNTYPE value, const PSubset sub) |
| Buffer one evaluated subset for the current batch (thread-safe; may be called from threaded-evaluator worker callbacks). | |
| IDXTYPE | flush_batch () |
| z-score the buffered batch and fold it into the accumulators; returns the number of evaluations flushed (0 for an empty batch or while frozen) | |
| void | freeze () |
| Freezes the ranking: flushes any pending batch, then turns all further add()/flush_batch() calls into successful no-ops — the statistics (scores AND exploration counts) stay exactly as they were at this point, e.g. as a warm-up round left them. Takes the mutex only AFTER flush_batch() has released it, so never call it while holding the lock yourself. | |
| bool | is_frozen () const |
| true once freeze() has been called (see freeze()) | |
| RETURNTYPE | score (const DIMTYPE f) const |
| current sampling score of feature f (see class doc) | |
| IDXTYPE | count_is (const DIMTYPE f) const |
| how many evaluated subsets contained f (exploration bookkeeping) | |
| IDXTYPE | count_isnot (const DIMTYPE f) const |
| how many evaluated subsets lacked f ("what happens without f" is the scarce observation for backward-step exploration) | |
| IDXTYPE | total_evals () const |
| cumulative count of evaluations passed to add() since construction/reset(), including any still buffered and not yet flushed | |
| IDXTYPE | flushed_batches () const |
| number of non-empty flush_batch() calls processed since construction/reset() (a count of batches, not of evaluations) | |
| std::ostream & | print (std::ostream &os) const |
| Write a compact one-line summary (n, horizon, mode, frozen flag, total evaluations) to os. Writes directly via operator<<, not through syncout::print — callers from threaded contexts should route the result through syncout::print themselves, or prefer print_stats() below, which already does. | |
| bool | print_stats (std::ostream &os, const DIMTYPE top=20) const |
| diagnostic listing of the top-scored features | |
Protected Attributes | |
| DIMTYPE | _n |
| current feature-space dimensionality, set by reset() (called explicitly, or lazily by the first add()) | |
| IDXTYPE | _horizon |
| adaptive-rate horizon supplied at construction (clamped to at least 1) | |
| StatsMode | _mode |
| configured StatsMode, selects which statistic score() reports | |
| bool | _frozen |
| set by freeze(); once true, add()/flush_batch() are no-ops and statistics stay frozen at their warm-up values | |
| std::vector< FeatureStat > | _fs |
| per-feature accumulators, indexed 0.._n-1 | |
| std::vector< BatchEntry > | _batch |
| buffered, not-yet-flushed evaluations added since the last flush_batch() | |
| std::vector< char > | _mark |
| flush_batch() scratch bitmap (size _n); marks one entry's selected features while folding it in, then clears them again | |
| IDXTYPE | _total_evals |
| cumulative count of evaluations passed to add() since construction/reset() (see total_evals()) | |
| IDXTYPE | _flushed_batches |
| count of non-empty flush_batch() calls since construction/reset() (see flushed_batches()) | |
| std::mutex | _add_mutex |
| guards _batch/_total_evals/_frozen so add() is safe to call from threaded-evaluator worker callbacks | |
Online per-feature statistics for budgeted (sampled) sequential steps — discounted batch-standardized DAF contrast.
The statistics engine behind Sequential_Step_Sampled: every criterion evaluation the step performs is fed here, and score(f) is what the step's proposal sampler concentrates its candidate budget on. See arXiv:2608.01502 for the method.
Collects criterion evaluations into a batch buffer (one batch = one sequential step's candidate sweep, or one warm-up probe round). CALLER CONTRACT: all subsets within one batch share the same cardinality and evaluation context — z-scores are only meaningful within such a batch. flush_batch() z-standardizes the buffered values and folds each evaluation into per-feature accumulators: for an evaluated subset with standardized score z, the 'is' accumulator of every selected feature and the 'isnot' accumulator of every unselected feature receive an update with z. score(f) = m_is(f) - m_isnot(f), a batch-relative DAF-style contrast that is comparable across subset sizes by construction (no per-size bins) and covers forward steps, backward steps and probes with one uniform rule: in a forward batch the added feature is selected in exactly one candidate, in a backward batch the removed feature is unselected in exactly one candidate, so the contrast picks up the correct sign automatically.
The accumulators use an adaptive rate 1/min(t,horizon): exact running mean until a feature's side has seen horizon updates, exponential forgetting beyond it (keeps statistics fresh once the search trajectory drifts to high |S|). Unobserved features score 0 = the batch average — the correct neutral prior for centered z-scores, so no cold-start bias correction is needed.
STATS_RAWMEAN is a simpler alternative statistic: the 1/|S|-size-weighted mean of the RAW criterion values over 'is' contexts only, with no standardization and no 'isnot' side. It is kept as a baseline to compare the contrast against; be aware of its flaw, namely that the absolute level it reports is dominated by WHEN during the search a feature happened to be evaluated (early small subsets and late large ones score on different scales), which is exactly what the z-contrast removes.
This is a plain statistics engine, deliberately independent of the Result_Tracker hierarchy: it neither stores subsets for later retrieval nor takes part in candidate iteration. The sampling policy that consumes the scores lives entirely in Sequential_Step_Sampled.
Thread safety: add() is mutex-protected (safe from threaded-evaluator worker callbacks); flush_batch() is to be called at batch boundaries only, where the step object is single-threaded by construction.
|
inline |
Construct with the given adaptive-rate horizon and scoring mode; all statistics start at zero and are properly sized on the first add() or an explicit reset().
| horizon | exponential-forgetting horizon (see class doc); clamped to at least 1 |
| mode | STATS_ZCONTRAST or STATS_RAWMEAN (see StatsMode) |
| bool FST::Result_Weighter_Sampled< RETURNTYPE, IDXTYPE, DIMTYPE, SUBSET >::add | ( | const RETURNTYPE | value, |
| const PSubset | sub ) |
Buffer one evaluated subset for the current batch (thread-safe; may be called from threaded-evaluator worker callbacks).
sub's feature-space size disagrees with the already established one — the caller should treat that as a fatal mismatch. Adding while frozen is a successful no-op, i.e. it returns true.