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 * <https://shark-ml.github.io/Shark/>
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
42namespace 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/// \ingroup supervised_trainer
54template<class InputType>
55class KernelMeanClassifier : public AbstractWeightedTrainer<KernelClassifier<InputType>, unsigned int>{
56public:
58
59 std::string name() const
60 { return "KernelMeanClassifier"; }
61
64 RealVector normalization = classWeight(dataset);
65 std::size_t patterns = dataset.numberOfElements();
66 std::size_t numClasses = normalization.size();
67 SHARK_RUNTIME_CHECK(min(normalization) > 0, "One class has no member" );
68
69 // compute coefficients and offset term
70 RealVector offset(numClasses,0.0);
71 RealMatrix alpha(patterns, numClasses,0.0);
72
73 //todo: slow implementation without batch processing!
74 std::size_t i = 0;
75 for(auto const& element: dataset.elements()){
76
77 unsigned int y = element.data.label;
78 double w = element.weight;
79
80 // compute and set coefficients
81 alpha(i,y) = w / normalization(y);
82 ++i;
83 // compute values to calculate offset
84 for(auto element2: dataset.elements()){
85 if (element2.data.label != y)
86 continue;
87 //todo: fast implementation should create batches of same class elements and process them!
88 offset(y) += w * element2.weight * mpe_kernel->eval(element.data.input, element2.data.input);
89 }
90 }
91 noalias(offset) /= sqr(normalization);
92
93 if(numClasses == 2){
94 model.decisionFunction().setStructure(mpe_kernel,dataset.inputs(),true);
95 noalias(column(model.decisionFunction().alpha(),0)) = column(alpha,1) - column(alpha,0);
96 model.decisionFunction().offset()(0) = (offset(0) - offset(1))/2;
97 }else{
98 model.decisionFunction().setStructure(mpe_kernel,dataset.inputs(),true, numClasses);
99 noalias(model.decisionFunction().alpha()) = alpha;
100 noalias(model.decisionFunction().offset()) = -offset/2;
101 }
102 }
103
105};
106
107
108}
109#endif