PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // GaussMix.h 00004 // 00005 // Copyright (C) 2004-2006 University of Montreal 00006 // 00007 // Redistribution and use in source and binary forms, with or without 00008 // modification, are permitted provided that the following conditions are met: 00009 // 00010 // 1. Redistributions of source code must retain the above copyright 00011 // notice, this list of conditions and the following disclaimer. 00012 // 00013 // 2. Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // 00017 // 3. The name of the authors may not be used to endorse or promote 00018 // products derived from this software without specific prior written 00019 // permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 // 00032 // This file is part of the PLearn library. For more information on the PLearn 00033 // library, go to the PLearn Web site at www.plearn.org 00034 00035 /* ******************************************************* 00036 * $Id: GaussMix.h 8215 2007-10-26 14:47:09Z tihocan $ 00037 ******************************************************* */ 00038 00040 #ifndef GaussMix_INC 00041 #define GaussMix_INC 00042 00043 #include "PDistribution.h" 00044 #include <plearn/misc/PTimer.h> 00045 00046 namespace PLearn { 00047 using namespace std; 00048 00049 class GaussMix: public PDistribution 00050 { 00051 00052 private: 00053 00054 typedef PDistribution inherited; 00055 00057 Vec log_likelihood_post, sample_row; 00058 00059 protected: 00060 00061 // TODO Document (H3^-1 as in my tex file, for each Gaussian) 00062 TVec<Mat> H3_inverse; 00063 00065 PP<PTimer> ptimer; 00066 00069 TMat<bool> missing_patterns; 00070 00072 TMat<bool> missing_template; 00073 00076 int current_cluster; 00077 00082 TVec<int> sample_to_path_index; 00083 00086 TVec< TVec<int> > spanning_path; 00087 00093 TVec< TVec<bool> > spanning_use_previous; 00094 00102 TVec< TVec<bool> > spanning_can_free; 00103 00106 Mat log_likelihood_post_clust; 00107 00109 TVec< TVec<int> > clusters_samp; 00110 00113 mutable TVec<Mat> cholesky_queue; 00114 00116 //observed part) 00117 mutable Vec log_det_queue; 00118 00120 TVec<VMat> imputed_missing; 00121 00123 //gaussian) 00124 TVec<Mat> clust_imputed_missing; 00125 00127 Vec sum_of_posteriors; 00128 00130 TVec<bool> no_missing_change; 00131 00132 // TODO Document 00133 // List of inverse matrices (H_3^-1). 00134 mutable TVec<Mat> cond_var_inv_queue; 00135 00142 mutable TVec< TVec<int> > indices_queue; 00143 00144 // TODO Document 00145 // Same but for inverse matrices (H_3^-1). 00146 mutable TVec< TVec<int> > indices_inv_queue; 00147 00150 int type_id; 00151 00153 // TODO There may be a need to declare them as learnt options if one wants 00154 // to continue the training of a saved GaussMix. 00155 Vec mean_training, stddev_training; 00156 00157 // TODO Document (to store the covariance of the error, that we need to add 00158 // when imputing missing values). 00159 TVec<Mat> error_covariance; 00160 00163 Mat posteriors; 00164 00167 Vec initial_weights; 00168 00172 Mat updated_weights; 00173 00174 TVec<Mat> eigenvectors_x; 00175 mutable Mat eigenvalues_x; 00176 TVec<Mat> y_x_mat; 00177 TVec<Mat> eigenvectors_y_x; 00178 mutable Mat eigenvalues_y_x; 00179 00181 mutable Mat center_y_x; 00182 00184 mutable Vec log_p_j_x; 00185 00188 mutable Vec p_j_x; 00189 00193 Vec log_coeff; 00194 00197 Vec log_coeff_x, log_coeff_y_x; 00198 00201 mutable TVec<Mat> joint_cov; 00202 00203 // TODO Document (inverse covariance of joint). 00204 mutable TVec<Mat> joint_inv_cov; 00205 00208 TVec<Mat> chol_joint_cov; 00209 00213 // TMat<Mat> chol_cov_template; 00214 // TODO Remove: not needed anymore. 00215 00218 TVec<int> stage_joint_cov_computed; 00219 00222 TVec<int> stage_replaced; 00223 00226 TVec<int> sample_to_template; 00227 00229 int current_training_sample; 00230 00237 int previous_training_sample; 00238 00241 mutable bool previous_predictor_part_had_missing; 00242 00244 mutable Vec y_centered; 00245 00248 Mat covariance; 00249 00251 mutable Vec log_likelihood_dens; 00252 00253 // TODO Document (i-th element = if missing pattern has changed). 00254 // (note: only used when efficient_missing == 2) 00255 TVec<bool> need_recompute; 00256 00257 // TODO Document (maps a sample in the original training set to its index 00258 // in the reordered train set). 00259 TVec<int> original_to_reordered; 00260 00261 // ********************* 00262 // * protected options * 00263 // ********************* 00264 00265 int D; 00266 Mat diags; 00267 Mat eigenvalues; 00268 TVec<Mat> eigenvectors; 00269 int n_eigen_computed; 00270 int nsamples; 00271 00272 public: 00273 00274 // ************************ 00275 // * public build options * 00276 // ************************ 00277 00278 real alpha_min; 00279 int efficient_k_median; 00280 int efficient_k_median_iter; 00281 int efficient_missing; 00282 real epsilon; 00283 real f_eigen; 00284 bool impute_missing; 00285 int kmeans_iterations; 00286 int L; 00287 int max_samples_in_cluster; 00288 int min_samples_in_cluster; 00289 int n_eigen; 00290 real sigma_min; 00291 string type; 00292 00293 // The following options are actually learnt options (since they are learnt 00294 // during training), but are public so that one may easily define a given 00295 // mixture of Gaussians. 00296 Vec alpha; 00297 Mat center; 00298 Vec sigma; 00299 00300 // **************** 00301 // * Constructors * 00302 // **************** 00303 00305 GaussMix(); 00306 00307 // ****************** 00308 // * Object methods * 00309 // ****************** 00310 00312 virtual void changeOptions(const map<string,string>& name_value); 00313 00314 protected: 00315 00316 // ******************** 00317 // * GaussMix methods * 00318 // ******************** 00319 00323 void generateFromGaussian(Vec& s, int given_gaussian) const; 00324 00327 virtual bool setPredictorPredictedSizes(int the_predictor_size, 00328 int the_predicted_size, 00329 bool call_parent = true); 00330 00331 00336 void setPredictorPredictedSizes_const() const; 00337 00340 void getInitialWeightsFrom(const VMat& vmat); 00341 00343 virtual void computeMeansAndCovariances(); 00344 00348 virtual void computePosteriors(); 00349 00352 void computeAllLogLikelihoods(const Vec& sample, const Vec& log_like); 00353 00358 real computeLogLikelihood(const Vec& y, int j, bool is_predictor = false) 00359 const; 00360 00367 real precomputeGaussianLogCoefficient(const Vec& eigenvals, int dimension) 00368 const; 00369 00373 void precomputeAllGaussianLogCoefficients(); 00374 00376 void resizeDataBeforeTraining(); 00377 00380 void resizeDataBeforeUsing(); 00381 00387 bool computeMixtureWeights(bool allow_replace = true); 00388 00395 void replaceGaussian(int j); 00396 00400 void updateSampleWeights(); 00401 00402 private: 00403 00405 void build_(); 00406 00407 protected: 00408 00410 static void declareOptions(OptionList& ol); 00411 00413 void kmeans(const VMat& samples, int nclust, TVec<int>& clust_idx, 00414 Mat& clust, int maxit=9999); 00415 00425 void updateCholeskyFromPrevious( 00426 const Mat& chol_previous, Mat& chol_updated, 00427 const Mat& full_matrix, 00428 const TVec<int>& indices_previous, const TVec<int>& indices_updated) 00429 const; 00430 00431 // TODO DOCUMENT 00432 // (use the inverse variance lemma to update the inverse covariance matrix) 00433 // (may also update the determinant of the corresponding covariance matrix) 00434 void updateInverseVarianceFromPrevious( 00435 const Mat& src, Mat& dst, const Mat& full, 00436 const TVec<int>& ind_src, const TVec<int>& ind_dst, 00437 real* src_log_det = 0, real* dst_log_det = 0) const; 00438 00439 // TODO DOCUMENT!!! 00440 void addToCovariance(const Vec& y, int j, const Mat& cov, real post); 00441 00443 virtual void unknownOutput(char def, const Vec& input, Vec& output, int& k) const; 00444 00445 public: 00446 00448 virtual void forget(); 00449 00450 // Simply calls inherited::build() then build_(). 00451 virtual void build(); 00452 00454 virtual void makeDeepCopyFromShallowCopy(CopiesMap& copies); 00455 00457 PLEARN_DECLARE_OBJECT(GaussMix); 00458 00459 // ******************** 00460 // * PLearner methods * 00461 // ******************** 00462 00464 virtual void train(); 00465 00467 virtual int outputsize() const; 00468 00470 virtual TVec<string> getTrainCostNames() const; 00471 00473 virtual void setTrainingSet(VMat training_set, bool call_forget=true); 00474 00475 // ************************* 00476 // * PDistribution methods * 00477 // ************************* 00478 00480 virtual void setPredictor(const Vec& predictor, bool call_parent = true) 00481 const; 00482 00484 virtual real log_density(const Vec& y) const; 00485 00487 virtual real survival_fn(const Vec& y) const; 00488 00490 virtual real cdf(const Vec& y) const; 00491 00493 virtual void expectation(Vec& mu) const; 00494 00497 virtual void missingExpectation(const Vec& input, Vec& mu); 00498 00500 virtual void variance(Mat& cov) const; 00501 00503 virtual void generate(Vec& s) const; 00504 00505 /* 00507 int getNEigenComputed() const; 00508 Mat getEigenvectors(int j) const; 00509 Vec getEigenvals(int j) const; 00510 Vec getLogLikelihoodDens() const { return log_likelihood_dens; } 00511 */ 00512 00513 /*********** Static members ************/ 00514 00515 protected: 00516 00522 static void traverse_tree(TVec<int>& path, 00523 TVec<bool>& span_can_free, 00524 TVec<bool>& span_use_previous, 00525 bool free_previous, 00526 bool use_previous, 00527 int index_node, int previous_node, 00528 const TVec<int>& parent, 00529 const TVec< TVec<int> >& children, 00530 const TVec<int>& message_up, 00531 const TVec<int>& message_down); 00532 00533 }; 00534 00535 // Declares a few other classes and functions related to this class 00536 DECLARE_OBJECT_PTR(GaussMix); 00537 00538 } // end of namespace PLearn 00539 00540 #endif 00541 00542 00543 /* 00544 Local Variables: 00545 mode:c++ 00546 c-basic-offset:4 00547 c-file-style:"stroustrup" 00548 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00549 indent-tabs-mode:nil 00550 fill-column:79 00551 End: 00552 */ 00553 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :