latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 /*---------------------------------------------------------------- 00025 * project ....: LTI Digital Image/Signal Processing Library 00026 * file .......: ltiClassifier.h 00027 * authors ....: Pablo Alvarado, Peter Doerfler 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 10.8.2000 00030 * revisions ..: $Id: ltiClassifier.h,v 1.11 2006/02/07 18:13:29 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_CLASSIFIER_H_ 00034 #define _LTI_CLASSIFIER_H_ 00035 00036 #ifndef _INCLUDE_DEPRECATED 00037 #define _INCLUDE_DEPRECATED 1 00038 #endif 00039 00040 #include "ltiObject.h" 00041 #include <list> 00042 #include <map> 00043 #include <vector> 00044 00045 #include "ltiIoObject.h" 00046 #include "ltiException.h" 00047 #include "ltiVector.h" 00048 #include "ltiMatrix.h" 00049 #include "ltiIoHandler.h" 00050 #include "ltiProgressInfo.h" 00051 #include "ltiStatus.h" 00052 00053 # ifdef min 00054 # undef min 00055 # endif 00056 00057 # ifdef max 00058 # undef max 00059 # endif 00060 00061 namespace lti { 00062 00063 00064 /** 00065 * Abstract parent class for all classifiers. 00066 * 00067 * The classifier class encloses a number of other important classes: 00068 * <dl> 00069 * <dt>lti::classifier::parameters</dt> 00070 * <dd>similar to the functor::parameters, this is used to specify the 00071 * characteristics of a classifier like learning rate, etc.</dd> 00072 * <dt>lti::classifier::outputVector</dt> 00073 * <dd>This type is used to return the classification results.</dd> 00074 * <dt>lti::classifier::outputTemplate</dt> 00075 * <dd>Contains information on how the outputVector is to be constructed 00076 * from a resulting vector of the classification.</dd> 00077 * </dl> 00078 * 00079 * Classifiers can be diveded into two large groups: supervised and 00080 * unsupervised. These two groups have the base classes 00081 * supervisedClassifier and unsupervisedClassifier which are 00082 * subclasses of this class. Examples for the first type are RBF 00083 * networks, multi layer perceptron, maximum likelihood classifiers 00084 * etc. The second type comprises statistic and neural clustering 00085 * methods.<p> All classifiers return an outputVector when classify 00086 * is called. The outputVector is created by the classifier by 00087 * applying its outputTemplate to the regular dvector which results 00088 * from the classification process. 00089 * 00090 */ 00091 class classifier : public ioObject, public status { 00092 public: 00093 /** 00094 * constant to indicate an unknown object 00095 */ 00096 static const int unknownObj; 00097 00098 /** 00099 * constant to indicate "no object" 00100 */ 00101 static const int noObject; 00102 00103 /** 00104 * all probabilities under this value will be considered as 0 00105 */ 00106 static const double nullProbability; 00107 00108 /* 00109 * name of the unknown object 00110 */ 00111 // static const std::string unknownName; 00112 00113 /** 00114 * An output %vector is the result of classifying data with any 00115 * classifier. 00116 * 00117 * It is usually built by a classifier using its 00118 * internal outputTemplate. The outputVector contains labels (also 00119 * called ids) and values (usually probabilities). Typically, each 00120 * label occurs only once in the outputVector and all values are 00121 * between 0 and 1 and form a probability distribution. However, 00122 * this is not required by definition. Each classifier should 00123 * document the nature of its outputVector. 00124 * 00125 * In general, an ouputVector looks like this: 00126 * \image html outputVector0.png 00127 * 00128 * \image latex outputVector0.eps 00129 * 00130 * Some classifiers have multiple outputs for each class or 00131 * unnormalized values. In case this is not wanted in further 00132 * processing outputVector supplies several methods for 00133 * manipulation of labels and values. 00134 * 00135 * The method idMaximize() searches for all multiple ids and 00136 * erases all but the entry with the highest value. For the above 00137 * example this leads to the following outputVector: 00138 * \image html outputVectorLabelMax.png 00139 * 00140 * \image latex outputVectorLabelMax.eps 00141 * 00142 * The values for multiple ids are summed using the method 00143 * idSum(). After execution there is only one entry for each label 00144 * with the sum of values as new value. For the example the result 00145 * is: 00146 * \image html outputVectorLabelSum.png 00147 * 00148 * \image latex outputVectorLabelSum.eps 00149 * 00150 * Due to algorithmic reasons both methods sort the labels in 00151 * ascending order. You can check wether multiple labels exist with the 00152 * method noMultipleIds(). 00153 * 00154 * For many application it is useful if the values of the 00155 * ouputVector form a probability distribution over the labels, 00156 * i.e. all values are greater equal zero and the sum over all 00157 * values is one. This is accomplished by the method 00158 * makeProbDistribution(). It sets values below zero to zero and 00159 * then normalizes the values to sum to one. When applied to the 00160 * two outputVectors above the method gives the following results: 00161 * \image html outputVectorLabelMaxProb.png 00162 * 00163 * \image html outputVectorLabelSumProb.png 00164 * 00165 * \image latex outputVectorLabelMaxProb.eps 00166 * 00167 * \image latex outputVectorLabelSumProb.eps 00168 * 00169 * A classifier or an independent module can decide that a 00170 * classification result does not contain any useful 00171 * informations. Such an outputVector is marked as rejected by 00172 * calling setReject() with argument either true or false. The 00173 * status is queried with isRejected(). 00174 * 00175 * Some classifiers, instead of rejecting a result or not, give 00176 * confidence values. These lie between 0 for lowest and 1 for 00177 * highest confidence. The confidence is set with 00178 * setConfidenceValue() and queried with getConfidenceValue(). 00179 * 00180 * \b NOTE: Confidence values are not taken into account when 00181 * algebraic methods are called. 00182 * 00183 * If possible all classifiers should define a winner unit. This 00184 * is the index (which usually corresponds to the same posisition 00185 * in an internal result) in the ouputVector which achieved the 00186 * best result in the classification. The winner unit is specified 00187 * by calling setWinnerUnit(). If the winner unit is the one with 00188 * the maximum value in the ouputVector, the method 00189 * setWinnerAtMax() can be used. The information is retrieved with 00190 * getWinnerUnit(). 00191 * 00192 * If two or more outputVectors are to be merged or compared it is 00193 * useful to know whether they describe the same set of 00194 * labels. The method compatible() checks whether another 00195 * outputVector contains exactly the same labels as this 00196 * outputVector. 00197 * 00198 * Other functional groups of methods include: 00199 * - read-access methods: getId(), getValueByPosition(), 00200 * getValueById(), getPair(), getValues(), getIds() 00201 * - write-access methods: setId(), setValueByPosition(), 00202 * setValueById(), setPair(), setValues(), setIds(),setIdsAndValues() 00203 * - searchMethods: find(), maxValue(), maxPosition(), maxId(), 00204 * maxPair(), minValue(), minPosition(), minId(), 00205 * minPair() 00206 * - sorting methods: sortAscending(), sortDescending() 00207 * - algebraic methods: various methods that add or multiply 00208 * ouputVectors or apply min or max operators. 00209 */ 00210 class outputVector : public ioObject { 00211 public: 00212 00213 /** 00214 * Default Constructor 00215 */ 00216 outputVector(); 00217 00218 /** 00219 * Copy Constructor 00220 */ 00221 outputVector(const outputVector& other); 00222 00223 /** 00224 * Constructor. Creates an outputVector of the given size. 00225 * @param size size of the output vector 00226 */ 00227 outputVector(const int& size); 00228 00229 /** 00230 * Constructor. Sets the values and the ids. 00231 */ 00232 outputVector(const ivector& theIds, const dvector& theValues); 00233 00234 /** 00235 * copy method. Copy other into this and return this. 00236 */ 00237 outputVector& copy(const outputVector& other); 00238 00239 /** 00240 * copy operator. Copy other into this and return this. 00241 */ 00242 outputVector& operator=(const outputVector& other); 00243 00244 /** 00245 * clone method. 00246 */ 00247 outputVector* clone() const; 00248 00249 /** 00250 * Returns the number of elements in the outputVector 00251 */ 00252 int size() const; 00253 00254 /** 00255 * Finds the given id in the outputVector and returns its position if 00256 * contained in the %outputVector. If the id is not found false is 00257 * returned and the position set to -1. 00258 * @param id find this id 00259 * @param pos the position of the id. 00260 * @return true if id was found, false otherwise 00261 */ 00262 bool find(const int& id, int& pos) const; 00263 00264 /** 00265 * Sets the values of the outputVector. 00266 * The internal vector will be resized to the size of theValues. 00267 * 00268 * @param theValues the new values 00269 */ 00270 void setValues(const dvector& theValues); 00271 00272 /** 00273 * Sets the value at the given position of the outputVector. 00274 * @param pos vector entry, where the value should be written 00275 * @param value the new value 00276 * @return true if successful, false otherwise. 00277 */ 00278 bool setValueByPosition(const int& pos, const double& value); 00279 00280 /** 00281 * Sets the value for the given id in the outputVector. 00282 * @param id id whose value is to be changed 00283 * @param value the new value 00284 * @return true if successful, false otherwise. 00285 */ 00286 bool setValueById(const int& id, const double& value); 00287 00288 /** 00289 * Returns a const reference to the values of the %outputVector. 00290 */ 00291 const dvector& getValues() const; 00292 00293 /** 00294 * Sets the ids of the outputVector. 00295 * @param theIds the new ids 00296 */ 00297 void setIds(const ivector& theIds); 00298 00299 /** 00300 * Sets the ids of the outputVector and the values. 00301 * 00302 * The state of the instance will be exactly as after constructing an 00303 * outputVector with ids and values. 00304 * 00305 * If the sizes of both vectors are not equal, the smallest size will be 00306 * used and the largest vector will be cut. 00307 * 00308 * @param theIds the new ids 00309 * @param theValues the new values 00310 */ 00311 void setIdsAndValues(const ivector& theIds, 00312 const dvector& theValues); 00313 00314 /** 00315 * Returns a const reference to the ids of the %outputVector 00316 */ 00317 const ivector& getIds() const; 00318 00319 /** 00320 * Sets the id and the value at the given position. If the position 00321 * does not exist, false is returned. 00322 * @param pos position to be changed 00323 * @param id id at that position 00324 * @param value value at that position 00325 * @return false on error 00326 */ 00327 bool setPair(const int& pos, const int& id, const double& value); 00328 00329 /** 00330 * Returns the id at the given position. 00331 * @param pos position in the vector 00332 * @param id the id at that position 00333 * @return true if id returned, false e.g. for invalid pos 00334 */ 00335 bool getId(const int& pos, int& id) const; 00336 00337 /** 00338 * Returns the value at the given position 00339 * @param pos position in the vector 00340 * @param value the value at that position 00341 * @return true if id returned, false e.g. for invalid pos 00342 */ 00343 bool getValueByPosition(const int& pos, double& value) const; 00344 00345 /** 00346 * Returns the value for the given id. If an id is used more than 00347 * once the value with the lowest position is returned. 00348 * @param id id value 00349 * @param value the value for the id 00350 * @return true if id returned, false e.g. for invalid pos 00351 */ 00352 bool getValueById(const int& id, double& value) const; 00353 00354 /** 00355 * Returns the id and the value at the given position. 00356 * @param pos position in the vector 00357 * @param id the id at that position 00358 * @param value the value at that position 00359 * @return true if id returned, false e.g. for invalid pos 00360 */ 00361 bool getPair(const int& pos, int& id, double& value) const; 00362 00363 /** 00364 * Set the winner unit 00365 * @param pos position of the winner unit in the vector 00366 * @return false if pos not between 0..n-1 00367 */ 00368 bool setWinnerUnit(const int& pos); 00369 00370 /** 00371 * Set the winner unit as the position of the maximum value of the 00372 * outputVector. 00373 * @return position of the winner unit in the vector 00374 */ 00375 int setWinnerAtMax(); 00376 00377 /** 00378 * Get position of the winner 00379 */ 00380 int getWinnerUnit() const; 00381 00382 /** 00383 * Sets whether result is rejected. Default for reject is false. 00384 * @param rej true if rejected 00385 */ 00386 void setReject(const bool& rej); 00387 00388 /** 00389 * Returns whether the ouputVector was marked as rejected or not. 00390 */ 00391 bool isRejected() const; 00392 00393 /** 00394 * Sets the confidence value for this outputVector. 00395 * The value must be between 0 and 1 for lowest and highest confidence. 00396 * Default is 1. 00397 * Other values are cropped. 00398 * @param conf new confidence value betwenn 0 and 1 00399 */ 00400 void setConfidenceValue(const double& conf); 00401 00402 /** 00403 * Returns the confidence value for this outputVector. Values are 00404 * between zero (no confidence) and one (total confidence). 00405 */ 00406 double getConfidenceValue() const; 00407 00408 /** 00409 * Sorts the outputVector so that values are in ascending order. 00410 * The sort is only executed if the vector is not already sorted. 00411 * Ids and winner position are adjusted accordingly. 00412 */ 00413 void sortAscending(); 00414 00415 /** 00416 * Sorts the outputVector so that values are in descending order. 00417 * The sort is only executed if the vector is not already sorted. 00418 * Ids and winner position are adjusted accordingly. 00419 */ 00420 void sortDescending(); 00421 00422 /** 00423 * Lets the outputVector comply to rules for probability 00424 * distributions: Values between 0 and 1, sum of values equals 00425 * 1. This is done by setting values that are lower than zero to 00426 * zero and afterwards dividing each value by the sum of values. 00427 */ 00428 void makeProbDistribution(); 00429 00430 /** 00431 * Checks whether the other outputVector contains exactly the same 00432 * ids as this outputVector. 00433 * @param other outputVector to be compared to this 00434 * @return true if ids are exactly the same. 00435 */ 00436 bool compatible(const outputVector& other) const; 00437 00438 /** 00439 * Returns true if there are never two elements of the outputVector 00440 * with the same id. 00441 */ 00442 bool noMultipleIds() const; 00443 00444 /** 00445 * If an id is given more than once, the maximum value is sought and 00446 * all other units of this id erased. The resulting outputVector is 00447 * sorted by ids. 00448 */ 00449 void idMaximize(); 00450 00451 /** 00452 * If an id is given more than once, the sum of the values is 00453 * computed and only one unit of that id remains. The resulting 00454 * outputVector is sorted by ids. 00455 */ 00456 void idSum(); 00457 00458 /** 00459 * Find the maximum value in the outputVector 00460 * @return the maximum value 00461 */ 00462 double maxValue() const; 00463 00464 /** 00465 * Find the position of the maximum value in the outputVector 00466 * @return the position of the maximum value 00467 */ 00468 int maxPosition() const; 00469 00470 /** 00471 * Find the id of the maximum value in the outputVector 00472 * @return the id of the maximum value 00473 */ 00474 int maxId() const; 00475 00476 /** 00477 * Find the id-value pair with the maximum value in the outputVector. 00478 * This is faster than finding them separately! 00479 * @param id id of the maximum value 00480 * @param value the maximum value 00481 */ 00482 void maxPair(int& id, double& value) const; 00483 00484 /** 00485 * Find the minimum value in the outputVector 00486 * @return the minimum value 00487 */ 00488 double minValue() const; 00489 00490 /** 00491 * Find the position of the minimum value in the outputVector 00492 * @return the position of the minimum value 00493 */ 00494 int minPosition() const; 00495 00496 /** 00497 * Find the id of the minimum value in the outputVector 00498 * @return the id of the minimum value 00499 */ 00500 int minId() const; 00501 00502 /** 00503 * Find the id-value pair with the minimum value in the outputVector. 00504 * This is faster than finding them separately! 00505 * @param id id of the minimum value 00506 * @param value the minimum value 00507 */ 00508 void minPair(int& id, double& value) const; 00509 00510 /** 00511 * Adds the other outputVector to this outputVector. 00512 * I.e. for each id that exists in both outputVectors the values 00513 * are added, else the value remains unchanged and the new ids 00514 * are appended to this outputVector. 00515 * @param other the outputVector to be added to this one 00516 * @return this outputVector 00517 */ 00518 outputVector& add(const outputVector& other); 00519 00520 /** 00521 * Adds the two outputVectors and writes the result into this 00522 * outputVector. 00523 * @param a the first summand 00524 * @param b the second summand 00525 * @return this outputVector 00526 * @see add(const outputVector& other) 00527 */ 00528 outputVector& add(const outputVector& a, const outputVector& b); 00529 00530 /** 00531 * Adds the given scalar to each value of the outputVector 00532 * @param s the scalar to be added 00533 * @return this outputVector 00534 */ 00535 outputVector& add(const double& s); 00536 00537 /** 00538 * Adds the other outputVector scaled by s to this outputVector. 00539 * I.e. for each id that exists in both outputVectors the values 00540 * are added, else the value remains unchanged and the new ids 00541 * are appended to this outputVector. 00542 * @param other the outputVector to be added to this one 00543 * @param s scaling factor for the other 00544 * @return this outputVector 00545 */ 00546 outputVector& addScaled(const outputVector& other, const double& s); 00547 00548 /** 00549 * Multiplies the other outputVector with this outputVector. 00550 * I.e. for each id that exists in both outputVectors the values 00551 * are multiplied, else the value is zero and the new ids 00552 * are appended to this outputVector. 00553 * @param other the outputVector to be multiplied to this one 00554 * @return this outputVector 00555 */ 00556 outputVector& mul(const outputVector& other); 00557 00558 /** 00559 * Multiplies the two outputVectors and writes the result into this 00560 * outputVector. 00561 * @param a the first factor 00562 * @param b the second factor 00563 * @return this outputVector 00564 * @see mul(const outputVector& other) 00565 */ 00566 outputVector& mul(const outputVector& a, const outputVector& b); 00567 00568 /** 00569 * Multiplies each value of the outputVector with the given scalar. 00570 * @param s the scalar 00571 * @return this outputVector 00572 */ 00573 outputVector& mul(const double& s); 00574 00575 /** 00576 * Divides each value of the outputVector by the given scalar. 00577 * @param s the scalar 00578 * @return this outputVector 00579 */ 00580 outputVector& divide(const double& s); 00581 00582 /** 00583 * Calculates the maximum between the other and this outputVector. 00584 * I.e. for each id that exists in both outputVectors the 00585 * maximum is taken, else the value stays unchanged and the new ids 00586 * are appended to this outputVector. 00587 * @param other the outputVector to be compared to this 00588 * @return this outputVector 00589 */ 00590 outputVector& max(const outputVector& other); 00591 00592 /** 00593 * Calculates the maximum between the two outputVectors and writes 00594 * it into this outputVector. Analog to inplace version. 00595 * @param a the first outputVector 00596 * @param b the second outputVector 00597 * @return this outputVector 00598 * @see max(const outputVector& other) 00599 */ 00600 outputVector& max(const outputVector& a, const outputVector& b); 00601 00602 /** 00603 * Calculates the minimum between the other and this outputVector. 00604 * I.e. for each id that exists in both outputVectors the 00605 * minimum is taken, else the value is zero and the new ids 00606 * are appended to this outputVector. 00607 * @param other the outputVector to be compared to this 00608 * @return this outputVector 00609 */ 00610 outputVector& min(const outputVector& other); 00611 00612 /** 00613 * Calculates the minimum between the two outputVectors and writes 00614 * it into this outputVector. Analog to inplace version. 00615 * @param a the first outputVector 00616 * @param b the second outputVector 00617 * @return this outputVector 00618 * @see min(const outputVector& other) 00619 */ 00620 outputVector& min(const outputVector& a, const outputVector& b); 00621 00622 /** 00623 * write the objectProb in the given ioHandler 00624 * @param handler the ioHandler to be used 00625 * @param complete if true (the default) the enclosing begin/end will 00626 * be also written, otherwise only the data block will be written. 00627 * @return true if write was successful 00628 */ 00629 bool write(ioHandler& handler,const bool complete=true) const; 00630 00631 /** 00632 * read the objectProb from the given ioHandler 00633 * @param handler the ioHandler to be used 00634 * @param complete if true (the default) the enclosing begin/end will 00635 * be also written, otherwise only the data block will be written. 00636 * @return true if write was successful 00637 */ 00638 bool read(ioHandler& handler,const bool complete=true); 00639 00640 # ifdef _LTI_MSC_6 00641 /** 00642 * this function is required by MSVC only, as a workaround for a 00643 * very awful bug, which exists since MSVC V.4.0, and still by 00644 * V.6.0 with all bugfixes (so called "service packs") remains 00645 * there... This method is also public due to another bug, so please 00646 * NEVER EVER call this method directly: use read() instead 00647 */ 00648 bool readMS(ioHandler& handler,const bool complete=true); 00649 00650 /** 00651 * this function is required by MSVC only, as a workaround for a 00652 * very awful bug, which exists since MSVC V.4.0, and still by 00653 * V.6.0 with all bugfixes (so called "service packs") remains 00654 * there... This method is also public due to another bug, so please 00655 * NEVER EVER call this method directly: use write() instead 00656 */ 00657 bool writeMS(ioHandler& handler,const bool complete=true) const; 00658 # endif 00659 00660 protected: 00661 00662 /** 00663 * The ids of the the objects for which the corresponding values 00664 * (usually a probability) stand 00665 */ 00666 ivector ids; 00667 00668 /** 00669 * The actual results of each output unit. Usually, the values are 00670 * probabilities but other double values are legitimate as well. 00671 */ 00672 dvector values; 00673 00674 /** 00675 * The position in the outputVector that contains the winner 00676 * element, ie internal id. 00677 */ 00678 int winner; 00679 00680 /** 00681 * Expresses the confidence in this outputVector. A value of 0 means 00682 * no confidence, a value of 1 stands for 100% confidence. 00683 * Default is 1. 00684 */ 00685 double confidence; 00686 00687 /** 00688 * The outputVector is rejected when this flag is true 00689 */ 00690 bool reject; 00691 00692 /** 00693 * The outputVector is valid only when this flag is true (default). 00694 * Invalid results should not be used for further processing. 00695 */ 00696 bool valid; 00697 00698 /** 00699 * Indicates if vector is sorted in ascending order 00700 */ 00701 bool sortedAsc; 00702 00703 /** 00704 * Indicates if vector is sorted in descending order 00705 */ 00706 bool sortedDesc; 00707 }; 00708 00709 /** 00710 * The %outputTemplate stores the relation between the different 00711 * positions (sometimes called internal ids) of a classification 00712 * result and the ids. Applying the %outputTemplate to such a 00713 * %vector results in an outputVector which is not to be confused 00714 * with the classification result. 00715 * 00716 * There are two data structures within the outputTemplate storing the 00717 * relevant data: 00718 * - A simple list of ids, one for each element of the classification 00719 * result. These are used, when the parameter multipleMode is set to 00720 * Ignore. If %Ignore is set, but the data is not available, the 00721 * %multipleMode is set to Max temporarily. 00722 * - For each element of the classification result exists a list of 00723 * ids and respective probabilities. They state that, when that 00724 * element is activated there is a certain probability that an 00725 * input belonging to the class of the id was presented. These 00726 * probabilities are usually generated by classifying a data-set and 00727 * generating a probability distribution of the ids for the element 00728 * of the classification result with the highest value. This data is 00729 * used for all values of multipleMode but Ignore. If the data is not 00730 * available, %multipleMode is set to %Ignore temprarily. 00731 * 00732 * The calculation of the outputVector using the apply method 00733 * depends on the value of the parameter multipleType, which is of 00734 * type eMultipleType. The following settings are available: 00735 * 00736 * <dl> 00737 * <dt>Ignore</dt> 00738 * <dd> 00739 * If default ids have been stored in the %outputTemplate via the 00740 * constructor that receives an %ivector, the method setIds or setData 00741 * these ids are simply copied to the %outputVector. I.e. no statistics 00742 * about the actual classification performance of the %classifier are 00743 * used. If the data is not set, the option Max is used and false is 00744 * returned by the apply method. 00745 * </dd> 00746 * <dt>Max</dt> 00747 * <dd> 00748 * The probability lists are used. For each element of the classification 00749 * result, the id with the highest probability is found and set to one 00750 * while all other probabilities for that element are set to zero. This 00751 * leads to an %outputVector which is equal or similar to the one 00752 * generated by Ignore. There will be differences, however, if a certain 00753 * element of the classification result was trained for one class, but 00754 * when building the probability distributions another class caused this 00755 * element to have the highest value more frequently. This case can be 00756 * seen for the second element in the example below. 00757 * </dd> 00758 * <dt>Uniform</dt> 00759 * <dd> 00760 * The probability lists are used. For each of the classification result 00761 * the number of ids in the list is found and their probabilities set 00762 * to be uniformly distributed. This method puts very little trust in 00763 * the data used for generating the probabilities, i.e. that it 00764 * represents the true distribution of the data. On the other hand, 00765 * it is very susceptible to noise in the data: One misclassified 00766 * example can completely change the outcome of future classifications. 00767 * </dd> 00768 * <dt>ObjProb</dt> 00769 * <dd> 00770 * The probablity lists are used. The complete information is used. 00771 * This has a functionality similar to a rule set: If element A is 00772 * activated, then there is a probability of 0.3 for class 1 and 0.7 00773 * for class 5. This method works quite well, when the training data 00774 * represents the actual distributions quite well, but the classifier 00775 * is not able to build the correct models. A typical effect of using 00776 * this approach rather than Ignore is that misclassified unknown data 00777 * will have greater probability and thus a higher ranking. On the 00778 * downside, sometimes data correctly classified by Ignore can be 00779 * just misclassified. 00780 * </dd> 00781 * </dl> 00782 * 00783 * As mentioned above for all cases but Ignore, the 00784 * %outputTemplate contains a list of class probabilities for each 00785 * element of the classification result. These are interpreted as 00786 * dependent probablities: P(o|x) where o stands for 00787 * the id and x for the position in the classification 00788 * result. Each element of the classification results is also 00789 * taken as a probability p(x). Thus the values for each id 00790 * are calculated as \f$P(o)=\sum_x p(x)\cdot P(o|x)\f$. <br> 00791 * 00792 * Here is a short example for the behavior of an outputTemplate 00793 * when applied to a classification result. The figure shows the 00794 * classification result on the lefthand side, the default ids 00795 * which are used with the option Ignore in the middle and the 00796 * probabiltity lists which are used for Max, Uniform and ObjProb 00797 * on the righthand side. 00798 * 00799 * \image html outputTemplate.png 00800 * 00801 * \image latex outputTemplate.eps 00802 * 00803 * Depending on the value of multipleMode the following outputVector is 00804 * generated by calling apply: 00805 * 00806 * <table border=1> 00807 * <tr> 00808 * <td> </td><td>1</td><td>3</td><td>5</td> 00809 * <td>6</td><td>17</td><td>22</td><td>41</td> 00810 * </tr><tr> 00811 * <td>Ignore</td><td>0.15</td><td>0.50</td><td>---</td> 00812 * <td>---</td><td>0.03</td><td>0.30</td><td>0.02</td> 00813 * </tr><tr> 00814 * <td>Max</td><td>0.15</td><td>---</td><td>---</td> 00815 * <td>0.50</td><td>0.03</td><td>0.30</td><td>0.02</td> 00816 * </tr><tr> 00817 * <td>Uniform</td><td>0.15</td><td>0.35</td><td>0.10</td> 00818 * <td>0.25</td><td>0.04</td><td>0.10</td><td>0.01</td> 00819 * </tr><tr> 00820 * <td>ObjProb</td><td>0.15</td><td>0.33</td><td>0.05</td> 00821 * <td>0.27</td><td>0.04</td><td>0.15</td><td>0.01</td> 00822 * </tr> 00823 * </table> 00824 * 00825 * If the use of all four options is desired, the constructor 00826 * outputTemplate(int) receiving an int value must be used. All 00827 * data can be set using methods setIds, setProbs and/or 00828 * setData. If the other constructors are used, no space is 00829 * reserved for the lists of probabilities, since these take much 00830 * space and some, especially unsupervised, %classifiers do not 00831 * need or have no means to gather this information. 00832 */ 00833 class outputTemplate : public ioObject { 00834 00835 public: 00836 00837 /** 00838 * This type specifies how the output element probability and 00839 * the probabilities in the list should be combined. See description of 00840 * outputTemplate. 00841 */ 00842 enum eMultipleMode{ 00843 Ignore = 0, /*!< ignore the %object probability */ 00844 Max, /*!< set the prob of the id with max prob to 1, others 00845 to zero. */ 00846 Uniform, /*!< assume that all objects in the list of one output 00847 element have the same probability 00848 (1/number of elements). */ 00849 ObjProb /*!< consider the given %object probabilities */ 00850 }; 00851 00852 00853 /** 00854 * Default constructor. <p> 00855 * multipleMode is ObjProb. 00856 */ 00857 outputTemplate(); 00858 00859 /** 00860 * Copy constructor. 00861 */ 00862 outputTemplate(const outputTemplate& other); 00863 00864 /** 00865 * Constructor. Since a vector of ids is given multipleMode is Ignore and 00866 * the probability lists are not initialized and thus cannot be set 00867 * later. 00868 */ 00869 outputTemplate(const ivector& theIds); 00870 00871 /** 00872 * Constructor. The number of output units is 00873 * given. multipleMode is ObjeProb. Default ids as well as lists 00874 * of probabilities can be set. 00875 */ 00876 outputTemplate(const int& size); 00877 00878 /** 00879 * copy 00880 */ 00881 outputTemplate& copy(const outputTemplate& other); 00882 00883 /** 00884 * assigment operator (alias for copy(other)). 00885 * @param other the outputTemplate to be copied 00886 * @return a reference to the actual outputTemplate 00887 */ 00888 inline outputTemplate& operator=(const outputTemplate& other) { 00889 return copy(other); 00890 } 00891 00892 /** 00893 * clone 00894 */ 00895 outputTemplate* clone() const; 00896 00897 /** 00898 * Change the setting of how the object probabilities of each unit 00899 * are taken into account when calculating the outputVector. See 00900 * description of outputTemplate. 00901 */ 00902 void setMultipleMode(const eMultipleMode& mode); 00903 00904 /** 00905 * Get the setting of multipleMode 00906 */ 00907 eMultipleMode getMultipleMode() const; 00908 00909 /** 00910 * Set the default id vector. These are used when multipleMode is set 00911 * to Ignore. 00912 */ 00913 bool setIds(const ivector& theIds); 00914 00915 /** 00916 * Returns a const reference to the id vector. 00917 */ 00918 const ivector& getIds() const; 00919 00920 /** 00921 * Set the probabilities of one unit. This information must be set for 00922 * all elements of the classification result. Then is can be used 00923 * by the apply method when multipleMode is set to one of Max, Uniform 00924 * or ObjProb. 00925 * @param pos the posision in the classification result this distribution 00926 * is for- 00927 * @param theIds list of ids of classes possibly correct, when this 00928 * position has high probability. 00929 * @param theValues probabilities of each of these ids. 00930 * @return false on errer, e.g. illegal pos 00931 */ 00932 bool setProbs(const int& pos, const ivector& theIds, 00933 const dvector& theValues); 00934 00935 /** 00936 * Set the probabilities of one unit. This information must be set for 00937 * all elements of the classification result. Then is can be used 00938 * by the apply method when multipleMode is set to one of Max, Uniform 00939 * or ObjProb. 00940 * @param pos the posision in the classification result this distribution 00941 * is for- 00942 * @param outV list of ids and corresponding probabilities of classes 00943 * possibly correct, when this position has high 00944 * probability. 00945 * @return false on error, e.g. illegal pos 00946 */ 00947 bool setProbs(const int& pos, const outputVector& outV); 00948 00949 /** 00950 * Returns a const reference to the probability distribution at 00951 * the given position of the template. 00952 */ 00953 const outputVector& getProbs(const int& pos) const; 00954 00955 /** 00956 * Set the probabilities and the default id of one unit. This 00957 * information must be set for all elements of the 00958 * classification result. Then is can be used by the apply 00959 * method for any value of multipleMode. 00960 * @param pos the posision in the classification result this distribution 00961 * is for. 00962 * @param realId the expected or desired id of this posision of the 00963 * classification result. 00964 * @param outV list of ids and corresponding probabilities of classes 00965 * possibly correct, when this position has high 00966 * probability. 00967 * @return false on error, e.g. illegal pos 00968 */ 00969 bool setData(const int& pos, const int& realId, 00970 const outputVector& outV); 00971 00972 /** 00973 * returns the number of output units handled by this outputTemplate 00974 */ 00975 int size() const; 00976 00977 /** 00978 * Uses the information stored in the outputTemplate to generate 00979 * an outputVector from a dvector. See description of 00980 * outputTemplate for details. The classification result should 00981 * contain only positive values which are greater for better 00982 * fit. The best interpretability is obtained if data is a 00983 * probability distribution. 00984 * @param data the classification result 00985 * @param result %outputVector calculted using the outputTemplate. 00986 * @return false on error (check getStatusString()) 00987 */ 00988 bool apply(const dvector& data, outputVector& result) const; 00989 00990 /** 00991 * write the outputTemplate in the given ioHandler 00992 * @param handler the ioHandler to be used 00993 * @param complete if true (the default) the enclosing begin/end will 00994 * be also written, otherwise only the data block will be written. 00995 * @return true if write was successful 00996 */ 00997 bool write(ioHandler& handler,const bool complete=true) const; 00998 00999 /** 01000 * read the outputTemplate from the given ioHandler 01001 * @param handler the ioHandler to be used 01002 * @param complete if true (the default) the enclosing begin/end will 01003 * be also written, otherwise only the data block will be written. 01004 * @return true if write was successful 01005 */ 01006 bool read(ioHandler& handler,const bool complete=true); 01007 01008 # ifdef _LTI_MSC_6 01009 /** 01010 * this function is required by MSVC only, as a workaround for a 01011 * very awful bug, which exists since MSVC V.4.0, and still by 01012 * V.6.0 with all bugfixes (so called "service packs") remains 01013 * there... This method is also public due to another bug, so please 01014 * NEVER EVER call this method directly: use read() instead 01015 */ 01016 bool readMS(ioHandler& handler,const bool complete=true); 01017 01018 /** 01019 * this function is required by MSVC only, as a workaround for a 01020 * very awful bug, which exists since MSVC V.4.0, and still by 01021 * V.6.0 with all bugfixes (so called "service packs") remains 01022 * there... This method is also public due to another bug, so please 01023 * NEVER EVER call this method directly: use write() instead 01024 */ 01025 bool writeMS(ioHandler& handler,const bool complete=true) const; 01026 # endif 01027 01028 protected: 01029 01030 01031 /** 01032 * Determines what data is used for calculation of an 01033 * outputVector from the classification result and the 01034 * outputTemplate. See eUseObjectProb and outputTemplate for 01035 * detailed description. 01036 */ 01037 eMultipleMode multipleMode; 01038 01039 /** 01040 * Contains one outputVector for each output unit. These 01041 * hold the probabilities for the ids being correct when this 01042 * unit is activated. 01043 */ 01044 std::vector<outputVector> probList; 01045 01046 /** 01047 * List of ids for each output unit. 01048 */ 01049 ivector defaultIds; 01050 01051 }; 01052 01053 01054 01055 // -------------------------------------------------- 01056 // classifier::parameters 01057 // -------------------------------------------------- 01058 01059 /** 01060 * the parameters for the class classifier 01061 */ 01062 class parameters : public ioObject { 01063 public: 01064 01065 /** 01066 * indicates the distance measure used for the classifier 01067 */ 01068 enum eDistanceMeasure { 01069 L1, /*!< L1-norm (sum of the absolut values) */ 01070 L2 /*!< L2-norm (square root of the sum of the squares)*/ 01071 }; 01072 01073 01074 /** 01075 * Sets the mode the outputTemplate of the %classifier works in, 01076 * if it uses multipleIds. This option is usually fixed for all 01077 * %classifiers. unsupervised %classifiers methods usually wont 01078 * use multiple ids, whereas supervised %classifiers will. The 01079 * default is ObjProb.<p> 01080 * Setting this parameters only makes sense before using classify, 01081 * since all information is recorded during training anyway. 01082 */ 01083 outputTemplate::eMultipleMode multipleMode; 01084 01085 /** 01086 * default constructor 01087 */ 01088 parameters(); 01089 01090 /** 01091 * copy constructor 01092 * @param other the parameters %object to be copied 01093 */ 01094 parameters(const parameters& other); 01095 01096 /** 01097 * destructor 01098 */ 01099 virtual ~parameters(); 01100 01101 /** 01102 * returns name of this type 01103 */ 01104 const char* getTypeName() const; 01105 01106 /** 01107 * copy the contents of a parameters %object 01108 * @param other the parameters %object to be copied 01109 * @return a reference to this parameters %object 01110 */ 01111 parameters& copy(const parameters& other); 01112 01113 /** 01114 * Alias for copy 01115 */ 01116 inline parameters& operator=(const parameters& other) { 01117 return copy(other); 01118 } 01119 01120 01121 /** 01122 * returns a pointer to a clone of the parameters 01123 */ 01124 virtual parameters* clone() const; 01125 01126 /** 01127 * write the parameters in the given ioHandler 01128 * @param handler the ioHandler to be used 01129 * @param complete if true (the default) the enclosing begin/end will 01130 * be also written, otherwise only the data block will be written. 01131 * @return true if write was successful 01132 */ 01133 virtual bool write(ioHandler& handler,const bool complete=true) const; 01134 01135 /** 01136 * read the parameters from the given ioHandler 01137 * @param handler the ioHandler to be used 01138 * @param complete if true (the default) the enclosing begin/end will 01139 * be also written, otherwise only the data block will be written. 01140 * @return true if write was successful 01141 */ 01142 virtual bool read(ioHandler& handler,const bool complete=true); 01143 01144 # ifdef _LTI_MSC_6 01145 /** 01146 * this function is required by MSVC only, as a workaround for a 01147 * very awful bug, which exists since MSVC V.4.0, and still by 01148 * V.6.0 with all bugfixes (so called "service packs") remains 01149 * there... This method is also public due to another bug, so please 01150 * NEVER EVER call this method directly: use read() instead 01151 */ 01152 bool readMS(ioHandler& handler,const bool complete=true); 01153 01154 /** 01155 * this function is required by MSVC only, as a workaround for a 01156 * very awful bug, which exists since MSVC V.4.0, and still by 01157 * V.6.0 with all bugfixes (so called "service packs") remains 01158 * there... This method is also public due to another bug, so please 01159 * NEVER EVER call this method directly: use write() instead 01160 */ 01161 bool writeMS(ioHandler& handler,const bool complete=true) const; 01162 # endif 01163 01164 }; 01165 01166 // -------------------------------------------------- 01167 // exceptions 01168 // -------------------------------------------------- 01169 01170 /** 01171 * Exception thrown when the output %objects has not been set yet 01172 */ 01173 class invalidOutputException : public exception { 01174 public: 01175 /** 01176 * Default constructor 01177 */ 01178 invalidOutputException() 01179 : exception("wrong classifier output type or output not set yet") {}; 01180 01181 /** 01182 * returns the name of this exception 01183 */ 01184 virtual const char* getTypeName() const { 01185 return "classifier::invalidOutputException"; 01186 }; 01187 }; 01188 01189 /** 01190 * Exception thrown when the parameters are not set 01191 */ 01192 class invalidParametersException : public exception { 01193 public: 01194 /** 01195 * Default constructor 01196 */ 01197 invalidParametersException() 01198 : exception("wrong parameter type or parameters not set yet") {}; 01199 01200 /** 01201 * Constructor with the alternative object name, where the exception 01202 * was thrown 01203 */ 01204 invalidParametersException(const std::string& str) 01205 : exception(std::string("wrong parameter type or parameters not set yet at ")+str) {}; 01206 01207 /** 01208 * Constructor with the alternative object name, where the exception 01209 * was thrown 01210 */ 01211 invalidParametersException(const char* str) 01212 : exception(std::string("wrong parameter type or parameters not set yet at ")+std::string(str)) {}; 01213 01214 /** 01215 * returns the name of this exception 01216 */ 01217 virtual const char* getTypeName() const; 01218 }; 01219 01220 /** 01221 * Exception thrown when a method of a functor is not implemented for 01222 * a specific parameter set. 01223 */ 01224 class invalidMethodException : public exception { 01225 public: 01226 /** 01227 * Default constructor 01228 */ 01229 invalidMethodException() 01230 : exception("Method not implemented for given parameters") {}; 01231 /** 01232 * returns the name of this exception 01233 */ 01234 virtual const char* getTypeName() const; 01235 }; 01236 01237 /** 01238 * Exception thrown when a parameter is out of range 01239 */ 01240 class parametersOutOfRangeException : public exception { 01241 public: 01242 /** 01243 * Default constructor 01244 */ 01245 parametersOutOfRangeException() 01246 : exception("at least one parameter is out range") {}; 01247 01248 /** 01249 * returns the name of this exception 01250 */ 01251 virtual const char* getTypeName() const; 01252 }; 01253 01254 // -------------------------------------------------- 01255 // classifier 01256 // -------------------------------------------------- 01257 01258 /** 01259 * default constructor 01260 */ 01261 classifier(); 01262 01263 /** 01264 * copy constructor 01265 * @param other the %object to be copied 01266 */ 01267 classifier(const classifier& other); 01268 01269 /** 01270 * destructor 01271 */ 01272 virtual ~classifier(); 01273 01274 /** 01275 * returns the name of this type ("classifier") 01276 */ 01277 virtual const char* getTypeName() const; 01278 01279 // /** 01280 // * return the last message set with setStatusString(). This will 01281 // * never return 0. If no status-string has been set yet an empty string 01282 // * (pointer to a string with only the char(0)) will be returned. 01283 // */ 01284 // virtual const char* getStatusString() const; 01285 01286 // /** 01287 // * set a status string. 01288 // * 01289 // * @param msg the const string to be reported next time by 01290 // * getStatusString(). The given string will be copied 01291 // * This message will be usually set within the apply methods to indicate 01292 // * an error cause. 01293 // * 01294 // * Note that the change of the status string is not considered as 01295 // * a change in the functor status. 01296 // */ 01297 // virtual void setStatusString(const char* msg) const; 01298 01299 /** 01300 * copy data of "other" functor. 01301 * @param other the functor to be copied 01302 * @return a reference to this functor %object 01303 */ 01304 classifier& copy(const classifier& other); 01305 01306 /** 01307 * 01308 * Alias for "copy". 01309 */ 01310 inline classifier& operator=(const classifier& other) { 01311 return copy(other); 01312 } 01313 01314 /** 01315 * returns a pointer to a clone of this functor. 01316 */ 01317 virtual classifier* clone() const = 0; 01318 01319 /** 01320 * returns true if the parameters are valid 01321 */ 01322 virtual bool validParameters() const {return (params != 0);}; 01323 01324 /** 01325 * returns used parameters 01326 */ 01327 const parameters& getParameters() const; 01328 01329 /** 01330 * sets the classifier's parameters. 01331 * This member makes a copy of <em>theParam</em>: the classifier 01332 * will keep its own copy of the parameters! 01333 */ 01334 virtual bool setParameters(const parameters& theParam); 01335 01336 /** 01337 * @name Progress Info 01338 * 01339 * Methods used to plug-in and retrieve progress visualization objects. 01340 */ 01341 //@{ 01342 01343 /** 01344 * set a progress %object 01345 * 01346 * A clone of the given %object will be generated. 01347 */ 01348 void setProgressObject(const progressInfo& progBox); 01349 01350 /** 01351 * remove the active progress %object 01352 */ 01353 void removeProgressObject(); 01354 01355 /** 01356 * return true if a valid progressInfo %object has already been setted 01357 */ 01358 bool validProgressObject() const; 01359 01360 /** 01361 * get progress %object 01362 */ 01363 progressInfo& getProgressObject(); 01364 01365 /** 01366 * get progress %object 01367 */ 01368 const progressInfo& getProgressObject() const; 01369 //@} 01370 01371 /** 01372 * sets the classifier's outputTemplate 01373 * This member makes a copy of <em>theOutputTemplate</em>: the classifier 01374 * will keep its own copy of the outputTemplate 01375 */ 01376 virtual void setOutputTemplate(const outputTemplate& theOutputTemplate); 01377 01378 /** 01379 * get a const reference to the outputTemplate 01380 */ 01381 const outputTemplate& getOutputTemplate() const; 01382 01383 /** 01384 * write the classifier in the given ioHandler 01385 * @param handler the ioHandler to be used 01386 * @param complete if true (the default) the enclosing begin/end will 01387 * be also written, otherwise only the data block will be written. 01388 * @return true if write was successful 01389 */ 01390 virtual bool write(ioHandler& handler,const bool complete=true) const; 01391 01392 /** 01393 * read the classifier from the given ioHandler 01394 * @param handler the ioHandler to be used 01395 * @param complete if true (the default) the enclosing begin/end will 01396 * be also written, otherwise only the data block will be written. 01397 * @return true if write was successful 01398 */ 01399 virtual bool read(ioHandler& handler,const bool complete=true); 01400 01401 protected: 01402 /** 01403 * returns current parameters. (non const! -> protected) 01404 */ 01405 //parameters& getParameters() {return *params;}; 01406 01407 /** 01408 * current parameters. 01409 */ 01410 parameters* params; 01411 01412 /** 01413 * current progress %object 01414 */ 01415 progressInfo* progressBox; 01416 01417 // /** 01418 // * the status string written with setStatusString 01419 // */ 01420 // mutable char* statusString; 01421 01422 // /** 01423 // * the empty string returned if the statusString is empty 01424 // */ 01425 // static const char *const emptyString; 01426 01427 /** 01428 * The outputTemplate for this classifier 01429 */ 01430 outputTemplate outTemplate; 01431 01432 }; 01433 01434 01435 /** 01436 * write the functor::parameters in the given ioHandler. 01437 * The complete flag indicates 01438 * if the enclosing begin and end should be also be written or not 01439 */ 01440 bool write(ioHandler& handler,const classifier::parameters& p, 01441 const bool complete = true); 01442 01443 /** 01444 * read the functor::parameters from the given ioHandler. 01445 * The complete flag indicates 01446 * if the enclosing begin and end should be also be written or not 01447 */ 01448 bool read(ioHandler& handler,classifier::parameters& p, 01449 const bool complete = true); 01450 01451 /** 01452 * write the classifier in the given ioHandler. 01453 * The complete flag indicates 01454 * if the enclosing begin and end should be also be written or not 01455 */ 01456 bool write(ioHandler& handler,const classifier& p, 01457 const bool complete = true); 01458 01459 /** 01460 * read the classifier from the given ioHandler. 01461 * The complete flag indicates 01462 * if the enclosing begin and end should be also be written or not 01463 */ 01464 bool read(ioHandler& handler,classifier& p, 01465 const bool complete = true); 01466 01467 /** 01468 * write the functor::parameters in the given ioHandler. 01469 * The complete flag indicates 01470 * if the enclosing begin and end should be also be written or not 01471 */ 01472 bool write(ioHandler& handler,const classifier::outputVector& p, 01473 const bool complete = true); 01474 01475 /** 01476 * read the functor::parameters from the given ioHandler. 01477 * The complete flag indicates 01478 * if the enclosing begin and end should be also be written or not 01479 */ 01480 bool read(ioHandler& handler,classifier::outputVector& p, 01481 const bool complete = true); 01482 01483 /** 01484 * write the functor::parameters in the given ioHandler. 01485 * The complete flag indicates 01486 * if the enclosing begin and end should be also be written or not 01487 */ 01488 bool write(ioHandler& handler,const classifier::outputTemplate& p, 01489 const bool complete = true); 01490 01491 /** 01492 * read the functor::parameters from the given ioHandler. 01493 * The complete flag indicates 01494 * if the enclosing begin and end should be also be written or not 01495 */ 01496 bool read(ioHandler& handler,classifier::outputTemplate& p, 01497 const bool complete = true); 01498 01499 } 01500 01501 namespace std { 01502 ostream& 01503 operator<<(ostream& s,const lti::classifier::outputVector& o); 01504 } 01505 01506 #endif