Feature Selection Toolbox FST4
UTIA · Czech Academy of Sciences
Loading...
Searching...
No Matches
criterion_normal_bhattacharyya.hpp
Go to the documentation of this file.
1#ifndef FSTCRITERIONNORMALBHATTACHARYYA_H
2#define FSTCRITERIONNORMALBHATTACHARYYA_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 <cassert>
51#include <iostream>
52#include <cmath>
53#include "error.hpp"
54#include "global.hpp"
55#include "criterion_normal.hpp"
56#include "indexed_vector.hpp"
57#include "indexed_matrix.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
77CLASSIFIER - class implementing interface defined in abstract class Classifier
78EVALUATOR - class implementing interface defined in abstract class Sequential_Step
79DISTANCE - class implementing interface defined in abstract class Distance
80DATAACCESSOR - class implementing interface defined in abstract class Data_Accessor
81INTERVALCONTAINER - class of class type Data_Intervaller
82CONTAINER - STL container of class type Data_Interval
83========================================================================== */
84
85namespace FST {
86
104template<class RETURNTYPE, typename DATATYPE, typename REALTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET, class DATAACCESSOR>
105class Criterion_Normal_Bhattacharyya : public Clonable_Impl<Criterion_Normal_Bhattacharyya<RETURNTYPE,DATATYPE,REALTYPE,IDXTYPE,DIMTYPE,SUBSET,DATAACCESSOR>,Criterion_Normal<RETURNTYPE,DATATYPE,REALTYPE,IDXTYPE,DIMTYPE,SUBSET,DATAACCESSOR> > {
106public:
109 typedef std::shared_ptr<DATAACCESSOR> PDataAccessor;
110 typedef std::shared_ptr<SUBSET> PSubset;
111 Criterion_Normal_Bhattacharyya() {notify("Criterion_Normal_Bhattacharyya constructor.");}
112 virtual ~Criterion_Normal_Bhattacharyya() {notify("Criterion_Normal_Bhattacharyya destructor.");}
113protected:
114 // Template-method hooks: initialize()/evaluate() skeletons live in Criterion_Normal
115 virtual const char* criterion_name() const override {return "Criterion_Normal_Bhattacharyya";}
122 virtual void update_derived_model() override {
123 _cov12->copy_raw(parent::_model->get_cov()[0]);
124 _cov12->add_raw(parent::_model->get_cov()[1]);
125 _cov12_div2->copy_constmul_raw(*_cov12,0.5);
126 }
127 virtual bool evaluate_narrowed(RETURNTYPE &result, const PSubset sub) override;
128private:
129 friend parent_impl;
131 Criterion_Normal_Bhattacharyya(const Criterion_Normal_Bhattacharyya& cnb);
132private:
133 std::unique_ptr<Indexed_Matrix<DATATYPE,DIMTYPE,SUBSET> > _cov12;
134 std::unique_ptr<Indexed_Matrix<DATATYPE,DIMTYPE,SUBSET> > _cov12_div2;
135 std::unique_ptr<Indexed_Matrix<REALTYPE,DIMTYPE,SUBSET> > _invbuf;
136 std::unique_ptr<Indexed_Matrix<REALTYPE,DIMTYPE,SUBSET> > _LUtemp;
137};
138
139template<class RETURNTYPE, typename DATATYPE, typename REALTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET, class DATAACCESSOR>
140Criterion_Normal_Bhattacharyya<RETURNTYPE,DATATYPE,REALTYPE,IDXTYPE,DIMTYPE,SUBSET,DATAACCESSOR>::Criterion_Normal_Bhattacharyya(const Criterion_Normal_Bhattacharyya& cnb) :
141 parent_impl(cnb)
142{
143 notify("Criterion_Normal_Bhattacharyya copy-constructor.");
148}
149
150template<class RETURNTYPE, typename DATATYPE, typename REALTYPE, typename IDXTYPE, typename DIMTYPE, class SUBSET, class DATAACCESSOR>
152{ // (model and _meandif have been narrowed to sub by Criterion_Normal::evaluate)
153 notify("Criterion_Normal_Bhattacharyya::evaluate_narrowed().");
154 assert(_cov12);
155 assert(_cov12_div2);
156 assert(_invbuf);
157 assert(_LUtemp);
158 assert(parent::get_n()==_cov12->get_n());
159 assert(parent::get_n()==_cov12_div2->get_n());
160 assert(parent::get_n()<=_invbuf->get_n_max());
161 assert(parent::get_n()<=_LUtemp->get_n_max());
162
163 RETURNTYPE logdet1,logdet2,logdet3;
164
165 _cov12->narrow_to(sub);
166 _cov12_div2->narrow_to(sub);
167
168 _invbuf->redim(parent::get_d());
169 _LUtemp->redim(parent::get_d());
170
171 // The covariance term ln( |S| / sqrt(|S0| |S1|) ) is formed in the LOG domain from
172 // log_determinant(): the three determinants themselves are products of d LU pivots and
173 // leave the double range (overflow to inf, or underflow to 0 and a bogus "singular"
174 // report) long before the matrices become ill-conditioned -- a 100-feature subset of
175 // features with variance 1e8 has |S| ~ 1e800. The log form depends only on the geometry,
176 // not on the feature scale, and is exact where the plain product would still be finite.
177 _cov12->LUdecompose(*_LUtemp);
178 _cov12->invert(*_invbuf,*_LUtemp);
179 parent::_model->get_cov()[0].LUdecompose(*_LUtemp);
180 logdet1=parent::_model->get_cov()[0].log_determinant(*_LUtemp);
181 parent::_model->get_cov()[1].LUdecompose(*_LUtemp);
182 logdet2=parent::_model->get_cov()[1].log_determinant(*_LUtemp);
183 _cov12_div2->LUdecompose(*_LUtemp);
184 logdet3=_cov12_div2->log_determinant(*_LUtemp);
185
186 // LIMITATION: a singular class covariance on the evaluated subset makes the criterion
187 // undefined and is reported by throwing, not by returning false. It happens when the
188 // subset contains constant, duplicate or linearly dependent features, or when d exceeds
189 // the number of training samples of a class. Remedies: reduce the target subset size,
190 // drop the constant/collinear features, use more training data, or pick a criterion that
191 // does not invert per-class covariances (e.g. a wrapper criterion). A zero LU pivot gives
192 // ln 0 = -inf here (LUdecompose() itself throws on an all-zero row).
193 if(!std::isfinite(logdet1) || !std::isfinite(logdet2))
194 throw FST::fst_error("Criterion_Normal_Bhattacharyya::evaluate: singular class covariance matrix on the evaluated subset (zero determinant)");
195 RETURNTYPE right=0.5*(logdet3-0.5*(logdet1+logdet2));
196 RETURNTYPE left=0.0;
197 RETURNTYPE pom;
198
199 for(DIMTYPE j=0;j<parent::get_d();j++)
200 {
201 pom=0.0;
202 for(DIMTYPE i=0;i<parent::get_d();i++)
203 {
204 pom+=parent::_meandif->at(i)*_invbuf->at_raw(i,j);
205 }
206 left+=pom*parent::_meandif->at(j);
207 }
208 result=0.25*left+right;
209 return true;
210}
211
212} // namespace
213#endif // FSTCRITERIONNORMALBHATTACHARYYA_H ///:~
CRTP mixin implementing the Clonable protocol for a concrete class.
Definition clonable.hpp:184
Implements Bhattacharyya distance based on normal (gaussian) model to serve as feature selection crit...
Definition criterion_normal_bhattacharyya.hpp:105
std::unique_ptr< Indexed_Matrix< DATATYPE, DIMTYPE, SUBSET > > _cov12
(cov[0]+cov[1]), computed by update_derived_model()
Definition criterion_normal_bhattacharyya.hpp:133
std::unique_ptr< Indexed_Matrix< REALTYPE, DIMTYPE, SUBSET > > _LUtemp
scratch LU-decomposition storage, reused for each matrix inversion/determinant
Definition criterion_normal_bhattacharyya.hpp:136
virtual const char * criterion_name() const override
class name, used in output and error messages
Definition criterion_normal_bhattacharyya.hpp:115
Criterion_Normal< RETURNTYPE, DATATYPE, REALTYPE, IDXTYPE, DIMTYPE, SUBSET, DATAACCESSOR > parent
base class: the normal-model template-method skeleton
Definition criterion_normal_bhattacharyya.hpp:107
virtual void allocate_buffers() override
(re)allocate criterion-specific work buffers for get_n() features (use the alloc_* helpers)
Definition criterion_normal_bhattacharyya.hpp:116
std::shared_ptr< SUBSET > PSubset
shared pointer to the feature subset being evaluated
Definition criterion_normal_bhattacharyya.hpp:110
virtual void update_derived_model() override
Definition criterion_normal_bhattacharyya.hpp:122
std::unique_ptr< Indexed_Matrix< REALTYPE, DIMTYPE, SUBSET > > _invbuf
inverse of the narrowed _cov12, used in the quadratic-form term
Definition criterion_normal_bhattacharyya.hpp:135
Clonable_Impl< Criterion_Normal_Bhattacharyya, parent > parent_impl
implements clone(); sharing/stateless_clone throw in Criterion
Definition criterion_normal_bhattacharyya.hpp:108
std::unique_ptr< Indexed_Matrix< DATATYPE, DIMTYPE, SUBSET > > _cov12_div2
_cov12/2, the pooled covariance whose determinant enters the Bhattacharyya distance
Definition criterion_normal_bhattacharyya.hpp:134
std::shared_ptr< DATAACCESSOR > PDataAccessor
shared pointer to the data accessor the model is learned from
Definition criterion_normal_bhattacharyya.hpp:109
virtual bool evaluate_narrowed(RETURNTYPE &result, const PSubset sub) override
narrow remaining buffers to sub, redim work buffers to get_d(), compute the criterion value....
Definition criterion_normal_bhattacharyya.hpp:151
Abstract class, defines interface for feature selection criterion implementations based on normal mod...
Definition criterion_normal.hpp:100
std::unique_ptr< Model_Normal< DATATYPE, REALTYPE, IDXTYPE, DIMTYPE, SUBSET, DATAACCESSOR > > _model
the learned per-class normal (mean/covariance) model, narrowed in evaluate()
Definition criterion_normal.hpp:149
void alloc_matrix(std::unique_ptr< Indexed_Matrix< MATRIXVALUETYPE, DIMTYPE, SUBSET > > &m, const bool LUstorage=false)
lazy (re)allocation of a work matrix for get_n() features; LUstorage as required by Indexed_Matrix::L...
Definition criterion_normal.hpp:144
DIMTYPE get_n() const
the full (raw, unnarrowed) feature count the model was learned for
Definition criterion_normal.hpp:119
std::unique_ptr< Indexed_Vector< DATATYPE, DIMTYPE, SUBSET > > _meandif
mean[0]-mean[1], shared by all two-class normal criteria
Definition criterion_normal.hpp:150
DIMTYPE get_d() const
the currently active (narrowed) feature count, see evaluate()
Definition criterion_normal.hpp:120
Matrix representation and operations, allows operation in selected subspace.
Definition indexed_matrix.hpp:102
FST4 specific error passing class.
Definition error.hpp:61
Defines interface for feature selection criterion implementations based on normal model.
FST4 specific error passing class.
Global definitions.
Matrix representation and operations, allows operation in selected subspace.
Vector representation and operations, allows operation in selected subspace.
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
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.