Feature Selection Toolbox FST4
UTIA · Czech Academy of Sciences
Loading...
Searching...
No Matches
result_weighter_sampled.hpp
Go to the documentation of this file.
1#ifndef FSTRESULTWEIGHTERSAMPLED_H
2#define FSTRESULTWEIGHTERSAMPLED_H
3 /*
27=========================================================================
28Copyright and license:
29 * FST4 software (with the exception of any bundled or externally linked
30 third-party components) is Copyright (C) 2000-present Institute of
31 Information Theory and Automation of the Czech Academy of Sciences (UTIA).
32 * FST4 is free software: you can redistribute it and/or modify it under
33 the terms of the GNU Affero General Public License as published by the
34 Free Software Foundation, version 3. The full text of the license is in
35 the file LICENSE in the distribution root and at
36 https://www.gnu.org/licenses/agpl-3.0.html.
37 * FST4 is distributed in the hope that it will be useful, but WITHOUT ANY
38 WARRANTY; without even the implied warranty of MERCHANTABILITY or
39 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
40 License for more details.
41 * Closed-source use without the AGPL's copyleft obligations requires a
42 commercial license from UTIA; in case of interest write to
43 utia@utia.cas.cz. LICENSING.md in the distribution root explains both
44 options, the contributor license agreement that every contribution
45 requires, and the contacts (technical questions and pull requests:
46 somol@utia.cas.cz, with "FST" in the subject line).
47========================================================================== */
48
49#include <memory>
50#include <vector>
51#include <mutex>
52#include <cmath>
53#include <cassert>
54#include <sstream>
55#include <algorithm>
56#include "error.hpp"
57#include "global.hpp"
58
59/*============== Template parameter type naming conventions ==============
60--------- Numeric types: -------------------------------------------------
61DATATYPE - data sample values - usually real numbers (but may be integers
62 in text processing etc.)
63REALTYPE - must be real numbers - for representing intermediate results of
64 calculations like mean, covariance etc.
65IDXTYPE - index values for enumeration of data samples - (nonnegative) integers,
66 extent depends on numbers of samples in data
67DIMTYPE - index values for enumeration of features (dimensions), or classes (not
68 class sizes) - (nonnegative) integers, usually lower extent than IDXTYPE,
69 but be aware of expressions like _classes*_features*_features !
70 in linearized representations of feature matrices for all classes
71BINTYPE - feature selection marker type - represents ca. <10 different feature
72 states (selected, deselected, sel./desel. temporarily 1st nested loop, 2nd...)
73RETURNTYPE - criterion value: real value, but may be extended in future to support
74 multiple values
75--------- Class types: ---------------------------------------------------
76SUBSET - class of class type Subset
77CRITERION - class implementing interface defined in abstract class Criterion
78========================================================================== */
79
80namespace FST {
81
127template<class RETURNTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET>
129public:
130 typedef std::shared_ptr<SUBSET> PSubset;
131
136 enum StatsMode { STATS_ZCONTRAST, STATS_RAWMEAN };
137
142 Result_Weighter_Sampled(const IDXTYPE horizon=100, const StatsMode mode=STATS_ZCONTRAST)
143 : _n(0), _horizon(horizon<1?1:horizon), _mode(mode), _frozen(false), _total_evals(0), _flushed_batches(0)
144 {notify("Result_Weighter_Sampled constructor.");}
145 virtual ~Result_Weighter_Sampled() {notify("Result_Weighter_Sampled destructor.");}
146
150 void reset(const DIMTYPE n);
151 DIMTYPE get_n() const {return _n;}
152 StatsMode get_mode() const {return _mode;}
153 IDXTYPE get_horizon() const {return _horizon;}
154
159 bool add(const RETURNTYPE value, const PSubset sub);
160 IDXTYPE flush_batch();
161
167 void freeze() {flush_batch(); std::lock_guard<std::mutex> lock(_add_mutex); _frozen=true;}
168 bool is_frozen() const {return _frozen;}
169
170 RETURNTYPE score(const DIMTYPE f) const;
171 IDXTYPE count_is(const DIMTYPE f) const {assert(f<_n); return _fs[f].n_is;}
172 IDXTYPE count_isnot(const DIMTYPE f) const {assert(f<_n); return _fs[f].n_isnot;}
173 IDXTYPE total_evals() const {return _total_evals;}
174 IDXTYPE flushed_batches() const {return _flushed_batches;}
175
180 std::ostream& print(std::ostream& os) const {os << "Result_Weighter_Sampled(n=" << _n << ", horizon=" << _horizon << ", stats=" << (_mode==STATS_ZCONTRAST?"zcontrast":"rawmean") << (_frozen?", FROZEN":"") << ", evals=" << _total_evals << ")"; return os;}
181 bool print_stats(std::ostream& os, const DIMTYPE top=20) const;
182
183protected:
191 struct FeatureStat {
192 RETURNTYPE m_is;
193 RETURNTYPE m_isnot;
194 RETURNTYPE v_is;
195 RETURNTYPE raw_sum_is;
196 RETURNTYPE raw_cnt_is;
197 IDXTYPE n_is;
198 IDXTYPE n_isnot;
199 };
200
204 struct BatchEntry {
205 RETURNTYPE value;
206 DIMTYPE d;
207 std::vector<DIMTYPE> selected;
208 };
209 DIMTYPE _n;
210 IDXTYPE _horizon;
212 bool _frozen;
213 std::vector<FeatureStat> _fs;
214 std::vector<BatchEntry> _batch;
215 std::vector<char> _mark;
216 IDXTYPE _total_evals;
218 std::mutex _add_mutex;
219};
220
221template<class RETURNTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET>
223{
224 assert(n>0);
225 _n=n;
226 _fs.assign(_n,FeatureStat());
227 for(DIMTYPE f=0;f<_n;f++) {
228 _fs[f].m_is=0.0; _fs[f].m_isnot=0.0; _fs[f].v_is=0.0;
229 _fs[f].raw_sum_is=0.0; _fs[f].raw_cnt_is=0.0;
230 _fs[f].n_is=0; _fs[f].n_isnot=0;
231 }
232 _mark.assign(_n,0);
233 _batch.clear();
234 _frozen=false;
235 _total_evals=0;
237}
238
239template<class RETURNTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET>
241{
242 assert(sub);
243 std::lock_guard<std::mutex> lock(_add_mutex);
244 if(_frozen) return true; // frozen ranking: the no-op is a success, callers must not treat it as an error
245 if(_n==0) reset(sub->get_n());
246 assert(_n==sub->get_n());
247 if(_n!=sub->get_n()) return false;
248 BatchEntry e;
249 e.value=value;
250 e.d=sub->get_d();
251 e.selected.reserve(e.d);
252 for(DIMTYPE f : sub->selected_features()) e.selected.push_back(f);
253 _batch.push_back(std::move(e));
254 _total_evals++;
255 return true;
256}
257
258template<class RETURNTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET>
260{
261 std::lock_guard<std::mutex> lock(_add_mutex);
262 if(_frozen) {_batch.clear(); return 0;}
263 const IDXTYPE B=(IDXTYPE)_batch.size();
264 if(B==0) return 0;
265 assert(_n>0);
266 double mu=0.0;
267 for(IDXTYPE i=0;i<B;i++) mu+=(double)_batch[i].value;
268 mu/=(double)B;
269 double var=0.0;
270 for(IDXTYPE i=0;i<B;i++) {const double dv=(double)_batch[i].value-mu; var+=dv*dv;}
271 var/=(double)B;
272 const double sd=std::sqrt(var);
273 const bool degenerate=!(sd>1e-12); // constant batch (or B==1) carries no ranking information -> z=0
274 for(IDXTYPE i=0;i<B;i++) {
275 const BatchEntry &e=_batch[i];
276 assert(e.d==_batch[0].d); // caller contract: one batch = one cardinality
277 const RETURNTYPE z=degenerate?(RETURNTYPE)0.0:(RETURNTYPE)(((double)e.value-mu)/sd);
278 for(size_t k=0;k<e.selected.size();k++) _mark[e.selected[k]]=1;
279 const RETURNTYPE dinv=(e.d>0)?(RETURNTYPE)(1.0/(double)e.d):(RETURNTYPE)0.0;
280 for(DIMTYPE j=0;j<_n;j++) {
281 FeatureStat &s=_fs[j];
282 if(_mark[j]) {
283 s.n_is++;
284 const RETURNTYPE a=(RETURNTYPE)1.0/(RETURNTYPE)(s.n_is<_horizon?s.n_is:_horizon);
285 s.m_is+=a*(z-s.m_is);
286 s.v_is+=a*(z*z-s.v_is);
287 s.raw_sum_is+=dinv*e.value;
288 s.raw_cnt_is+=dinv;
289 } else {
290 s.n_isnot++;
291 const RETURNTYPE a=(RETURNTYPE)1.0/(RETURNTYPE)(s.n_isnot<_horizon?s.n_isnot:_horizon);
292 s.m_isnot+=a*(z-s.m_isnot);
293 }
294 }
295 for(size_t k=0;k<e.selected.size();k++) _mark[e.selected[k]]=0;
296 }
297 _batch.clear();
299 return B;
300}
301
302template<class RETURNTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET>
304{
305 assert(f<_n);
306 const FeatureStat &s=_fs[f];
307 if(_mode==STATS_RAWMEAN) return (s.raw_cnt_is>0.0)?(s.raw_sum_is/s.raw_cnt_is):(RETURNTYPE)0.0;
308 return s.m_is-s.m_isnot;
309}
310
311template<class RETURNTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET>
313{
314 std::ostringstream sos;
315 if(_n<1) {sos << "Result_Weighter_Sampled: nothing to print." << std::endl; syncout::print(os,sos); return false;}
316 std::vector<DIMTYPE> idx(_n);
317 for(DIMTYPE f=0;f<_n;f++) idx[f]=f;
318 const DIMTYPE k=(top>0 && top<_n)?top:_n;
319 std::partial_sort(idx.begin(),idx.begin()+k,idx.end(),
320 [this](const DIMTYPE a,const DIMTYPE b){const RETURNTYPE sa=score(a),sb=score(b); return sa>sb || (sa==sb && a<b);});
321 sos << "Sampled-step feature stats (top " << k << " of " << _n << ", evals=" << _total_evals << ", batches=" << _flushed_batches << "):" << std::endl;
322 for(DIMTYPE i=0;i<k;i++) {
323 const DIMTYPE f=idx[i];
324 sos << " F:" << f << " score=" << score(f)
325 << " m_is=" << _fs[f].m_is << " m_isnot=" << _fs[f].m_isnot
326 << " n_is=" << _fs[f].n_is << " n_isnot=" << _fs[f].n_isnot << std::endl;
327 }
328 syncout::print(os,sos);
329 return true;
330}
331
332} // namespace
333#endif // FSTRESULTWEIGHTERSAMPLED_H ///:~
Online per-feature statistics for budgeted (sampled) sequential steps — discounted batch-standardized...
Definition result_weighter_sampled.hpp:128
IDXTYPE _flushed_batches
count of non-empty flush_batch() calls since construction/reset() (see flushed_batches())
Definition result_weighter_sampled.hpp:217
std::vector< BatchEntry > _batch
buffered, not-yet-flushed evaluations added since the last flush_batch()
Definition result_weighter_sampled.hpp:214
IDXTYPE _horizon
adaptive-rate horizon supplied at construction (clamped to at least 1)
Definition result_weighter_sampled.hpp:210
IDXTYPE count_isnot(const DIMTYPE f) const
how many evaluated subsets lacked f ("what happens without f" is the scarce observation for backward-...
Definition result_weighter_sampled.hpp:172
std::vector< FeatureStat > _fs
per-feature accumulators, indexed 0.._n-1
Definition result_weighter_sampled.hpp:213
bool print_stats(std::ostream &os, const DIMTYPE top=20) const
diagnostic listing of the top-scored features
Definition result_weighter_sampled.hpp:312
RETURNTYPE score(const DIMTYPE f) const
current sampling score of feature f (see class doc)
Definition result_weighter_sampled.hpp:303
IDXTYPE flushed_batches() const
number of non-empty flush_batch() calls processed since construction/reset() (a count of batches,...
Definition result_weighter_sampled.hpp:174
DIMTYPE get_n() const
current feature-space dimensionality (0 until the first add() or reset())
Definition result_weighter_sampled.hpp:151
IDXTYPE flush_batch()
z-score the buffered batch and fold it into the accumulators; returns the number of evaluations flush...
Definition result_weighter_sampled.hpp:259
StatsMode
Selects which statistic score(f) reports: STATS_ZCONTRAST (default) is the batch-standardized DAF-sty...
Definition result_weighter_sampled.hpp:136
StatsMode _mode
configured StatsMode, selects which statistic score() reports
Definition result_weighter_sampled.hpp:211
std::shared_ptr< SUBSET > PSubset
shared-ownership handle to the evaluated Subset passed into add()
Definition result_weighter_sampled.hpp:130
bool is_frozen() const
true once freeze() has been called (see freeze())
Definition result_weighter_sampled.hpp:168
std::ostream & print(std::ostream &os) const
Write a compact one-line summary (n, horizon, mode, frozen flag, total evaluations) to os....
Definition result_weighter_sampled.hpp:180
std::vector< char > _mark
flush_batch() scratch bitmap (size _n); marks one entry's selected features while folding it in,...
Definition result_weighter_sampled.hpp:215
IDXTYPE _total_evals
cumulative count of evaluations passed to add() since construction/reset() (see total_evals())
Definition result_weighter_sampled.hpp:216
bool add(const RETURNTYPE value, const PSubset sub)
Buffer one evaluated subset for the current batch (thread-safe; may be called from threaded-evaluator...
Definition result_weighter_sampled.hpp:240
std::mutex _add_mutex
guards _batch/_total_evals/_frozen so add() is safe to call from threaded-evaluator worker callbacks
Definition result_weighter_sampled.hpp:218
IDXTYPE total_evals() const
cumulative count of evaluations passed to add() since construction/reset(), including any still buffe...
Definition result_weighter_sampled.hpp:173
DIMTYPE _n
current feature-space dimensionality, set by reset() (called explicitly, or lazily by the first add()...
Definition result_weighter_sampled.hpp:209
void freeze()
Freezes the ranking: flushes any pending batch, then turns all further add()/flush_batch() calls into...
Definition result_weighter_sampled.hpp:167
StatsMode get_mode() const
the configured StatsMode (see StatsMode)
Definition result_weighter_sampled.hpp:152
IDXTYPE count_is(const DIMTYPE f) const
how many evaluated subsets contained f (exploration bookkeeping)
Definition result_weighter_sampled.hpp:171
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...
Definition result_weighter_sampled.hpp:142
IDXTYPE get_horizon() const
the (clamped, >=1) adaptive-rate horizon supplied at construction
Definition result_weighter_sampled.hpp:153
bool _frozen
set by freeze(); once true, add()/flush_batch() are no-ops and statistics stay frozen at their warm-u...
Definition result_weighter_sampled.hpp:212
void reset(const DIMTYPE n)
(Re)dimension to n features and zero all statistics, the pending batch and the counters....
Definition result_weighter_sampled.hpp:222
static void print(std::ostream &os, std::ostringstream &sos)
Writes sos's buffered content to os, serializing concurrent writers under FST_THREADED via a shared m...
Definition global.hpp:86
FST4 specific error passing class.
Global definitions.
The Feature Selection Toolbox 4 library: every library component – data access, criteria and classifi...
Definition data_accessor.hpp:80
void notify(const std::string msg)
Prints msg followed by a newline via syncout::print(); a no-op unless the preprocessor macro DEBUG is...
Definition global.hpp:112
One buffered, not-yet-flushed criterion evaluation: its raw value, the cardinality of the evaluated s...
Definition result_weighter_sampled.hpp:204
std::vector< DIMTYPE > selected
indices of the subset's selected features
Definition result_weighter_sampled.hpp:207
DIMTYPE d
cardinality of the evaluated subset (caller contract: identical for every entry in one batch)
Definition result_weighter_sampled.hpp:206
RETURNTYPE value
the raw criterion value returned for this evaluated subset
Definition result_weighter_sampled.hpp:205
Per-feature accumulators, one instance per feature index, updated by flush_batch()....
Definition result_weighter_sampled.hpp:191
RETURNTYPE raw_cnt_is
matching 1/|S|-weighted normalizer for raw_sum_is
Definition result_weighter_sampled.hpp:196
IDXTYPE n_isnot
number of evaluations in which the feature was not selected (exploration count, see count_isnot())
Definition result_weighter_sampled.hpp:198
RETURNTYPE m_isnot
adaptive-rate mean of batch-z over evaluations where the feature was not selected (STATS_ZCONTRAST sc...
Definition result_weighter_sampled.hpp:193
RETURNTYPE raw_sum_is
1/|S|-weighted sum of raw criterion values over 'is' evaluations (STATS_RAWMEAN score source)
Definition result_weighter_sampled.hpp:195
RETURNTYPE m_is
adaptive-rate mean of batch-z over evaluations where the feature was selected (STATS_ZCONTRAST score ...
Definition result_weighter_sampled.hpp:192
IDXTYPE n_is
number of evaluations in which the feature was selected (exploration count, see count_is())
Definition result_weighter_sampled.hpp:197
RETURNTYPE v_is
adaptive-rate mean of z^2 on the 'is' side; maintained as a dispersion estimate but not read by score...
Definition result_weighter_sampled.hpp:194
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.