1 | /*! |
---|
2 | \file |
---|
3 | \brief Bayesian Filtering for mixtures of exponential family (EF) members |
---|
4 | \author Vaclav Smidl. |
---|
5 | |
---|
6 | ----------------------------------- |
---|
7 | BDM++ - C++ library for Bayesian Decision Making under Uncertainty |
---|
8 | |
---|
9 | Using IT++ for numerical operations |
---|
10 | ----------------------------------- |
---|
11 | */ |
---|
12 | |
---|
13 | #ifndef MEF_H |
---|
14 | #define MEF_H |
---|
15 | |
---|
16 | |
---|
17 | #include "../stat/libFN.h" |
---|
18 | #include "../stat/libEF.h" |
---|
19 | #include "../stat/emix.h" |
---|
20 | |
---|
21 | namespace bdm { |
---|
22 | |
---|
23 | enum MixEF_METHOD { EM = 0, QB = 1}; |
---|
24 | |
---|
25 | /*! |
---|
26 | * \brief Mixture of Exponential Family Densities |
---|
27 | |
---|
28 | An approximate estimation method for models with latent discrete variable, such as |
---|
29 | mixture models of the following kind: |
---|
30 | \f[ |
---|
31 | f(y_t|\psi_t, \Theta) = \sum_{i=1}^{n} w_i f(y_t|\psi_t, \theta_i) |
---|
32 | \f] |
---|
33 | where \f$\psi\f$ is a known function of past outputs, \f$w=[w_1,\ldots,w_n]\f$ are component weights, and component parameters \f$\theta_i\f$ are assumed to be mutually independent. \f$\Theta\f$ is an aggregation af all component parameters and weights, i.e. \f$\Theta = [\theta_1,\ldots,\theta_n,w]\f$. |
---|
34 | |
---|
35 | The characteristic feature of this model is that if the exact values of the latent variable were known, estimation of the parameters can be handled by a single model. For example, for the case of mixture models, posterior density for each component parameters would be a BayesianModel from Exponential Family. |
---|
36 | |
---|
37 | This class uses EM-style type algorithms for estimation of its parameters. Under this simplification, the posterior density is a product of exponential family members, hence under EM-style approximate estimation this class itself belongs to the exponential family. |
---|
38 | |
---|
39 | TODO: Extend BM to use rvc. |
---|
40 | */ |
---|
41 | class MixEF: public BMEF { |
---|
42 | protected: |
---|
43 | //!Number of components |
---|
44 | int n; |
---|
45 | //! Models for Components of \f$\theta_i\f$ |
---|
46 | Array<BMEF*> Coms; |
---|
47 | //! Statistics for weights |
---|
48 | multiBM weights; |
---|
49 | //!Posterior on component parameters |
---|
50 | eprod* est; |
---|
51 | ////!Indeces of component rvc in common rvc |
---|
52 | |
---|
53 | //! Flag for a method that is used in the inference |
---|
54 | MixEF_METHOD method; |
---|
55 | |
---|
56 | //! Auxiliary function for use in constructors |
---|
57 | void build_est() { |
---|
58 | est = new eprod; |
---|
59 | if ( n>0 ) { |
---|
60 | Array<const epdf*> epdfs ( n+1 ); |
---|
61 | for ( int i=0;i<Coms.length();i++ ) { |
---|
62 | // it_assert_debug(!x,"MixEF::MixEF : Incompatible components"); |
---|
63 | epdfs ( i ) =& ( Coms ( i )->posterior() ); |
---|
64 | } |
---|
65 | // last in the product is the weight |
---|
66 | epdfs ( n ) =& ( weights.posterior() ); |
---|
67 | est->set_parameters ( epdfs, false ); |
---|
68 | } |
---|
69 | } |
---|
70 | |
---|
71 | public: |
---|
72 | //! Full constructor |
---|
73 | MixEF ( const Array<BMEF*> &Coms0, const vec &alpha0 ) : |
---|
74 | BMEF ( ), n ( Coms0.length() ), Coms ( n ), |
---|
75 | weights (), method ( QB ) { |
---|
76 | // it_assert_debug ( n>0,"MixEF::MixEF : Empty Component list" ); |
---|
77 | |
---|
78 | for ( int i=0;i<n;i++ ) {Coms ( i ) = ( BMEF* ) Coms0 ( i )->_copy_();} |
---|
79 | build_est(); |
---|
80 | }; |
---|
81 | //! Constructor of empty mixture |
---|
82 | MixEF () : |
---|
83 | BMEF ( ), n ( 0 ), Coms ( 0 ), |
---|
84 | weights (),method ( QB ) {build_est();} |
---|
85 | //! Copy constructor |
---|
86 | MixEF ( const MixEF &M2 ) : BMEF ( ), n ( M2.n ), Coms ( n ), |
---|
87 | weights ( M2.weights ), method ( M2.method ) { |
---|
88 | // it_assert_debug ( n>0,"MixEF::MixEF : Empty Component list" ); |
---|
89 | |
---|
90 | for ( int i=0;i<n;i++ ) {Coms ( i ) = M2.Coms ( i )->_copy_();} |
---|
91 | build_est(); |
---|
92 | } |
---|
93 | //! Initializing the mixture by a random pick of centroids from data |
---|
94 | //! \param Com0 Initial component - necessary to determine its type. |
---|
95 | //! \param Data Data on which the initialization will be done |
---|
96 | //! \param c Initial number of components, default=5 |
---|
97 | void init ( BMEF* Com0, const mat &Data, int c=5 ); |
---|
98 | //Destructor |
---|
99 | ~MixEF() { |
---|
100 | delete est; |
---|
101 | for ( int i=0;i<n;i++ ) {delete Coms ( i );} |
---|
102 | } |
---|
103 | //! Recursive EM-like algorithm (QB-variant), see Karny et. al, 2006 |
---|
104 | void bayes ( const vec &dt ); |
---|
105 | //! EM algorithm |
---|
106 | void bayes ( const mat &dt ); |
---|
107 | void bayesB ( const mat &dt, const vec &wData ); |
---|
108 | double logpred ( const vec &dt ) const; |
---|
109 | const epdf& posterior() const {return *est;} |
---|
110 | const eprod* _e() const {return est;} |
---|
111 | emix* epredictor() const; |
---|
112 | //! Flatten the density as if it was not estimated from the data |
---|
113 | void flatten ( const BMEF* M2 ); |
---|
114 | //! Access function |
---|
115 | BMEF* _Coms ( int i ) {return Coms ( i );} |
---|
116 | |
---|
117 | //!Set which method is to be used |
---|
118 | void set_method ( MixEF_METHOD M ) {method=M;} |
---|
119 | }; |
---|
120 | |
---|
121 | } |
---|
122 | #endif // MEF_H |
---|
123 | |
---|