Feature Selection Toolbox FST4
UTIA · Czech Academy of Sciences
Loading...
Searching...
No Matches
FST::Criterion_Extern_Value< RETURNTYPE, DATATYPE, REALTYPE, IDXTYPE, DIMTYPE, SUBSET, DATAACCESSOR > Class Template Reference

External-tool criterion: a user-supplied command computes the criterion value itself - unlike wrapper-extern, which exchanges labels and computes accuracy on the FST4 side. More...

#include <criterion_extern_value.hpp>

Inheritance diagram for FST::Criterion_Extern_Value< RETURNTYPE, DATATYPE, REALTYPE, IDXTYPE, DIMTYPE, SUBSET, DATAACCESSOR >:
FST::Clonable_Impl< Criterion_Extern_Value< RETURNTYPE, DATATYPE, REALTYPE, IDXTYPE, DIMTYPE, SUBSET, DATAACCESSOR >, Criterion< RETURNTYPE, SUBSET > > FST::Criterion< RETURNTYPE, SUBSET > FST::Clonable

Public Types

typedef Criterion< RETURNTYPE, SUBSET > parent
 base class: the abstract criterion interface
typedef Clonable_Impl< Criterion_Extern_Value, parent > parent_impl
 implements clone(); sharing/stateless_clone throw in Criterion
typedef std::shared_ptr< DATAACCESSOR > PDataAccessor
 shared pointer to the data accessor supplying the DATA block's TRAIN part
typedef std::shared_ptr< SUBSET > PSubset
 shared pointer to the feature subset being evaluated
typedef DATAACCESSOR::PPattern PPattern
 raw feature-vector pointer type, as sent full-width by send_row()
Public Types inherited from FST::Criterion< RETURNTYPE, SUBSET >
typedef std::shared_ptr< SUBSET > PSubset
 shared pointer to the feature subset being evaluated

Public Member Functions

void set_command (const std::string &cmd)
 sets the external command line (--extern-cmd); required before the first evaluate()
const std::string & get_command () const
 returns the currently configured external command line
void set_monotonic (const bool m)
 the user's assertion (--extern-monotonic); see the class note
virtual bool is_monotonic () const override
void set_no_data (const bool nd)
 --extern-no-data: suppress the DATA block - pure set-function optimization, the tool answers index-only VALUE requests from its own logic
void initialize (const PDataAccessor da, const PDataAccessor da_for_evaluate=PDataAccessor())
 Records the data shape and marks the tool's stored DATA stale; the criterion then evaluates on da's TRAIN part. Must be called before the first evaluate(), and again whenever the effective split changes – that is what makes the next evaluate() re-send the DATA block. Throws fst_error when no command has been set, or (unless no-data mode is in effect) when da has fewer than 2 classes.
virtual bool evaluate (RETURNTYPE &result, const PSubset sub) override
 Evaluates sub by one VALUE request to the external tool.
virtual std::ostream & print (std::ostream &os) const override
 writes a human-readable identification of the object; base default writes nothing
