KernelMeanClassifier.h
Go to the documentation of this file.
1 //===========================================================================
2 /*!
3  *
4  *
5  * \brief KernelMeanClassifier
6  *
7  *
8  *
9  * \author T. Glasmachers, C. Igel
10  * \date 2010, 2011
11  *
12  *
13  * \par Copyright 1995-2017 Shark Development Team
14  *
15  * <BR><HR>
16  * This file is part of Shark.
17  * <http://shark-ml.org/>
18  *
19  * Shark is free software: you can redistribute it and/or modify
20  * it under the terms of the GNU Lesser General Public License as published
21  * by the Free Software Foundation, either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * Shark is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU Lesser General Public License for more details.
28  *
29  * You should have received a copy of the GNU Lesser General Public License
30  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
33 //===========================================================================
34 #ifndef SHARK_ALGORITHMS_TRAINERS_KERNELMEAN_H
35 #define SHARK_ALGORITHMS_TRAINERS_KERNELMEAN_H
36 
37 
40 #include <shark/Data/Dataset.h>
41 
42 namespace shark {
43 
44 /// \brief Kernelized mean-classifier
45 ///
46 /// Computes the mean of the training data in feature space for each
47 /// class and assigns a new data point to the class with the nearest
48 /// mean. The trainer supports multi-class and weighted data
49 ///
50 /// The resulting classifier is a kernel expansion as assigning the label
51 /// with minimum distance (or maximum negative distance by convention for classifiers)
52 /// \f[ max -1/2 ||\phi(x) - m_i||^2 = <\phi(x), m_i> - 1/2<m_i,m_i> \f]
53 template<class InputType>
54 class KernelMeanClassifier : public AbstractWeightedTrainer<KernelClassifier<InputType>, unsigned int>{
55 public:
57 
58  std::string name() const
59  { return "KernelMeanClassifier"; }
60 
63  RealVector normalization = classWeight(dataset);
64  std::size_t patterns = dataset.numberOfElements();
65  std::size_t numClasses = normalization.size();
66  SHARK_RUNTIME_CHECK(min(normalization) > 0, "One class has no member" );
67 
68  // compute coefficients and offset term
69  RealVector offset(numClasses,0.0);
70  RealMatrix alpha(patterns, numClasses,0.0);
71 
72  //todo: slow implementation without batch processing!
73  std::size_t i = 0;
74  for(auto const& element: dataset.elements()){
75 
76  unsigned int y = element.data.label;
77  double w = element.weight;
78 
79  // compute and set coefficients
80  alpha(i,y) = w / normalization(y);
81  ++i;
82  // compute values to calculate offset
83  for(auto element2: dataset.elements()){
84  if (element2.data.label != y)
85  continue;
86  //todo: fast implementation should create batches of same class elements and process them!
87  offset(y) += w * element2.weight * mpe_kernel->eval(element.data.input, element2.data.input);
88  }
89  }
90  noalias(offset) /= sqr(normalization);
91 
92  if(numClasses == 2){
93  model.decisionFunction().setStructure(mpe_kernel,dataset.inputs(),true);
94  noalias(column(model.decisionFunction().alpha(),0)) = column(alpha,1) - column(alpha,0);
95  model.decisionFunction().offset()(0) = (offset(0) - offset(1))/2;
96  }else{
97  model.decisionFunction().setStructure(mpe_kernel,dataset.inputs(),true, numClasses);
98  noalias(model.decisionFunction().alpha()) = alpha;
99  noalias(model.decisionFunction().offset()) = -offset/2;
100  }
101  }
102 
104 };
105 
106 
107 }
108 #endif