ECOCPAK v0.9
|
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 #ifndef _CLASSIFIER_CUSTOM_H_ 00025 #define _CLASSIFIER_CUSTOM_H_ 00026 00027 00028 00029 #include "Classifier.hpp" 00030 00031 00032 00038 class Classifier_custom : public Classifier 00039 { 00040 public: 00041 00042 // ---------------------------------------------------------------- // 00043 // ------------------------ Constructors -------------------------- // 00044 // ---------------------------------------------------------------- // 00045 00046 // Copy ctor 00047 Classifier_custom 00048 ( 00049 const Classifier_custom& c 00050 ); 00051 00052 // User defined ctor custom classifier -- Overloaded 00053 Classifier_custom 00054 ( 00055 const mat& A, 00056 const mat& B 00057 ); 00058 00059 // ---------------------------------------------------------------- // 00060 // ---------------------- Member Functions ------------------------ // 00061 // ---------------------------------------------------------------- // 00062 00063 // return prediction value of classifier for input feature vector 00064 double predict(const rowvec& t) const; 00065 00066 00067 // ---------------------------------------------------------------- // 00068 // --------------------- Overloaded Operators --------------------- // 00069 // ---------------------------------------------------------------- // 00070 00071 // ---------------------------------------------------------------- // 00072 // -------------------------- Attributes -------------------------- // 00073 // ---------------------------------------------------------------- // 00074 00075 // ================================================================ // 00076 // || INFO: Below you must add the necessary attributes of your || // 00077 // || custom binary classifier. These attributes must be || // 00078 // || set in the user defined constructor of your || // 00079 // || classifier i.e., || // 00080 // || "Classifier_custom(const mat& A, const mat& B)" || // 00081 // || and then to be used in the "predict(const rowvec& t)"|| // 00082 // || in order for your classifier to be capable to assign || // 00083 // || a test feature vector. || // 00084 // ================================================================ // 00085 00086 // ================================================================ // 00087 // || START YOUR CODE HERE || // 00088 // ================================================================ // 00089 00090 00091 00092 // ================================================================ // 00093 // || END YOUR CODE HERE || // 00094 // ================================================================ // 00095 }; 00096 00097 00098 00106 Classifier_custom::Classifier_custom 00107 ( 00108 const Classifier_custom& c 00109 ) 00110 { 00111 // ================================================================== // 00112 // || INFO: Here you can intergrade a custom classifier in the || // 00113 // || ECOCPAK. || // 00114 // || || // 00115 // || Here you must add the necessary statements in order to || // 00116 // || construct a valuable copy constructor for you custom || // 00117 // || classifier objects. Due to the fact that classifier || // 00118 // || objects are stored in standard vectors a copy || // 00119 // || constructor is necessary in order for your custom || // 00120 // || classifier attributes to be copied once your custom || // 00121 // || classifier objects are inserted in a standard vector. || // 00122 // || || // 00123 // || Example: Let's say that you have defined that your || // 00124 // || custom classifier will have an array of type || // 00125 // || double* as an attribute named "array". Let's || // 00126 // || say also that you have defined another || // 00127 // || attribute of type "unsigned int" that denotes || // 00128 // || the previous array's size i.e., L. Then in || // 00129 // || your copy constructor below you must add the || // 00130 // || following piece of code: || // 00131 // || || // 00132 // || memcpy(array, c.array, L * sizeof(double)); || // 00133 // || L = c.L; || // 00134 // || || // 00135 // || Note however, that the above piece of code is || // 00136 // || valid if your classifier's attributes are of || // 00137 // || type public, otherwise you must add the proper|| // 00138 // || accessor and mutator methods. || // 00139 // ================================================================== // 00140 00141 // ================================================================== // 00142 // || START YOUR CODE HERE || // 00143 // ================================================================== // 00144 00145 00146 00147 // ================================================================== // 00148 // || END YOUR CODE HERE || // 00149 // ================================================================== // 00150 00151 // update the plus and minus classes (!DO NOT ALTER!) 00152 pos = c.pos; 00153 neg = c.neg; 00154 00155 // update the number of negative and positive samples (!DO NOT ALTER!) 00156 n_pos = c.n_pos; 00157 n_neg = c.n_neg; 00158 00159 // update the classifier's training error 00160 training_error = c.training_error; 00161 } 00162 00163 00164 00173 Classifier_custom::Classifier_custom 00174 ( 00175 const mat& A, 00176 const mat& B 00177 ) 00178 { 00179 // ================================================================== // 00180 // || INFO: Here you can intergrade a custom classifier in the || // 00181 // || ECOCPAK. || // 00182 // || || // 00183 // || This is the main constructor of your binary classifier || // 00184 // || objects. || // 00185 // || || // 00186 // || This constructor takes as inputs two 2D Armadillo || // 00187 // || matrices that their rows represent the feature vectors || // 00188 // || for each class of the binary problem. || // 00189 // || || // 00190 // || If your classifier routine uses as inputs raw C++ || // 00191 // || arrays of type "double" you can take advantage of the || // 00192 // || fact that 2D Armadillo matrix core is also stored as an|| // 00193 // || 1D array of type "double" and can be accessed via the || // 00194 // || "memptr()" member function as shown below: || // 00195 // || || // 00196 // || double* A_mem = A.memptr(); || // 00197 // || double* B_mem = B.memptr(); || // 00198 // || || // 00199 // || You can also get either the number of rows or the || // 00200 // || number of columns of the Armadillo 2D matrices using || // 00201 // || the following statements below: || // 00202 // || || // 00203 // || const unsigned int n_rowsA = A.n_rows; || // 00204 // || const unsigned int n_colsA = A.n_cols; || // 00205 // || || // 00206 // || const unsigned int n_rowsB = B.n_rows; || // 00207 // || const unsigned int n_colsB = B.n_cols; || // 00208 // || || // 00209 // || Where "n_rowsA" is the number of matrix A rows, || // 00210 // || "n_colsA" the number of matrix A columns, "n_rowsB" is || // 00211 // || the number of matrix B rows and "n_colsB" is the || // 00212 // || number of matrix B columns. || // 00213 // || || // 00214 // || Note however, that Armadillo 2D matrices are stored in || // 00215 // || memory in a columnwise manner. e.g., if we have the || // 00216 // || following (2 x 3) sized 2D matrix: || // 00217 // || || // 00218 // || 2 1 3 || // 00219 // || 3 4 5 || // 00220 // || || // 00221 // || it is stored in memory as: || // 00222 // || || // 00223 // || {2, 3, 1, 4, 3, 5} || // 00224 // ||==============================================================|| // 00225 00226 // ========== UNCOMMENT PIECE OF CODE IF NECESSARY ========== // 00227 // || Number of first class feature vectors || // 00228 // ========================================================== // 00229 00230 // %% UNCOMMENT BEGINNING %% 00231 // const unisigned int n_samplesA = A.n_rows; 00232 // %% UNCOMMENT END %% 00233 00234 // ========== UNCOMMENT PIECE OF CODE IF NECESSARY ========== // 00235 // || Number of second class feature vectors || // 00236 // ========================================================== // 00237 00238 // %% UNCOMMENT BEGINNING %% 00239 // const unsinged int n_samplesB = B.n_rows; 00240 // %% UNCOMMENT END %% 00241 00242 // ========== UNCOMMENT PIECE OF CODE IF NECESSARY ========== // 00243 // || Number of first class feature vectors attributes || // 00244 // ========================================================== // 00245 00246 // %% UNCOMMENT BEGINNING %% 00247 // const unsigned int n_attributesA = A.n_cols; 00248 // %% UNCOMMENT END %% 00249 00250 // ========== UNCOMMENT PIECE OF CODE IF NECESSARY ========== // 00251 // || Number of second class feature vectors attributes || // 00252 // ========================================================== // 00253 00254 // %% UNCOMMENT BEGINNING %% 00255 // const unsigned int n_attributesB = B.n_cols; 00256 // %% UNCOMMENT END %% 00257 00258 00259 // ================================================================== // 00260 // || INFO: If you want to use the raw C++ pointer to 1D arrays of || // 00261 // || type "double*" or "unsigned int*" you have to uncomment|| // 00262 // || the pieces of code below. Note however, that Armadillo || // 00263 // || 2D matrices are stored in memory in a columnwise || // 00264 // || manner. || // 00265 // || || // 00266 // || - The memptr() member function is used to obtain a || // 00267 // || raw pointer to the memory used for storing || // 00268 // || elements. || // 00269 // || || // 00270 // || - As soon as the size of the matrix/vector is || // 00271 // || changed, the pointer is no longer valid. || // 00272 // || || // 00273 // || - Data for matrices is stored in a column-by-column || // 00274 // || order. || // 00275 // ================================================================== // 00276 00277 // ========== UNCOMMENT PIECE OF CODE IF NECESSARY ========== // 00278 // || Raw pointer to first class 2D matrix || // 00279 // ========================================================== // 00280 00281 // %% UNCOMMENT BEGINNING %% 00282 // double* A_mem = A.memptr(); 00283 // %% UNCOMMENT END %% 00284 00285 // ========== UNCOMMENT PIECE OF CODE IF NECESSARY ========== // 00286 // || Raw pointer to first class 2D matrix || // 00287 // ========================================================== // 00288 00289 // %% UNCOMMENT BEGINNING %% 00290 // double* B_mem = B.memptr(); 00291 // %% UNCOMMENT END %% 00292 00293 00294 // ================================================================== // 00295 // || START YOUR CODE HERE || // 00296 // ================================================================== // 00297 00298 00299 // ================================================================== // 00300 // || END YOUR CODE HERE || // 00301 // ================================================================== // 00302 } 00303 00304 00305 00318 inline 00319 double 00320 Classifier_custom::predict(const rowvec& t) const 00321 { 00322 // ================================================================== // 00323 // || INFO: Here you can intergrade a custom classifier in the || // 00324 // || ECOCPAK. || // 00325 // || || // 00326 // || This is the member function of your binary classifier || // 00327 // || objects that is used in order for you classifiers to be|| // 00328 // || capable of returning their predictions values || // 00329 // || concerning a test feature vector. || // 00330 // || || // 00331 // || This member function takes as input an Armadillo row || // 00332 // || vector object that represents the input test feature || // 00333 // || that is to be tested by your binary classifier object. || // 00334 // || || // 00335 // || If your classifier routine uses as inputs raw C++ || // 00336 // || arrays of type "double" you can take advantage of the || // 00337 // || fact that 1D Armadillo vector core is also stored as an|| // 00338 // || 1D array of type "double" and can be accessed via the || // 00339 // || "memptr()" member function as shown below. || // 00340 // || || // 00341 // || double* t_mem = t.memptr(); || // 00342 // || || // 00343 // || You can also get the number of elements of the || // 00344 // || 1D Armadillo vector by the following statement: || // 00345 // || || // 00346 // || const u32 n_attributes = t.n_cols; || // 00347 // ||==============================================================|| // 00348 00349 // ========== UNCOMMENT PIECE OF CODE IF NECESSARY ========== // 00350 // || Number of test feature vectors attributes || // 00351 // ========================================================== // 00352 00353 // %% UNCOMMENT BEGINNING %% 00354 // const u32 n_attributes = t.n_cols; 00355 // %% UNCOMMENT END %% 00356 00357 // ================================================================== // 00358 // || INFO: If you want to use the raw C++ pointer to 1D arrays of || // 00359 // || type "double*" or "unsigned int*" you have to uncomment|| // 00360 // || the pieces of code below. Note however, that Armadillo || // 00361 // || 2D matrices are stored in memory in a columnwise || // 00362 // || manner. || // 00363 // || || // 00364 // || - The memptr() member function is used to obtain a || // 00365 // || raw pointer to the memory used for storing || // 00366 // || elements. || // 00367 // || || // 00368 // || - As soon as the size of the matrix/vector is || // 00369 // || changed, the pointer is no longer valid. || // 00370 // || || // 00371 // || - Data for matrices is stored in a column-by-column || // 00372 // || order. || // 00373 // ================================================================== // 00374 00375 // ========== UNCOMMENT PIECE OF CODE IF NECESSARY ========== // 00376 // || Raw pointer to test feature vector 1D array of type || // 00377 // ||"double*" || // 00378 // ========================================================== // 00379 00380 // %% UNCOMMENT BEGINNING %% 00381 // double* t_mem = t.memptr(); 00382 // %% UNCOMMENT END %% 00383 00384 // ================================================================== // 00385 // || START YOUR CODE HERE || // 00386 // ================================================================== // 00387 00388 // the "predict()" member function must return a double for the 00389 // following reason: 00390 // 00391 // - Many decoding algorithms e.g., Loss Based Decoding need the 00392 // real valued prediction of the classifier, if available (i.e., 00393 // not just, +1 or -1). 00394 00395 00396 // set the return statement to return the prediction of your 00397 // custom classifier 00398 return 0; 00399 00400 // ================================================================== // 00401 // || END YOUR CODE HERE || // 00402 // ================================================================== // 00403 } 00404 00405 00406 00407 #endif 00408 00409 00410