STK++ 0.9.13
STK_IMixtureComposer.cpp
Go to the documentation of this file.
1/*--------------------------------------------------------------------*/
2/* Copyright (C) 2004-2016 Serge Iovleff
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this program; if not, write to the
16 Free Software Foundation, Inc.,
17 59 Temple Place,
18 Suite 330,
19 Boston, MA 02111-1307
20 USA
21
22 Contact : S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
23*/
24
25/*
26 * Project: stkpp::Clustering
27 * created on: 16 oct. 2012
28 * Author: iovleff, S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
29 * Originally created by Parmeet Bhatia <b..._DOT_p..._AT_gmail_Dot_com>
30 **/
31
36#include <cmath>
37
38#if STK_MIXTURE_DEBUG | STK_MIXTURE_VERBOSE | STK_MIXTURE_VERY_VERBOSE
40#endif
41
43
46
47namespace STK
48{
49IMixtureComposer::IMixtureComposer( int nbSample, int nbCluster)
50 : IMixtureStatModel(nbSample, nbCluster)
51 , state_(Clust::modelCreated_)
53 , lnComp_(nbCluster)
54#endif
55{}
56
57/* copy constructor */
60 , state_(model.state_)
62 , lnComp_(model.lnComp_)
63#endif
64{}
65/* destructor */
67
68/* @brief Initialize the model before at its first use.
69 * This function can be overloaded in derived class for initialization of
70 * the specific model parameters. It should be called prior to any used of
71 * the class.
72 * @sa IMixture,MixtureBridge,MixtureComposer
73 **/
75{
76#ifdef STK_MIXTURE_VERBOSE
77 stk_cout << _T("Entering IMixtureComposer::initializeStep\n");
78#endif
79 // (re)initialize the mixture parameters tik and pk. (virtual method)
81 // compute nk
83 // (re) initialize mixtures
85 // compute zi (virtual method)
86 mapStep();
87 // compute proportions pk_ (virtual method)
88 pStep();
89 // (re)initialize the likelihood
91 // compute the number of free parameters
93 // update state
95#ifdef STK_MIXTURE_VERBOSE
96 stk_cout << _T("IMixtureComposer::initializeStep done\n");
97#endif
98#ifdef STK_MIXTURE_VERY_VERBOSE
99 stk_cout << _T("Model parameters\n");
101#endif
102}
103
104/* initialize randomly the labels zi of the model */
106{
107#ifdef STK_MIXTURE_VERY_VERBOSE
108 stk_cout << _T("Entering IMixtureComposer::randomClassInit()\n");
109#endif
110 // initialize mixture model if necessary
112 // generate random zi, compute tik and nk
114 // update parameters
116 // compute eStep()
117 eStep();
118 // model initialized
120#ifdef STK_MIXTURE_VERY_VERBOSE
121 stk_cout << _T("IMixtureComposer::randomClassInit() done\n");
122#endif
123}
124
125/* initialize randomly the posterior probabilities tik of the model */
127{
128#ifdef STK_MIXTURE_VERBOSE
129 stk_cout << _T("Entering IMixtureComposer::randomFuzzyInit(). state= ") << state() << _T("\n");
130#endif
131 // initialize mixture model if necessary
133 // create random tik and compute nk
135 // compute zi
136 mapStep();
137 // update paramters values
139 // eStep
140 eStep();
141 // model intialized
143#ifdef STK_MIXTURE_VERBOSE
144 stk_cout << _T("IMixtureComposer::randomFuzzyInit() done\n");
145#endif
146}
147
148/* cStep */
150{
151#ifdef STK_MIXTURE_VERY_VERBOSE
152 stk_cout << _T("Entering IMixtureComposer::cStep()\n");
153#endif
154 for (int i=tik_.beginRows(); i < tik_.endRows(); i++)
155 { cStep(i);}
156 // count the number of individuals in each class
158#ifdef STK_MIXTURE_VERY_VERBOSE
159 stk_cout << _T("IMixtureComposer::cStep() tk_ = ") << tk_;
160 stk_cout << _T("IMixtureComposer::cStep() done\n");
161#endif
162 return tk_.minElt();
163}
164
165/* simulate zi */
166/* compute tik, default implementation. */
168{
169#ifdef STK_MIXTURE_VERY_VERBOSE
170 stk_cout << _T("Entering IMixtureComposer::sStep()\n");
171#endif
172 // simulate zi
173 for (int i = zi_.begin(); i< zi_.end(); ++i) { sStep(i);}
174#ifdef STK_MIXTURE_VERY_VERBOSE
175 stk_cout << _T("IMixtureComposer::sStep() done\n");
176#endif
177 return cStep();
178}
179
181{
182#ifdef STK_MIXTURE_VERY_VERBOSE
183 stk_cout << _T("Entering IMixtureComposer::eStep()\n");
184#endif
185 Real sum = 0.;
186 int i;
187#ifdef _OPENMP
188#pragma omp parallel for reduction (+:sum)
189#endif
190 for (i = tik_.beginRows(); i < tik_.endRows(); ++i) { sum += eStep(i);}
191 // update ln-likelihood
193 // compute proportions
195#ifdef STK_MIXTURE_VERY_VERBOSE
196 stk_cout << _T("IMixtureComposer::eStep() lnLikelihood =") << sum << _T("\n");
197 stk_cout << _T("IMixtureComposer::eStep() done\n");
198 if (!isFinite(sum))
199 { stk_cout << _T("tik_ =\n") << tik_.transpose();}
200#endif
201 return tk_.minElt();
202}
203
204/* Compute Zi using the Map estimate, default implementation. */
206{
207 for (int i = zi_.begin(); i< zi_.end(); ++i)
208 { mapStep(i); }
209}
210
211/* Simulate zi accordingly to tik.
212 * @param i index of the the individual
213 **/
216/* Replace tik by zik
217 * @param i index of the the individual
218 **/
220{ tik_.row(i) = 0.; tik_.elt(i, zi_[i]) = 1.;}
221
222/* compute tik, default implementation. */
224{
225#ifdef _OPENMP
226 CPointX lnComp_(tik_.cols());
227#endif
228 // get maximal element of ln(x_i,\theta_k) + ln(p_k)
229 for (int k=tik_.beginCols(); k< tik_.endCols(); k++)
230 { lnComp_[k] = std::log(pk_[k])+lnComponentProbability(i,k);}
231 if (lnComp_.isInfinite().any())
232 {
233#ifdef STK_MIXTURE_VERY_VERBOSE
234 stk_cout << _T("IMixtureComposer::eStep(") << i << _T(")\n");
235 stk_cout << _T("pk_ =") << pk_;
236 stk_cout << _T("tk_ =") << tk_;
237 stk_cout << _T("lnComp_ =") << lnComp_;
238 for (int k=tik_.beginCols(); k< tik_.endCols(); k++)
239 {
241 stk_cout << _T("lnComponentProbability(") << i << _T(",")<< k << _T(")=") << val << _T("\n");
242 }
244 stk_cout << _T("tik_ =\n") << tik_.transpose();
245#endif
246 throw(Clust::eStepFail_);
247 }
248 int kmax;
250 // set zi_
251 zi_[i] = kmax;
252 // return max + sum_k p_k exp{lnCom_k - lnComp_kmax}
253 Real sum = (tik_.row(i) = (lnComp_ - max).exp()).sum();
254 tik_.row(i) /= sum;
255 return max + std::log( sum );
256}
257
258/* Compute Zi using the Map estimate, default implementation. */
260{
261 int k;
262 tik_.row(i).maxElt(k);
263 zi_[i] = k;
264}
265
266/* estimate the proportions and the parameters of the components of the
267 * model given the current tik/zi mixture parameters values.
268 **/
270{ pStep();
271 /* implement specific parameters estimation in concrete class. */
272}
273
274/* Compute prop using the ML estimate, default implementation. */
277
278/* @brief Finalize the estimation of the model.
279 * The default behavior is compute current lnLikelihood.
280 **/
286
287
288// protected methods----------------------
289/* Create the parameters of the mixture model. */
291{
292#ifdef STK_MIXTURE_VERBOSE
293 stk_cout << _T("Entering IMixtureComposer::initializeMixtureParameters\n");
294#endif
295 pk_ = 1./nbCluster_;
296 tik_ = 1./nbCluster_;
297 tk_ = sumByCol(tik_);
298}
299
300/* generate random tik_ */
302{
303 tk_ = 0.;
304 tik_.randUnif();
305 for (int i = tik_.beginRows(); i < tik_.endRows(); ++i)
306 {
307 // create a reference on the i-th row
308 CPointX tikRowi(tik_.row(i), true);
309 tikRowi = tikRowi * pk_;
310 tikRowi /= tikRowi.sum();
311 tk_ += tikRowi;
312 }
313 return tk_.minElt();
314}
315
316/* generate random tik_ */
318{
320 zi_.rand(law);
321 return cStep();
322}
323
324
325} // namespace STK
326
This file define methods for displaying Arrays and Expressions.
In this file we define the abstract base class for mixture models.
In this file we define the Categorical distribution.
This file contain the functors computings statistics.
#define stk_cout
Standard stk output stream.
#define _T(x)
Let x unmodified.
TransposeOperator< Derived > const transpose() const
Derived & randUnif()
set random values to this using a uniform law.
Derived & rand(Law::IUnivLaw< Type > const &law)
set random values to this using a distribution law given by the user.
Type const maxElt(int &row, int &col) const
Type const minElt(int &row, int &col) const
UnaryOperator< IsInfiniteOp< Type >, Derived > isInfinite() const
hidden::CSlice< Derived, 1, sizeCols_ >::Result row(int i) const
implement the row operator using a reference on the row of the allocator
Base class for Mixture (composed) model.
virtual ~IMixtureComposer()
destructor
virtual int cStep()
Replace tik by zik.
virtual void initializeStep()
Initialize the model before its first use.
void setState(Clust::modelState state)
set the state of the model : should be used by any strategy
void randomFuzzyInit()
Initialize randomly the posterior probabilities tik of the model, then compute the zi values with map...
virtual void pStep()
Compute proportions using the ML estimates, default implementation.
virtual Real eStep()
compute the zi, the lnLikelihood of the current estimates and the next value of the tik.
CPointX lnComp_
Auxiliary array used in the eStep.
virtual int randomZi()
generate random zi_
virtual void initializeMixtureParameters()
Create the mixture model parameters pk_ and tik_.
virtual void mapStep()
Compute zi using the Map estimate.
IMixtureComposer(int nbSample, int nbCluster)
Constructor.
Clust::modelState state() const
void randomClassInit()
Initialize randomly the labels zi of the model.
virtual int sStep()
Simulate zi accordingly to tik and replace tik by zik by calling cStep().
virtual int randomTik()
generate random tik_
virtual void paramUpdateStep()=0
Compute the proportions and the model parameters given the current tik mixture parameters.
virtual void finalizeStep()
Finalize the estimation of the model.
Interface base class for Mixture (composed) model.
CArrayXX tik_
The tik probabilities.
virtual void writeParameters(ostream &os) const
write the parameters of the model in the stream os.
virtual Real lnComponentProbability(int i, int k) const =0
CVectorXi zi_
The zi class label.
virtual void initializeStep()
Initialize the model before at its first use.
int computeNbFreeParameters() const
compute the number of free parameters of the model.
CPointX pk_
The proportions of each mixtures.
CPointX tk_
The sum of the columns of tik_.
int nbCluster_
number of cluster.
void setNbFreeParameter(int const &nbFreeParameter)
set the number of free parameters of the model
void setLnLikelihood(Real const &lnLikelihood)
set the log-likelihood of the model
Categorical probability law.
virtual int rand() const
The MultidimRegression class allows to regress a multidimensional output variable among a multivariat...
bool isFinite(Type const &x)
utility method allowing to know if a value is a finite value
Arrays::SumOp< Lhs, Rhs >::result_type sum(Lhs const &lhs, Rhs const &rhs)
convenience function for summing two arrays
@ modelInitialized_
the model is initialized and its parameters are initialized to default values
@ modelFinalized_
the model is finalized
@ modelParamInitialized_
The parameters of the model have been initialized.
double Real
STK fundamental type of Real values.
hidden::SliceVisitorSelector< Derived, hidden::MaxVisitor, Arrays::by_col_ >::type_result max(Derived const &A)
If A is a row-vector or a column-vector then the function will return the usual maximal value of the ...
hidden::FunctorTraits< Derived, SumOp >::Row sum(Derived const &A)
Compute the sum of A.
hidden::FunctorTraits< Derived, MeanOp >::Row meanByCol(Derived const &A)
hidden::FunctorTraits< Derived, SumOp >::Row sumByCol(Derived const &A)
The namespace STK is the main domain space of the Statistical ToolKit project.
hidden::SliceVisitorSelector< Derived, hidden::SumVisitor, Arrays::by_col_ >::type_result sumByCol(Derived const &A)