ECOCPAK v0.9
fn_one_vs_one.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 
00049 u32
00050 one_vs_one
00051   (
00052   const mat& training_samples,
00053   const icolvec& training_labels,
00054   const mat& testing_samples,
00055   const icolvec& testing_labels,
00056   const int decoding_strategy,
00057   const int classifiers_type,
00058   const bool verbose,
00059   ofstream& verbose_output,
00060   double& execution_time
00061   )
00062   {
00063   // timer object to count execution times
00064   wall_clock timer;
00065 
00066   // start timer
00067   timer.tic();
00068 
00069   // number of training samples
00070   const u32 n_training_samples = training_samples.n_rows;
00071 
00072   // number of samples attributes
00073   const u32 n_attributes = training_samples.n_cols;
00074 
00075   // number of testing samples
00076   const u32 n_testing_samples = testing_samples.n_rows;
00077 
00078   // variable to hold the number of classes
00079   u32 n_classes = 0;
00080 
00081   // vector to hold number of samples per class
00082   ucolvec n_samples_per_class;
00083 
00084   // adjust the training samples class labels to start from one
00085   // and count number of classes
00086   const ucolvec tmp_training_labels = process_labels
00087                                         (
00088                                         training_labels,
00089                                         n_classes
00090                                         );
00091 
00092   // adjust the testing samples class labels to start from one
00093   const ucolvec tmp_testing_labels = process_labels(testing_labels);
00094 
00095   // decompose the training samples matrix into ClassData object
00096   vector<ClassData> classes_vector =
00097     create_class_vector
00098       (
00099       training_samples,
00100       conv_to<icolvec>::from(tmp_training_labels)
00101       );
00102 
00103   // declare empty classifiers vector
00104   // vector<Classifier*> classifiers_vector;
00105 
00106   // allocate error correcting output codes matrix
00107   imat coding_matrix = zeros<imat>
00108                          (
00109                          n_classes,
00110                          (n_classes * (n_classes - 1)) / 2
00111                          );
00112 
00113   // classifiers vector
00114   vector<Classifier*> classifiers_vector;
00115 
00116   // ================================================================ //
00117   // ||                        Training Step                       || //
00118   // ================================================================ //
00119 
00120     // auxuliary column counter
00121     u32 k = 0;
00122 
00123     // start training of (K * (K - 1) / 2) classifiers, where K = number
00124     // of classes
00125     for(u32 i = 0; i < n_classes; i++)
00126       {
00127       for(u32 j = i+1; j < n_classes; j++)
00128         {
00129         switch(classifiers_type)
00130           {
00131           // Nearest Class Centroid Classifier
00132           case NCC:
00133             {
00134             Classifier_ncc* tmp = new Classifier_ncc
00135                                         (
00136                                         classes_vector[i].Data(),
00137                                         classes_vector[j].Data()
00138                                         );
00139 
00140             // update classifier's class objects
00141             tmp->pos.push_back(&(classes_vector[i]));
00142             tmp->neg.push_back(&(classes_vector[j]));
00143 
00144             // update classifier's number of possitive and negative
00145             // samples
00146             tmp->n_pos = classes_vector[i].Samples();
00147             tmp->n_neg = classes_vector[j].Samples();
00148 
00149             // store classifier
00150             classifiers_vector.push_back(tmp);
00151 
00152             break;
00153             }
00154 
00155           // Fisher Linear Discriminant followed by NCC
00156           case FLDA:
00157             {
00158             Classifier_flda* tmp = new Classifier_flda
00159                                         (
00160                                         classes_vector[i].Data(),
00161                                         classes_vector[j].Data()
00162                                         );
00163 
00164             // update classifier's class objects
00165             tmp->pos.push_back(&(classes_vector[i]));
00166             tmp->neg.push_back(&(classes_vector[j]));
00167 
00168             // update classifier's number of possitive and negative
00169             // samples
00170             tmp->n_pos = classes_vector[i].Samples();
00171             tmp->n_neg = classes_vector[j].Samples();
00172 
00173             // store classifier
00174             classifiers_vector.push_back(tmp);
00175 
00176             break;
00177             }
00178 
00179           // Support Vector Machine Classifier
00180           case SVM:
00181             {
00182             Classifier_svm* tmp = new Classifier_svm
00183                                         (
00184                                         classes_vector[i].Data(),
00185                                         classes_vector[j].Data()
00186                                         );
00187 
00188             // update classifier's class objects
00189             tmp->pos.push_back(&(classes_vector[i]));
00190             tmp->neg.push_back(&(classes_vector[j]));
00191 
00192             // update classifier's number of possitive and negative
00193             // samples
00194             tmp->n_pos = classes_vector[i].Samples();
00195             tmp->n_neg = classes_vector[j].Samples();
00196 
00197             // store classifier
00198             classifiers_vector.push_back(tmp);
00199 
00200             break;
00201             }
00202 
00203           // AdaBoost Classifier
00204           case ADABOOST:
00205             {
00206             Classifier_adaBoost* tmp = new Classifier_adaBoost
00207                                              (
00208                                              classes_vector[i].Data(),
00209                                              classes_vector[j].Data()
00210                                              );
00211 
00212             // update classifier's class objects
00213             tmp->pos.push_back(&(classes_vector[i]));
00214             tmp->neg.push_back(&(classes_vector[j]));
00215 
00216             // update classifier's number of possitive and negative
00217             // samples
00218             tmp->n_pos = classes_vector[i].Samples();
00219             tmp->n_neg = classes_vector[j].Samples();
00220 
00221             // store classifier
00222             classifiers_vector.push_back(tmp);
00223 
00224             break;
00225             }
00226 
00227           // Sum of Error Squares Classifier
00228           case LEAST_SQUARES:
00229             {
00230             Classifier_ls* tmp = new Classifier_ls
00231                                        (
00232                                         classes_vector[i].Data(),
00233                                         classes_vector[j].Data()
00234                                        );
00235 
00236             // update classifier's class objects
00237             tmp->pos.push_back(&(classes_vector[i]));
00238             tmp->neg.push_back(&(classes_vector[j]));
00239 
00240             // update classifier's number of possitive and negative
00241             // samples
00242             tmp->n_pos = classes_vector[i].Samples();
00243             tmp->n_neg = classes_vector[j].Samples();
00244 
00245             // store classifier
00246             classifiers_vector.push_back(tmp);
00247 
00248             break;
00249             }
00250 
00251           // Custom Classifier
00252           case CUSTOM_CLASSIFIER:
00253             {
00254             Classifier_custom* tmp = new Classifier_custom
00255                                            (
00256                                            classes_vector[i].Data(),
00257                                            classes_vector[j].Data()
00258                                            );
00259 
00260             // update classifier's class objects
00261             tmp->pos.push_back(&(classes_vector[i]));
00262             tmp->neg.push_back(&(classes_vector[j]));
00263 
00264             // update classifier's number of possitive and negative
00265             // samples
00266             tmp->n_pos = classes_vector[i].Samples();
00267             tmp->n_neg = classes_vector[j].Samples();
00268 
00269             // store classifier
00270             classifiers_vector.push_back(tmp);
00271 
00272             break;
00273             }
00274 
00275           default:
00276             {
00277             arma_debug_print("one_vs_one(): Unknown classifier's option");
00278             }
00279 
00280           }
00281 
00282         // update ECOC matrix in order to create 1 vs 1 configuration
00283         coding_matrix(i, k) =   1;
00284         coding_matrix(j, k) =  -1;
00285 
00286         // increase ECOC matrix column counter
00287         k++;
00288         }
00289 
00290       }
00291 
00292   // ================================================================ //
00293   // ||                        Testing Step                        || //
00294   // ================================================================ //
00295 
00296     // classification error
00297     double error = 0.0;
00298 
00299     // predictions for each sample
00300     uvec predictions;
00301 
00302     // confussion matrix
00303     umat confussion;
00304 
00305     // number of misclassified samples
00306     u32 n_missed = 0;
00307 
00308     // used to hold the number of missclassified testing samples
00309     decode
00310       (
00311       testing_samples,
00312       tmp_testing_labels,
00313       coding_matrix,
00314       classifiers_vector,
00315       classes_vector,
00316       decoding_strategy,
00317       predictions,
00318       n_missed,
00319       error,
00320       confussion
00321       );
00322 
00323   // if verbose output is activated
00324   if(verbose == true)
00325     {
00326     verbose_output << "* Predictions vs Labels: "
00327                    << endl
00328                    << join_rows(predictions, tmp_testing_labels)
00329                    << endl << endl;
00330     verbose_output << "* Coding Matrix: " << endl << coding_matrix << endl << endl;
00331     verbose_output << "* Confusion Matrix: " << endl << confussion << endl;
00332     }
00333 
00334   // clean up classifiers vector
00335   for(u32 i = 0; i < classifiers_vector.size(); i++)
00336     {
00337     delete classifiers_vector[i];
00338     }
00339 
00340   // stop timer
00341   execution_time = timer.toc();
00342 
00343   // reset class counter
00344   ClassData::globalIndex = 0;
00345 
00346   // return number of misclassified samples
00347   return n_missed;
00348   }
00349 
00350 
00351 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerator Defines