Public Member Functions inherited from FST::Clonable_Impl< Criterion_Extern_Value< RETURNTYPE, DATATYPE, REALTYPE, IDXTYPE, DIMTYPE, SUBSET, DATAACCESSOR >, Criterion< RETURNTYPE, SUBSET > >
Criterion< RETURNTYPE, SUBSET > * clone () const override
 dispatches to the DEEP_KIND mechanism (default CLONE_DEEP: Derived's copy-constructor)
Criterion< RETURNTYPE, SUBSET > * sharing_clone () const override
 dispatches to the SHARING_KIND mechanism (default CLONE_INHERIT: defers to Base, which throws by family convention)
Criterion< RETURNTYPE, SUBSET > * stateless_clone () const override
 dispatches to the STATELESS_KIND mechanism (default CLONE_INHERIT: defers to Base, which throws by family convention)
Public Member Functions inherited from FST::Criterion< RETURNTYPE, SUBSET >
Criterion * sharing_clone () const override
Criterion * stateless_clone () const override
Public Member Functions inherited from FST::Clonable
bool is_clone () const
bool is_sharing () const
 true if this instance is a sharing_clone() result (referencing, not owning, the source's structures)
bool is_sharing_clone () const
 true if this instance is BOTH a clone and sharing – i.e. specifically a sharing_clone() result, not a clone()/stateless_clone() one

Protected Member Functions

bool send_data_block ()
 sends one full-width DATA block over the current split's TRAIN part (returns false on an empty train part)
void send_row (const DIMTYPE label, const PPattern &pattern)
 sends one %.17g-formatted labelled FULL-WIDTH data row
double parse_value (const std::string &line)
 strict full-line numeric parse incl. finiteness (throws on violation, symmetric with the classifier bridge's loudness)
Protected Member Functions inherited from FST::Clonable
void set_cloned (const bool cloned=true)
 marks/unmarks this instance as a clone; call from clone()/stateless_clone() overrides (Clonable_Impl does this automatically)
void set_sharing (const bool sharing=true)
 marks/unmarks this instance as sharing (see is_sharing())
void set_sharing_cloned (const bool cloned=true, const bool sharing=true)
 sets both flags at once; call from sharing_clone() overrides (Clonable_Impl does this automatically)

Protected Attributes

Extern_Bridge _bridge
 persistent child process + line I/O (per instance; never shared by clones)
bool _monotonic
 the user's cardinality-monotonicity assertion
bool _no_data
 --extern-no-data: never send DATA (the tool is a pure set function over index sets)
bool _data_stale
 the tool's stored DATA no longer matches the current split (set by initialize() and child respawn)
PDataAccessor _da
 the data accessor whose TRAIN part feeds the DATA block
DIMTYPE _classes
 class count recorded by initialize(), from _da->getNoOfClasses()
DIMTYPE _features
 raw feature count recorded by initialize(), from _da->getNoOfFeatures()
DIMTYPE _subfeatures
 d = current subset size (number of valid entries in _index)
std::vector< DIMTYPE > _index
 subset position -> raw feature index (first _subfeatures entries valid)

Private Member Functions

 Criterion_Extern_Value (const Criterion_Extern_Value &cev)
 Copy-constructor; spawns its own fresh bridge (clones never share pipes) and copies the recorded data shape.

Private Attributes

friend parent_impl

Detailed Description

template<class RETURNTYPE, typename DATATYPE, typename REALTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET, class DATAACCESSOR>
class FST::Criterion_Extern_Value< RETURNTYPE, DATATYPE, REALTYPE, IDXTYPE, DIMTYPE, SUBSET, DATAACCESSOR >

External-tool criterion: a user-supplied command computes the criterion value itself - unlike wrapper-extern, which exchanges labels and computes accuracy on the FST4 side.

One PERSISTENT child process per criterion instance (spawned lazily on first use; clones spawn their own, so threaded evaluation is isolation-safe), speaking a line protocol on stdin/stdout:

-> DATA <N> <D> <K>\n   followed by N lines  <label> <v1> ... <vD>
<- OK\n                 (anything else fails the evaluation, loudly)
-> VALUE <d> <f1> ... <fd>\n   (0-based RAW feature indices, ascending)
<- one line: the criterion value (parsed as a strict full-line double)

The DATA block carries the FULL-width TRAIN part of the current split (the filter convention: the criterion sees training data only) and is sent once per split - re-sent whenever initialize() is called (the pipeline's refresh contract, same as filter model re-estimation) or the child was (re)spawned. Each evaluation then costs one VALUE request of d integers: the tool holds the data (or better, per-feature SUFFICIENT STATISTICS computed at DATA time) and answers from the indices - O(d) per request instead of re-streaming N*d values (the cost model that matters under B&B's thousands of evaluations). Raw indices also give the tool feature IDENTITIES (per-feature caching, acquisition-cost-aware measures). Values are exchanged as %.17g decimal (bit round-trip for doubles). A reference implementation ships in tests/extern_value_meandiff.awk (the sufficient-statistics pattern).

NO-DATA MODE (set_no_data(), the CLI's --extern-no-data): the DATA block is suppressed entirely and the tool answers index-only VALUE requests from logic of its own - cost tables, simulations, external experiments: FST4 as a black-box SET-FUNCTION optimizer over an abstract feature universe. A dataset is then only a source of the universe size, and the fst4 CLI does not need one at all in this mode: --features N replaces --data and supplies a feature-only accessor of N features and no classes. The three-layer design: wrapper-extern = external CLASSIFIER, extern-value with DATA = external DATA-DEPENDENT CRITERION (the DATA block is the split-synchronization mechanism - only FST4 knows the current split, and a self-loading tool would leak held-out data), extern-value with no data = external SET FUNCTION.

VALUE SEMANTICS: FST4 maximizes - larger values must mean better subsets (negate error-style measures inside the tool). There is NO range or scale requirement beyond that: criterion values are only ever compared within the same search, never across criteria (built-in filters return unbounded distances, wrappers [0,1] accuracies — both coexist for the same reason). Values must be FINITE doubles (non-finite responses fail loudly, see parse_value) and deterministic for identical requests. Flags expressed in value units (--tracker-margin, --regularize-margins) are in the external measure's own units, as with every criterion.

NORMALIZATION follows the standard FST4 convention: the streamed values are the accessor's in-memory data AFTER the global --scaler (applied per-feature over the whole dataset at load) — exactly what built-in criteria see; the bridge adds NO internal per-training standardization. If the tool normalizes further, beware the monotonicity assertion: per-feature-independent normalization is safe for per-feature-sum measures, but normalization coupling the streamed columns (subset-level variance/totals) can silently break the asserted monotonicity and void the B&B optimality guarantee.

MONOTONICITY AND BRANCH & BOUND: is_monotonic() returns what the user asserted via set_monotonic() (the CLI's --extern-monotonic; default false). Asserting it admits the criterion to the optimal B&B searches — THE OPTIMALITY GUARANTEE THEN RESTS ENTIRELY ON THE ASSERTION being true of the external measure (removing a feature must never increase the value). A false assertion yields silently suboptimal "optimal" results. Without the assertion, Search_Branch_And_Bound prints its warning (and the fst4 CLI refuses bb-* searches outright).

All LOUD CAVEATS of the extern mechanism apply as for wrapper-extern (classifier_extern.hpp): USER-SUPPLIED CODE EXECUTION through the system shell; REPRODUCIBILITY GUARANTEES END AT THE BRIDGE (a stochastic external measure breaks run- and thread-reproducibility AND, under B&B, the optimality logic itself); no timeout machinery (extern_bridge.hpp).

Member Function Documentation

◆ evaluate()

template<class RETURNTYPE, typename DATATYPE, typename REALTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET, class DATAACCESSOR>
bool FST::Criterion_Extern_Value< RETURNTYPE, DATATYPE, REALTYPE, IDXTYPE, DIMTYPE, SUBSET, DATAACCESSOR >::evaluate ( RETURNTYPE & result,
const PSubset sub )
overridevirtual

Evaluates sub by one VALUE request to the external tool.

Sends "VALUE d f1 ... fd" with the 0-based RAW feature indices in ascending subset order and reads back one line holding the value. Before that, in the DATA modes, the DATA block is (re)sent whenever it is stale – after an initialize(), and after the child process was spawned or respawned, since a fresh child holds nothing.

Returns
false when the subset is empty, or when the current split's TRAIN part holds no patterns (so there is no DATA to send). Everything else that can go wrong throws: a rejected DATA block, a non-numeric or non-finite value line, a child that died. The value itself is whatever the tool returned – FST4 does not check its range.

Implements FST::Criterion< RETURNTYPE, SUBSET >.

◆ initialize()

template<class RETURNTYPE, typename DATATYPE, typename REALTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET, class DATAACCESSOR>
void FST::Criterion_Extern_Value< RETURNTYPE, DATATYPE, REALTYPE, IDXTYPE, DIMTYPE, SUBSET, DATAACCESSOR >::initialize ( const PDataAccessor da,
const PDataAccessor da_for_evaluate = PDataAccessor() )

Records the data shape and marks the tool's stored DATA stale; the criterion then evaluates on da's TRAIN part. Must be called before the first evaluate(), and again whenever the effective split changes – that is what makes the next evaluate() re-send the DATA block. Throws fst_error when no command has been set, or (unless no-data mode is in effect) when da has fewer than 2 classes.

Parameters
dathe accessor the criterion reads; its currently designated TRAIN part becomes the DATA block, and its feature count the size of the feature universe.
da_for_evaluateaccepted for signature compatibility with the criteria that evaluate on a second accessor; this criterion has no such split and ignores it.

◆ is_monotonic()

template<class RETURNTYPE, typename DATATYPE, typename REALTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET, class DATAACCESSOR>
virtual bool FST::Criterion_Extern_Value< RETURNTYPE, DATATYPE, REALTYPE, IDXTYPE, DIMTYPE, SUBSET, DATAACCESSOR >::is_monotonic ( ) const
inlineoverridevirtual

Declares monotonicity with respect to subset cardinality: true means removing a feature can NEVER increase the criterion value. Branch & Bound prunes on this property, so ALL of its optimality guarantees rest on this declaration - and the library cannot verify it, it is an assertion made by the criterion's author. A false declaration silently turns Branch & Bound into a heuristic that may skip the optimum. Search_Branch_And_Bound therefore prints a warning at search start when the supplied criterion does not declare the property, and the fst4 command-line tool refuses the --search bb-* algorithms outright for such a criterion. Defaults to false: user-supplied criteria should override to true only if monotonicity provably holds. The built-in normal-model and multinomial filters declare true (see Criterion_Normal and Criterion_Multinomial); wrapper criteria and the adapter criteria (negative/subset-size/sum-of-weights) deliberately keep the false default.

Reimplemented from FST::Criterion< RETURNTYPE, SUBSET >.

◆ print()

template<class RETURNTYPE, typename DATATYPE, typename REALTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET, class DATAACCESSOR>
virtual std::ostream & FST::Criterion_Extern_Value< RETURNTYPE, DATATYPE, REALTYPE, IDXTYPE, DIMTYPE, SUBSET, DATAACCESSOR >::print ( std::ostream & os) const
inlineoverridevirtual

writes a human-readable identification of the object; base default writes nothing

Reimplemented from FST::Clonable.

Member Data Documentation

◆ parent_impl

template<class RETURNTYPE, typename DATATYPE, typename REALTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET, class DATAACCESSOR>
friend FST::Criterion_Extern_Value< RETURNTYPE, DATATYPE, REALTYPE, IDXTYPE, DIMTYPE, SUBSET, DATAACCESSOR >::parent_impl
private

grants Clonable_Impl access to the copy-constructor


The documentation for this class was generated from the following file:
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.