1#ifndef FSTRESULTTRACKERFEATURESTATS_H
2#define FSTRESULTTRACKERFEATURESTATS_H
108template<
class RETURNTYPE,
typename IDXTYPE,
typename DIMTYPE,
class SUBSET>
109class Result_Tracker_Feature_Stats :
public Clonable_Impl<Result_Tracker_Feature_Stats<RETURNTYPE,IDXTYPE,DIMTYPE,SUBSET>,Result_Tracker_Dupless<RETURNTYPE,IDXTYPE,DIMTYPE,SUBSET>,CLONE_INHERIT,CLONE_INHERIT,CLONE_DEEP> {
150 bool getFirstDAF(RETURNTYPE &value, DIMTYPE &feature,
const unsigned int DAFidx=0)
const;
153 bool getNextDAF(RETURNTYPE &value, DIMTYPE &feature,
const unsigned int DAFidx=0)
const;
182 bool print_pair_stats(std::ostream& os=std::cout,
const std::size_t top_pairs=0);
191 bool getFirstPairDAF(RETURNTYPE &daf0, RETURNTYPE &daf1,
bool &daf1_valid, RETURNTYPE &synergy, DIMTYPE &
f1, DIMTYPE &f2)
const;
194 bool getNextPairDAF(RETURNTYPE &daf0, RETURNTYPE &daf1,
bool &daf1_valid, RETURNTYPE &synergy, DIMTYPE &
f1, DIMTYPE &f2)
const;
251 static std::size_t
pair_index(
const std::size_t a,
const std::size_t b,
const std::size_t k) {assert(a<b && b<k);
return a*k - a*(a+1)/2 + (b-a-1);}
256template<
class RETURNTYPE,
typename IDXTYPE,
typename DIMTYPE,
class SUBSET>
263 _n=iter->sub->get_n();
265 for(DIMTYPE f=0;f<
_n;f++) {
267 _stats[f].daf_valid[0]=
false;
268 _stats[f].daf_valid[1]=
false;
269 _stats[f].daf_valid[2]=
false;
272 for(DIMTYPE ss=1;ss<=
_n;ss++) {
281 assert(iter->sub->get_n()==
_n);
282 DIMTYPE d=iter->sub->get_d();
283 assert(d>0 && d<=
_n);
284 for(DIMTYPE f=0;f<
_n;f++) {
285 if(iter->sub->selected_raw(f)) {
287 _stats[f].mean_is+=iter->value;
290 _stats[f].mean_isnot+=iter->value;
293 _dstat[d].mean+=iter->value;
298 for(DIMTYPE f=0;f<
_n;f++)
303 for(DIMTYPE ss=1;ss<=
_n;ss++)
if(
_dstat[ss].freq>0) {
311 assert(iter->sub->get_n()==
_n);
312 DIMTYPE d=iter->sub->get_d();
313 assert(d>0 && d<=
_n);
314 for(DIMTYPE f=0;f<
_n;f++) {
315 if(iter->sub->selected_raw(f)) {
318 _stats[f].stdev_isnot+=(
_stats[f].mean_isnot-iter->value)*(
_stats[f].mean_isnot-iter->value);
325 for(DIMTYPE f=0;f<
_n;f++)
332 for(DIMTYPE ss=1;ss<=
_n;ss++)
if(
_dstat[ss].freq>0) {
340 for(DIMTYPE f=0;f<
_n;f++)
350 _stats[f].daf_valid[1]=
true;
353 _stats[f].daf_valid[0]=
true;
355 else _stats[f].daf_valid[1]=
_stats[f].daf_valid[0]=
false;
362 std::vector<RETURNTYPE> mi1,mi2; mi1.resize(
_n); mi2.resize(
_n);
363 std::vector<IDXTYPE> cnt1,cnt2; cnt1.resize(
_n); cnt2.resize(
_n);
364 for(DIMTYPE f=0;f<
_n;f++) {mi1[f]=mi2[f]=0; cnt1[f]=cnt2[f]=0;}
367 assert(iter->sub->get_n()==
_n);
368 DIMTYPE d=iter->sub->get_d();
369 assert(d>0 && d<=
_n);
372 for(DIMTYPE f=0;f<
_n;f++) {
373 if(iter->sub->selected_raw(f)) {mi1[f]+=iter->value/
_dstat[d].stdev; cnt1[f]++;}
374 else {mi2[f]+=iter->value/
_dstat[d].stdev; cnt2[f]++;}
378 for(DIMTYPE f=0;f<
_n;f++) {
379 if(cnt1[f]==0 || cnt2[f]==0)
_stats[f].daf[2]=0;
else
383 _stats[f].daf[2]=mi1[f]-mi2[f];
385 _stats[f].daf_valid[2]=
true;
391 for(
unsigned int DAFidx=0; DAFidx<3; DAFidx++)
394 for(DIMTYPE f=0;f<
_n;f++)
396 if(
_stats[f].daf_valid[DAFidx]) {
397 typename ORDERTYPE::iterator iter=
_order[DAFidx].begin();
399 _order[DAFidx].insert(iter,f);
402 if(
_order[DAFidx].
size()<
_n &&
parent::output_normal()) {std::ostringstream sos; sos <<
"WARNING: DAF"<<DAFidx<<
" rank could not be computed for all features due to insufficient number of evaluated probe subsets." << std::endl << std::flush;
syncout::print(os,sos);}
406 for(DIMTYPE f=1;f<
_n;f++) {
407 if(
_stats[f].freq_isnot<minfreq) minfreq=
_stats[f].freq_isnot;
408 if(
_stats[f].freq_is<minfreq) minfreq=
_stats[f].freq_is;
411 std::ostringstream sos;
412 sos <<
"Lowest feature evaluation frequency over all probes is "<<minfreq<<
"." << std::endl;
413 if(minfreq<100) sos <<
"WARNING: To ensure reliable DAF estimates the minimum feature evaluation frequency should be at least in the order of hundreds. More probes may be needed." << std::endl;
414 sos << std::endl << std::flush;
422template<
class RETURNTYPE,
typename IDXTYPE,
typename DIMTYPE,
class SUBSET>
425 std::ostringstream sos;
426 if(
_n<1) {sos <<
"Result_Tracker_Feature_Stats:: Nothing to print out." << std::endl;
syncout::print(os,sos);
return false;}
428 sos <<
"Probe subset stats for each (valid) cardinality:"<< std::endl;
429 for(DIMTYPE ss=1;ss<=
_n;ss++)
430 if(
_dstat[ss].valid) sos <<
" d: "<< ss <<
" mean=" <<
_dstat[ss].mean <<
", stddev=" <<
_dstat[ss].stdev <<
", freq=" <<
_dstat[ss].freq << std::endl;
431 sos << std::endl <<
"Feature stats over all probe subsets:"<< std::endl;
432 for(DIMTYPE f=0;f<
_n;f++) {
433 sos <<
" F:"<<f<<
" daf0 = ";
if(
_stats[f].daf_valid[0]) sos <<
_stats[f].daf[0];
else sos <<
"n/a";
434 sos <<
", daf1 = ";
if(
_stats[f].daf_valid[1]) sos <<
_stats[f].daf[1];
else sos <<
"n/a";
435 sos <<
", daf2 = ";
if(
_stats[f].daf_valid[2]) sos <<
_stats[f].daf[2];
else sos <<
"n/a";
436 sos<<
", freq "<<
_stats[f].freq_is<<
"|"<<
_stats[f].freq_isnot<<
", mean ";
437 if(
_stats[f].freq_is>0) sos<<
_stats[f].mean_is;
else sos<<
"n/a";
439 if(
_stats[f].freq_isnot>0) sos<<
_stats[f].mean_isnot;
else sos<<
"n/a";
441 if(
_stats[f].freq_is>0) sos<<
_stats[f].stdev_is;
else sos<<
"n/a";
443 if(
_stats[f].freq_isnot>0) sos<<
_stats[f].stdev_isnot;
else sos <<
"n/a";
452template<
class RETURNTYPE,
typename IDXTYPE,
typename DIMTYPE,
class SUBSET>
460 if(!
_order[DAFidx].empty()) {
461 feature=
_order[DAFidx][0];
463 value=
_stats[feature].daf[DAFidx];
469template<
class RETURNTYPE,
typename IDXTYPE,
typename DIMTYPE,
class SUBSET>
479 value=
_stats[feature].daf[DAFidx];
486template<
class RETURNTYPE,
typename IDXTYPE,
typename DIMTYPE,
class SUBSET>
491 if(top_k<2)
return false;
492 const std::size_t K = std::min<std::size_t>(top_k,
_order[0].
size());
493 if(K<2)
return false;
501 const std::size_t P=K*(K-1)/2;
502 std::vector<RETURNTYPE> both_freq(P,0), both_sum(P,0), both_sumsq(P,0);
503 std::vector<RETURNTYPE> f_freq(K,0), f_sum(K,0), f_sumsq(K,0);
504 RETURNTYPE t_freq=0, t_sum=0, t_sumsq=0;
505 std::vector<std::size_t> present; present.reserve(K);
508 assert(iter->sub->get_n()==
_n);
509 const RETURNTYPE v=iter->value;
510 t_freq+=1; t_sum+=v; t_sumsq+=v*v;
512 for(std::size_t k=0;k<K;k++)
if(iter->sub->selected_raw(
_pair_features[k])) present.push_back(k);
513 for(std::size_t i=0;i<present.size();i++) {
514 const std::size_t a=present[i];
515 f_freq[a]+=1; f_sum[a]+=v; f_sumsq[a]+=v*v;
516 for(std::size_t j=i+1;j<present.size();j++) {
517 const std::size_t ij=
pair_index(a,present[j],K);
518 both_freq[ij]+=1; both_sum[ij]+=v; both_sumsq[ij]+=v*v;
525 std::size_t valid_count=0;
526 for(std::size_t a=0;a<K;a++)
for(std::size_t b=a+1;b<K;b++) {
530 const RETURNTYPE fb=both_freq[ij], sb=both_sum[ij], qb=both_sumsq[ij];
531 const RETURNTYPE f1o=f_freq[a]-fb, s1o=f_sum[a]-sb;
532 const RETURNTYPE f2o=f_freq[b]-fb, s2o=f_sum[b]-sb;
533 const RETURNTYPE fn=t_freq-f_freq[a]-f_freq[b]+fb;
534 const RETURNTYPE sn=t_sum-f_sum[a]-f_sum[b]+sb;
535 const RETURNTYPE qn=t_sumsq-f_sumsq[a]-f_sumsq[b]+qb;
538 ps.
valid=(fb>0 && fn>0 && f1o>0 && f2o>0);
541 const RETURNTYPE mb=sb/fb, mn=sn/fn, m1o=s1o/f1o, m2o=s2o/f2o;
544 RETURNTYPE vb=qb/fb-mb*mb;
if(vb<0) vb=0;
545 RETURNTYPE vn=qn/fn-mn*mn;
if(vn<0) vn=0;
546 const RETURNTYPE denom=(fb/(fb+fn))*sqrt(vb) + (fn/(fb+fn))*sqrt(vn);
556 if(_pair_stats[x].daf0!=_pair_stats[y].daf0) return _pair_stats[x].daf0>_pair_stats[y].daf0;
557 if(_pair_stats[x].f1!=_pair_stats[y].f1) return _pair_stats[x].f1<_pair_stats[y].f1;
558 return _pair_stats[x].f2<_pair_stats[y].f2;
562 std::ostringstream sos;
563 sos <<
"compute_pair_stats(): pairwise stats over the top " << K <<
" DAF0-ranked features (" << P <<
" pairs, " << valid_count <<
" valid)." << std::endl;
564 if(valid_count<P) sos <<
"WARNING: " << (P-valid_count) <<
" pairs have an empty presence cell (insufficient probes); they carry no pair-DAF value." << std::endl;
568 return valid_count>0;
571template<
class RETURNTYPE,
typename IDXTYPE,
typename DIMTYPE,
class SUBSET>
574 std::ostringstream sos;
575 if(
_pair_order.empty()) {sos <<
"Result_Tracker_Feature_Stats:: No pairwise stats to print out." << std::endl;
syncout::print(os,sos);
return false;}
576 const std::size_t count = (top_pairs==0 || top_pairs>
_pair_order.size()) ?
_pair_order.size() : top_pairs;
577 sos <<
"Pairwise DAF stats over the top " <<
_pair_features.size() <<
" DAF0-ranked features (showing " << count <<
" of " <<
_pair_order.size() <<
" valid pairs, best pair-DAF0 first):" << std::endl;
578 for(std::size_t i=0;i<count;i++) {
580 sos <<
" P:("<<ps.
f1<<
","<<ps.
f2<<
") pairdaf0 = " << ps.
daf0;
581 sos <<
", pairdaf1 = ";
if(ps.
daf1_valid) sos << ps.
daf1;
else sos <<
"n/a";
582 sos <<
", synergy = " << ps.
synergy;
590template<
class RETURNTYPE,
typename IDXTYPE,
typename DIMTYPE,
class SUBSET>
605template<
class RETURNTYPE,
typename IDXTYPE,
typename DIMTYPE,
class SUBSET>
CRTP mixin implementing the Clonable protocol for a concrete class.
Definition clonable.hpp:184
Collects multiple results, avoiding duplicates.
Definition result_tracker_dupless.hpp:92
RESULTSITER end()
iterator past the last held result
Definition result_tracker_dupless.hpp:147
parent::ResultRec ResultRec
see Result_Tracker::ResultRec
Definition result_tracker_dupless.hpp:96
std::list< ResultRec > results
held results, sorted descending by value (ties broken toward the smaller subset); see add() for the e...
Definition result_tracker_dupless.hpp:138
const IDXTYPE _capacity_limit
set by the constructor; 0 = unlimited
Definition result_tracker_dupless.hpp:141
std::list< ResultRec >::const_iterator CONSTRESULTSITER
read-only iterator over results, for use by subclasses/friends inspecting the collected results
Definition result_tracker_dupless.hpp:144
RESULTSITER begin()
iterator to the best (first) held result
Definition result_tracker_dupless.hpp:146
virtual std::size_t size() const override
number of results currently held (std::size_t rather than 'long': on LLP64 platforms 'long' is 32 bit...
Definition result_tracker_dupless.hpp:125
Collects evaluated subsets to eventually provide Dependency-Aware Feature Ranking coefficients.
Definition result_tracker_feature_stats.hpp:109
std::vector< DIMTYPE > ORDERTYPE
feature-index ordering vector, as built per DAF variant by compute_stats()
Definition result_tracker_feature_stats.hpp:227
std::vector< std::size_t > _pair_order
indices into _pair_stats, valid pairs only, sorted decreasing pair-DAF0
Definition result_tracker_feature_stats.hpp:248
DIMTYPE _itersize[3]
per DAF variant: getFirstDAF()/getNextDAF() cursor position (index into _order[DAFidx]); 0 = iteratio...
Definition result_tracker_feature_stats.hpp:229
std::vector< SubSizeStat > _dstat
one entry per subset size 1.._n (index 0 unused); filled by compute_stats()
Definition result_tracker_feature_stats.hpp:225
bool getNextDAF(RETURNTYPE &value, DIMTYPE &feature, const unsigned int DAFidx=0) const
Definition result_tracker_feature_stats.hpp:470
std::vector< DIMTYPE > _pair_features
the top-k DAF0-ranked (global) feature indices the pairs are drawn from
Definition result_tracker_feature_stats.hpp:247
bool compute_stats(std::ostream &os=std::cout)
Aggregates DAF ranking statistics (DAF0/DAF1/DAF2) from all probe subsets recorded so far.
Definition result_tracker_feature_stats.hpp:257
bool getFirstDAF(RETURNTYPE &value, DIMTYPE &feature, const unsigned int DAFidx=0) const
Starts an iteration (descending by value) over the feature ordering built by compute_stats() for the ...
Definition result_tracker_feature_stats.hpp:453
parent::ResultRec ResultRec
[subset,criterion value] result record, see Result_Tracker::ResultRec
Definition result_tracker_feature_stats.hpp:113
Result_Tracker_Dupless< RETURNTYPE, IDXTYPE, DIMTYPE, SUBSET > parent
the base tracker: dupless probe storage sorted descending by criterion value; this class adds DAF pos...
Definition result_tracker_feature_stats.hpp:111
std::mutex _itersize_mutex
serializes access to the iteration cursors _itersize AND _pair_itersize across concurrent getFirst/ge...
Definition result_tracker_feature_stats.hpp:231
bool compute_pair_stats(const DIMTYPE top_k, std::ostream &os=std::cout)
Computes pairwise (group) DAF statistics: 2x2 presence-cell contrasts over all pairs of the top top_k...
Definition result_tracker_feature_stats.hpp:487
ORDERTYPE _order[3]
per DAF variant (0=DAF0, 1=DAF1, 2=DAF2): feature indices with a valid DAF value, sorted descending b...
Definition result_tracker_feature_stats.hpp:228
bool print_pair_stats(std::ostream &os=std::cout, const std::size_t top_pairs=0)
Definition result_tracker_feature_stats.hpp:572
static std::size_t pair_index(const std::size_t a, const std::size_t b, const std::size_t k)
Upper-triangle linearization of pair (a,b), a<b<k, into a flat index over PairStat storage (k = the t...
Definition result_tracker_feature_stats.hpp:251
virtual std::ostream & print(std::ostream &os) const override
writes a human-readable identification of the object; base default writes nothing
Definition result_tracker_feature_stats.hpp:198
DIMTYPE _n
Definition result_tracker_feature_stats.hpp:201
ResultRec * PResultRec
raw pointer to a ResultRec, as used by the inherited get_first()/get_next() iteration
Definition result_tracker_feature_stats.hpp:114
bool print_stats(std::ostream &os=std::cout)
Definition result_tracker_feature_stats.hpp:423
std::vector< FeatureStat > _stats
one entry per feature (index 0.._n-1), aggregated over all recorded probes; filled by compute_stats()
Definition result_tracker_feature_stats.hpp:216
bool getFirstPairDAF(RETURNTYPE &daf0, RETURNTYPE &daf1, bool &daf1_valid, RETURNTYPE &synergy, DIMTYPE &f1, DIMTYPE &f2) const
Starts an iteration (decreasing pair-DAF0) over the pairwise statistics built by compute_pair_stats()...
Definition result_tracker_feature_stats.hpp:591
std::shared_ptr< SUBSET > PSubset
Definition result_tracker_feature_stats.hpp:115
bool getNextPairDAF(RETURNTYPE &daf0, RETURNTYPE &daf1, bool &daf1_valid, RETURNTYPE &synergy, DIMTYPE &f1, DIMTYPE &f2) const
Definition result_tracker_feature_stats.hpp:606
Clonable_Impl< Result_Tracker_Feature_Stats, parent, CLONE_INHERIT, CLONE_INHERIT, CLONE_DEEP > parent_impl
implements stateless_clone(); clone()/sharing_clone() throw in Result_Tracker
Definition result_tracker_feature_stats.hpp:112
Result_Tracker_Feature_Stats(const Result_Tracker_Feature_Stats &rtfs)
the stateless_clone() copy: replicates configuration (capacity limit, margin) via the parent copy-con...
Definition result_tracker_feature_stats.hpp:118
std::size_t _pair_itersize
Definition result_tracker_feature_stats.hpp:249
Result_Tracker_Feature_Stats(const IDXTYPE capacity_limit=0)
Definition result_tracker_feature_stats.hpp:117
std::vector< PairStat > _pair_stats
upper-triangle linearization (via pair_index()) over the top-k feature set; filled by compute_pair_st...
Definition result_tracker_feature_stats.hpp:246
bool output_normal() const
true unless output detail is SILENT
Definition result_tracker.hpp:118
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.
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
@ f1
classification, two-class data: F1 of the positive class, which is Metric_Spec::f1_positive (class in...
Definition wrapper_metrics.hpp:63
Enables collecting multiple results.
Structure to gather feature occurrence statistics over probe subset evaluations.
Definition result_tracker_feature_stats.hpp:203
bool daf_valid[3]
per-DAF-variant validity flag; DAF2's entry is always true (see compute_stats())
Definition result_tracker_feature_stats.hpp:214
RETURNTYPE daf[3]
Definition result_tracker_feature_stats.hpp:213
RETURNTYPE mean_is
mean criterion value over probes containing this feature
Definition result_tracker_feature_stats.hpp:206
RETURNTYPE stdev_is
criterion value stdev over probes containing this feature
Definition result_tracker_feature_stats.hpp:208
RETURNTYPE stdev_isnot
Definition result_tracker_feature_stats.hpp:209
RETURNTYPE freq_is
number of recorded probes containing this feature
Definition result_tracker_feature_stats.hpp:204
RETURNTYPE freq_isnot
number of recorded probes not containing this feature
Definition result_tracker_feature_stats.hpp:205
RETURNTYPE mean_isnot
mean criterion value over probes not containing this feature
Definition result_tracker_feature_stats.hpp:207
Structure to hold pairwise feature statistics (2x2 presence-cell contrasts over probe subset evaluati...
Definition result_tracker_feature_stats.hpp:235
RETURNTYPE freq_neither
number of probes containing neither feature
Definition result_tracker_feature_stats.hpp:239
bool valid
all four presence cells non-empty
Definition result_tracker_feature_stats.hpp:243
RETURNTYPE daf0
mean(both present) - mean(both absent)
Definition result_tracker_feature_stats.hpp:240
RETURNTYPE daf1
daf0 normalized by frequency-weighted stdevs of the two cells (0 if daf1_valid==false)
Definition result_tracker_feature_stats.hpp:241
RETURNTYPE synergy
mean_both + mean_neither - mean_f1only - mean_f2only
Definition result_tracker_feature_stats.hpp:242
DIMTYPE f2
global index of the pair's second feature
Definition result_tracker_feature_stats.hpp:237
bool daf1_valid
valid AND the daf1 normalization denominator is positive
Definition result_tracker_feature_stats.hpp:244
RETURNTYPE freq_both
number of probes containing both features
Definition result_tracker_feature_stats.hpp:238
DIMTYPE f1
global index of the pair's first feature
Definition result_tracker_feature_stats.hpp:236
Structure to gather probe subset cardinality statistics.
Definition result_tracker_feature_stats.hpp:219
RETURNTYPE freq
number of recorded probes with this exact subset size (cardinality)
Definition result_tracker_feature_stats.hpp:220
bool valid
true once freq>0 and mean/stdev have been computed (see compute_stats())
Definition result_tracker_feature_stats.hpp:223
RETURNTYPE mean
mean criterion value over probes of this cardinality
Definition result_tracker_feature_stats.hpp:221
RETURNTYPE stdev
criterion value stdev over probes of this cardinality
Definition result_tracker_feature_stats.hpp:222