iRoCS Toolbox  1.1.0
MultiClassSVMOneVsOne.hh
Go to the documentation of this file.
1 /**************************************************************************
2  *
3  * Copyright (C) 2004-2015 Olaf Ronneberger, Florian Pigorsch, Jörg Mechnich,
4  * Thorsten Falk
5  *
6  * Image Analysis Lab, University of Freiburg, Germany
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  **************************************************************************/
23 
24 /**************************************************************************
25 ** Title: multi class svm using "one versus one" technique
26 ** $RCSfile$
27 ** $Revision: 2825 $$Name$
28 ** $Date: 2009-09-15 17:04:15 +0200 (Tue, 15 Sep 2009) $
29 ** Copyright: GPL $Author: ronneber $
30 ** Description:
31 **
32 **
33 **
34 **-------------------------------------------------------------------------
35 **
36 ** $Log$
37 ** Revision 1.7 2005/10/26 07:26:37 ronneber
38 ** - added saveClassificationDetails()
39 ** - corrected some comments where "decision value" was called "alpha"
40 **
41 ** Revision 1.6 2005/03/29 18:00:31 ronneber
42 ** - replaced updateCacheFlag, etc with updateKernelCache() and
43 ** clearKernelCache() methods
44 **
45 ** Revision 1.5 2004/09/13 10:04:04 ronneber
46 ** - documentation update
47 **
48 ** Revision 1.4 2004/09/08 14:32:31 ronneber
49 ** - adapted to new ParamInfo class
50 **
51 ** Revision 1.3 2004/09/03 07:13:36 ronneber
52 ** - adapted to new updateCache() interface of Kernels
53 **
54 ** Revision 1.2 2004/09/01 14:43:36 ronneber
55 ** changed IterToPointerTraits stuff to
56 ** DirectAccessor and DereferencingAccessor, to make code more
57 ** intuitive understandable
58 **
59 ** Revision 1.1 2004/08/26 08:36:59 ronneber
60 ** initital import
61 **
62 ** Revision 1.13 2003/05/19 11:02:52 ronneber
63 ** - converted from MapTools to ParamMapWrapper
64 ** - added new train() method where access to the feature vectors
65 ** container is done via a custom functor. This means, you now can give
66 ** your training vectors, e.g., as std::vector<FV> or std::vector<FV*>
67 ** or somethin completely different. You just have to pass an
68 ** appropriate Accessor to make an FV* from an iterator
69 ** - added verboseLevel
70 **
71 ** Revision 1.12 2002/09/05 13:08:27 pigorsch
72 ** -modified to use new MapTools
73 **
74 ** Revision 1.11 2002/06/07 07:40:05 ronneber
75 ** - added missing #include <vector>
76 **
77 ** Revision 1.10 2002/05/23 19:04:32 ronneber
78 ** - #included missing SupportVector
79 **
80 ** Revision 1.9 2002/05/23 15:24:10 ronneber
81 ** - added copySVCoefsToModelMatrix()
82 **
83 ** Revision 1.8 2002/05/22 16:39:06 ronneber
84 ** - added progress reporting capabilities
85 **
86 ** Revision 1.7 2002/05/14 10:12:25 ronneber
87 ** - adapted to new TriangularMatrix (now using upper triangular matrix)
88 **
89 ** Revision 1.6 2002/05/13 16:24:17 ronneber
90 ** - added copySVCoefsToFeatureVectors(). This function can be used to
91 ** store support vectors in an original libsvm compatible format
92 **
93 ** Revision 1.5 2002/05/10 11:33:40 ronneber
94 ** - added default Constructor and twoClassSVM() method
95 **
96 ** Revision 1.4 2002/05/10 11:07:03 ronneber
97 ** - removed FV template for all public classes, because Feature Vector type
98 ** can be extracted automatically from passed iterators or other
99 ** parameters -- this makes the public interface much more intuitive
100 **
101 ** Revision 1.3 2002/05/08 10:36:11 ronneber
102 ** - added some debugging stuff
103 **
104 ** Revision 1.2 2002/05/06 12:23:37 ronneber
105 ** - first functional version
106 **
107 ** Revision 1.1 2002/05/02 15:43:55 ronneber
108 ** initial revision
109 **
110 **
111 **
112 **************************************************************************/
113 
114 #ifndef MULTICLASSSVMONEVSONE_HH
115 #define MULTICLASSSVMONEVSONE_HH
116 
117 #ifdef HAVE_CONFIG_H
118 #include <config.hh>
119 #endif
120 
121 // std includes
122 #include <map>
123 #include <set>
124 #include <sstream>
125 #include <string>
126 #include <vector>
127 
128 // libsvmtl includes
129 
130 #include "TriangularMatrix.hh"
131 #include "ProgressReporter.hh"
132 #include "Model_MC_OneVsOne.hh"
133 #include "GroupedTrainingData.hh"
134 #include "DereferencingAccessor.hh"
135 
136 // requirements of template parameters
143 
144 namespace svt
145 {
146  /*======================================================================*/
167  /*======================================================================*/
168  template< typename SVM>
170  {
173 
174 
175 
176  public:
177 
178  template< typename FV>
179  struct Traits
180  {
182  };
183 
185 
186 
187  /*---------------------------------------------------------------------
188  * Dummy result matrix, if no detailed results are requested
189  *---------------------------------------------------------------------*/
191  {
192  double dummy;
193  public:
194  void resizeWidth( unsigned int)
195  {}
196 
197  double& operator()( int, int)
198  {
199  return dummy;
200  }
201  };
202 
203 
204 
205  /*======================================================================*/
212  /*======================================================================*/
213  MultiClassSVMOneVsOne( const SVM& svm)
214  :_twoClassSVM( svm),
215  _pr(0)
216  {
217  }
218 
219 
220  /*======================================================================*/
226  /*======================================================================*/
228  :_pr(0)
229  {
230  }
231 
232 
233  /*======================================================================*/
246  /*======================================================================*/
248  {
249  _pr = pr;
250  _twoClassSVM.setProgressReporter( pr);
251  }
252 
253 
254 
255  /*======================================================================*/
259  /*======================================================================*/
260  const SVM& twoClassSVM() const
261  {
262  return _twoClassSVM;
263  }
264 
265  /*======================================================================*/
269  /*======================================================================*/
270  SVM& twoClassSVM()
271  {
272  return _twoClassSVM;
273  }
274 
275 
276  /*======================================================================*/
286  /*======================================================================*/
287  template< typename ForwardIter, typename Accessor>
288  void updateKernelCache( const ForwardIter& fvBegin,
289  const ForwardIter& fvEnd,
290  Accessor accessor) const
291  {
292  _twoClassSVM.updateKernelCache( fvBegin, fvEnd, accessor);
293  }
294 
295 
296  /*======================================================================*/
306  /*======================================================================*/
307  void clearKernelCache() const
308  {
309  _twoClassSVM.clearKernelCache();
310  }
311 
312 
313  /*====================================================================*/
333  /*====================================================================*/
334  template<typename FV>
335  void train( const GroupedTrainingData<FV>& trainData,
336  typename Traits<FV>::ModelType& model) const;
337 
338 
339 
340  /*====================================================================*/
350  /*====================================================================*/
351  template<typename FV>
352  void train( const SVM_Problem<FV>& problem,
353  typename Traits<FV>::ModelType& model) const
354  {
355  GroupedTrainingData<FV> trainData( problem);
356  train( trainData, model);
357  }
358 
359 
360 
361 
362 
363  /*======================================================================*/
381  /*======================================================================*/
382  template< typename ForwardIter>
383  void train( ForwardIter FV_begin,
384  const ForwardIter& FV_end,
385  typename Traits<typename std::iterator_traits< ForwardIter>::value_type>::ModelType& model) const
386  {
387  train( FV_begin, FV_end, model, DirectAccessor());
388  }
389 
390 
391  /*======================================================================*/
413  /*======================================================================*/
414  template< typename ForwardIter, typename Accessor>
415  void train( ForwardIter FV_begin,
416  const ForwardIter& FV_end,
417  typename Traits<typename Accessor::template Traits<ForwardIter>::value_type>::ModelType& model,
418  Accessor accessor) const
419  {
420  typedef typename Accessor::template Traits<ForwardIter>::value_type FV;
421  GroupedTrainingData<FV> trainData( FV_begin, FV_end,
422  accessor);
423  train( trainData, model);
424  }
425 
426 
427 
428 
429  /*======================================================================*/
449  /*======================================================================*/
450  template<typename FV>
452  const GroupedTrainingData<FV>& trainData,
453  const typename Traits<FV>::ModelType& fullModel,
454  const std::vector<char>& leaveOutFlagsByUID,
455  typename Traits<FV>::ModelType& resultingModel) const;
456 
457 
458  /*======================================================================*/
471  /*======================================================================*/
472  template< typename FV, typename ResultMatrix>
473  unsigned int predictClassIndex(
474  const FV& testObject,
475  const typename Traits<FV>::ModelType& model,
476  ResultMatrix& resultMatrix) const;
477 
478 
479  /*======================================================================*/
488  /*======================================================================*/
489  template< typename FV>
490  unsigned int predictClassIndex(
491  const FV& testObject,
492  const typename Traits<FV>::ModelType& model) const
493  {
494  DummyResultMatrix dummy;
495  return predictClassIndex( testObject, model, dummy);
496  }
497 
498 
499  /*======================================================================*/
513  /*======================================================================*/
514  template< typename FV, typename ResultMatrix>
515  double classify( const FV& testObject,
516  const typename Traits<FV>::ModelType& model,
517  ResultMatrix& resultMatrix) const
518  {
519  return model.classIndexToLabel(
520  predictClassIndex( testObject, model, resultMatrix));
521  }
522 
523 
524  /*======================================================================*/
533  /*======================================================================*/
534  template< typename FV>
535  double classify( const FV& testObject,
536  const typename Traits<FV>::ModelType& model) const
537  {
538  DummyResultMatrix dummy;
539  return classify( testObject, model, dummy);
540  }
541 
542 
543  template<typename STDATA>
544  void loadParameters( STDATA& stData)
545  {
547 
548  _twoClassSVM.loadParameters(stData);
549 
550  }
551 
552  template<typename STDATA>
553  void saveParameters( STDATA& stData) const
554  {
556 
557  stData.setValue( "multi_class_type", name());
558  _twoClassSVM.saveParameters( stData);
559  }
560 
561  /*======================================================================*/
570  /*======================================================================*/
571  template< typename ModelType, typename STDATA>
573  const DetailedResultType&,
574  STDATA&) const
575  {
576  std::cerr << "warning: saving details from "
577  "MultiClassSVMOneVsOne not implemented yet!\n";
578  }
579 
580  /*======================================================================*/
589  /*======================================================================*/
590  static void getParamInfos( std::vector<ParamInfo>&)
591  {
592  }
593 
594 
595  static const char* name()
596  {
597  return "one_vs_one";
598  }
599 
600  static const char* description()
601  {
602  return "multi-class SVM by using the 'one versus one' approach";
603  }
604 
605  private:
606  SVM _twoClassSVM;
607  ProgressReporter* _pr;
608 
609 
610  };
611 
612 #include "MultiClassSVMOneVsOne.icc"
613 }
614 
615 #endif
The GroupedTrainingData class is a container for feature vectors.
#define CHECK_MEMBER_TEMPLATE(c)
void updateKernelCache(const ForwardIter &fvBegin, const ForwardIter &fvEnd, Accessor accessor) const
call the updateKernelCache() method of selected two-class svm
void saveParameters(STDATA &stData) const
double classify(const FV &testObject, const typename Traits< FV >::ModelType &model, ResultMatrix &resultMatrix) const
classify the given testObject using the models in Model matrix.
double classIndexToLabel(unsigned int classIndex) const
Definition: Model_MC.hh:145
#define CHECK_CLASS_TEMPLATE1(c)
The TriangularMatrix class is an upper triangular matrix without diagonal elements.
double classify(const FV &testObject, const typename Traits< FV >::ModelType &model) const
classify the given testObject using the model
void train(ForwardIter FV_begin, const ForwardIter &FV_end, typename Traits< typename std::iterator_traits< ForwardIter >::value_type >::ModelType &model) const
train the Multi Class SVM with the given feature vectors.
The MultiClassSVMOneVsOne class provides a one vs.
void clearKernelCache() const
call the clearKernelCache() method of selected two-class svm
static void getParamInfos(std::vector< ParamInfo > &)
get information about the parameters, that are used in loadParameters() and saveParameters().
#define CHECK_CLASS_TEMPLATE2(c)
void loadParameters(STDATA &stData)
Ensure that TESTCLASS provides a loadParameters() and saveParamters() method.
MultiClassSVMOneVsOne(const SVM &svm)
Create a multi class SVM basing on the given svm object.
MultiClassSVMOneVsOne()
Create a multi class SVM.
TriangularMatrix< double > DetailedResultType
unsigned int predictClassIndex(const FV &testObject, const typename Traits< FV >::ModelType &model) const
classify the given testObject using the model
void setProgressReporter(ProgressReporter *pr)
set a progress reporter object.
void saveClassificationDetails(const ModelType &, const DetailedResultType &, STDATA &) const
save classification details.
void train(const SVM_Problem< FV > &problem, typename Traits< FV >::ModelType &model) const
train SVM with given Feature Vectors.
void train(const GroupedTrainingData< FV > &trainData, typename Traits< FV >::ModelType &model) const
train SVM with given Feature Vectors.
void retrainWithLeftOutVectors(const GroupedTrainingData< FV > &trainData, const typename Traits< FV >::ModelType &fullModel, const std::vector< char > &leaveOutFlagsByUID, typename Traits< FV >::ModelType &resultingModel) const
calls the retrainWithLeftOutVectors() for each two-class model, only if the model is affected by the ...
void train(ForwardIter FV_begin, const ForwardIter &FV_end, typename Traits< typename Accessor::template Traits< ForwardIter >::value_type >::ModelType &model, Accessor accessor) const
same as train(), but you can specify an Accessor for accessing the elements of your container...
Model_MC_OneVsOne< typename SVM::template Traits< FV >::ModelType > ModelType
Ensure that TESTCLASS provides a setProgressReporter() method.
static const char * description()
unsigned int predictClassIndex(const FV &testObject, const typename Traits< FV >::ModelType &model, ResultMatrix &resultMatrix) const
classify the given testObject using the model