ECOCPAK v0.9
fn_one_vs_all.hpp
Go to the documentation of this file.
00001 // Copyright (C) 2011 the authors listed below
00002 // http://ecocpak.sourceforge.net
00003 //
00004 // Authors:
00005 // - Dimitrios Bouzas (bouzas at ieee dot org)
00006 // - Nikolaos Arvanitopoulos (niarvani at ieee dot org)
00007 // - Anastasios Tefas (tefas at aiia dot csd dot auth dot gr)
00008 //
00009 // This file is part of the ECOC PAK C++ library. It is
00010 // provided without any warranty of fitness for any purpose.
00011 //
00012 // You can redistribute this file and/or modify it under
00013 // the terms of the GNU Lesser General Public License (LGPL)
00014 // as published by the Free Software Foundation, either
00015 // version 3 of the License or (at your option) any later
00016 // version.
00017 // (see http://www.opensource.org/licenses for more info)
00018 
00019 
00022 
00023 
00024 
00050 u32
00051 one_vs_all
00052   (
00053   const mat& training_samples,
00054   const icolvec& training_labels,
00055   const mat& testing_samples,
00056   const icolvec& testing_labels,
00057   const int decoding_strategy,
00058   const int classifiers_type,
00059   const bool verbose,
00060   ofstream& verbose_output,
00061   double& execution_time
00062   )
00063   {
00064   // timer object to count execution times
00065   wall_clock timer;
00066 
00067   // start timer
00068   timer.tic();
00069 
00070   // number of training samples
00071   const u32 n_training_samples = training_samples.n_rows;
00072 
00073   // number of samples attributes
00074   const u32 n_attributes = training_samples.n_cols;
00075 
00076   // number of testing samples
00077   const u32 n_testing_samples = testing_samples.n_rows;
00078 
00079   // variable to hold the number of classes
00080   u32 n_classes = 0;
00081 
00082   // adjust the training samples class labels to start from one
00083   // and count number of classes
00084   const ucolvec tmp_training_labels = process_labels
00085                                         (
00086                                         training_labels,
00087                                         n_classes
00088                                         );
00089 
00090   // adjust the testing samples class labels to start from one
00091   const ucolvec tmp_testing_labels = process_labels
00092                                        (
00093                                        testing_labels
00094                                        );
00095 
00096   // decompose the training samples matrix into ClassData object
00097   vector<ClassData> classes_vector =
00098   create_class_vector
00099     (
00100     training_samples,
00101     conv_to<icolvec>::from(tmp_training_labels)
00102     );
00103 
00104   // allocate error correcting output codes matrix
00105   imat coding_matrix = -ones<imat>(n_classes, n_classes);
00106 
00107   // classifiers vector
00108   vector<Classifier*> classifiers_vector;
00109 
00110   // ================================================================ //
00111   // ||                        Training Step                       || //
00112   // ================================================================ //
00113 
00114     // auxuliary column counter
00115     u32 k = 0;
00116 
00117     // iterate through number of classes
00118     for(u32 i = 0; i < n_classes; i++)
00119       {
00120       // negative classes data matrix
00121       mat X_neg;
00122 
00123       // negative classes vector
00124       vector<ClassData*> neg_classes;
00125 
00126       // number of negative examples
00127       u32 n_neg = 0;
00128 
00129       // iterate through classes to construct X_neg
00130       for(u32 j = 0; j < n_classes; j++)
00131         {
00132         // if class is considered negative
00133         if(j != i)
00134           {
00135           // append samples of current class to the of X_neg
00136           X_neg = join_cols(X_neg, classes_vector[j].Data());
00137 
00138           // store pointer to current class to temporary vector
00139           neg_classes.push_back(&(classes_vector[j]));
00140 
00141           // increase negative samples temporary counter
00142           n_neg += classes_vector[j].Samples();
00143           }
00144 
00145         }
00146 
00147       // create and store specific classifier
00148       switch(classifiers_type)
00149         {
00150         // Nearest Class Centroid Classifier
00151         case NCC:
00152           {
00153           Classifier_ncc* tmp = new Classifier_ncc
00154                                       (
00155                                       classes_vector[i].Data(),
00156                                       X_neg
00157                                       );
00158 
00159           // update classifier's possitive class pointer
00160           tmp->pos.push_back(&(classes_vector[i]));
00161 
00162           // update classifier's negative classes
00163           tmp->neg = neg_classes;
00164 
00165           // update classifier's number of possitive samples
00166           tmp->n_pos = classes_vector[i].Samples();
00167 
00168           // update classifier's number of negative samples
00169           tmp->n_neg = n_neg;
00170 
00171           // store classifier
00172           classifiers_vector.push_back(tmp);
00173 
00174           break;
00175           }
00176 
00177         // Fisher Linear Discriminant followed by NCC
00178         case FLDA:
00179           {
00180           Classifier_flda* tmp = new Classifier_flda
00181                                        (
00182                                        classes_vector[i].Data(),
00183                                        X_neg
00184                                        );
00185 
00186           // update classifier's possitive class pointer
00187           tmp->pos.push_back(&(classes_vector[i]));
00188 
00189           // update classifier's negative classes
00190           tmp->neg = neg_classes;
00191 
00192           // update classifier's number of possitive samples
00193           tmp->n_pos = classes_vector[i].Samples();
00194 
00195           // update classifier's number of negative samples
00196           tmp->n_neg = n_neg;
00197 
00198           // store classifier
00199           classifiers_vector.push_back(tmp);
00200 
00201           break;
00202           }
00203 
00204         // Support Vector Machine Classifier
00205         case SVM:
00206           {
00207           Classifier_svm* tmp = new Classifier_svm
00208                                       (
00209                                       classes_vector[i].Data(),
00210                                       X_neg
00211                                       );
00212 
00213           // update classifier's possitive class pointer
00214           tmp->pos.push_back(&(classes_vector[i]));
00215 
00216           // update classifier's negative classes
00217           tmp->neg = neg_classes;
00218 
00219           // update classifier's number of possitive samples
00220           tmp->n_pos = classes_vector[i].Samples();
00221 
00222           // update classifier's number of negative samples
00223           tmp->n_neg = n_neg;
00224 
00225           // store classifier
00226           classifiers_vector.push_back(tmp);
00227 
00228           break;
00229           }
00230 
00231         // AdaBoost Classifier
00232         case ADABOOST:
00233           {
00234           Classifier_adaBoost* tmp = new Classifier_adaBoost
00235                                            (
00236                                            classes_vector[i].Data(),
00237                                            X_neg
00238                                            );
00239 
00240           // update classifier's possitive class pointer
00241           tmp->pos.push_back(&(classes_vector[i]));
00242 
00243           // update classifier's negative classes
00244           tmp->neg = neg_classes;
00245 
00246           // update classifier's number of possitive samples
00247           tmp->n_pos = classes_vector[i].Samples();
00248 
00249           // update classifier's number of negative samples
00250           tmp->n_neg = n_neg;
00251 
00252           // store classifier
00253           classifiers_vector.push_back(tmp);
00254 
00255           break;
00256           }
00257 
00258         // Sum of Error Squares Classifier
00259         case LEAST_SQUARES:
00260           {
00261           Classifier_ls* tmp = new Classifier_ls
00262                                      (
00263                                      classes_vector[i].Data(),
00264                                      X_neg
00265                                      );
00266 
00267           // update classifier's possitive class pointer
00268           tmp->pos.push_back(&(classes_vector[i]));
00269 
00270           // update classifier's negative classes
00271           tmp->neg = neg_classes;
00272 
00273           // update classifier's number of possitive samples
00274           tmp->n_pos = classes_vector[i].Samples();
00275 
00276           // update classifier's number of negative samples
00277           tmp->n_neg = n_neg;
00278 
00279           // store classifier
00280           classifiers_vector.push_back(tmp);
00281 
00282           break;
00283           }
00284 
00285         // Custom Classifier
00286         case CUSTOM_CLASSIFIER:
00287           {
00288           Classifier_custom* tmp = new Classifier_custom
00289                                          (
00290                                          classes_vector[i].Data(),
00291                                          X_neg
00292                                          );
00293 
00294            // update classifier's possitive class pointer
00295           tmp->pos.push_back(&(classes_vector[i]));
00296 
00297           // update classifier's negative classes
00298           tmp->neg = neg_classes;
00299 
00300           // update classifier's number of possitive samples
00301           tmp->n_pos = classes_vector[i].Samples();
00302 
00303           // update classifier's number of negative samples
00304           tmp->n_neg = n_neg;
00305 
00306           // store classifier
00307           classifiers_vector.push_back(tmp);
00308 
00309           break;
00310           }
00311 
00312         default:
00313           {
00314           arma_debug_print("one_vs_all(): Unknown classifier's option");
00315           }
00316 
00317         }
00318 
00319       // update ECOC matrix in order to create 1 vs all configuration
00320       coding_matrix(i, k) = 1;
00321 
00322       // increase ECOC matrix column counter
00323       k++;
00324       }
00325 
00326   // ================================================================ //
00327   // ||                        Testing Step                        || //
00328   // ================================================================ //
00329 
00330     // classification error
00331     double error = 0.0;
00332 
00333     // predictions for each sample
00334     uvec predictions;
00335 
00336     // confussion matrix
00337     umat confussion;
00338 
00339     // number of misclassified samples
00340     u32 n_missed = 0;
00341 
00342     // used to hold the number of missclassified testing samples
00343     decode
00344       (
00345       testing_samples,
00346       tmp_testing_labels,
00347       coding_matrix,
00348       classifiers_vector,
00349       classes_vector,
00350       decoding_strategy,
00351       predictions,
00352       n_missed,
00353       error,
00354       confussion
00355       );
00356 
00357   // if verbose output is activated
00358   if(verbose == true)
00359     {
00360     predictions = join_rows(predictions, tmp_testing_labels);
00361     verbose_output << "* Predictions vs Labels: " << endl << predictions << endl << endl;
00362     verbose_output << "* Coding Matrix: " << endl << coding_matrix << endl << endl;
00363     verbose_output << "* Confusion Matrix: " << endl << confussion << endl;
00364     }
00365 
00366   // clean up classifiers vector
00367   for(u32 i = 0; i < classifiers_vector.size(); i++)
00368     {
00369     delete classifiers_vector[i];
00370     }
00371 
00372   // stop timer
00373   execution_time = timer.toc();
00374 
00375   // reset class counter
00376   ClassData::globalIndex = 0;
00377 
00378   // return number of misclassified samples
00379   return n_missed;
00380   }
00381 
00382 
00383 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerator Defines