RadiusMarginQuotient.h
Go to the documentation of this file.
1/*!
2 *
3 *
4 * \brief Radius Margin Quotient for SVM model selection
5 *
6 *
7 *
8 * \author T.Glasmachers, O.Krause
9 * \date 2012
10 *
11 *
12 * \par Copyright 1995-2017 Shark Development Team
13 *
14 * <BR><HR>
15 * This file is part of Shark.
16 * <https://shark-ml.github.io/Shark/>
17 *
18 * Shark is free software: you can redistribute it and/or modify
19 * it under the terms of the GNU Lesser General Public License as published
20 * by the Free Software Foundation, either version 3 of the License, or
21 * (at your option) any later version.
22 *
23 * Shark is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU Lesser General Public License for more details.
27 *
28 * You should have received a copy of the GNU Lesser General Public License
29 * along with Shark. If not, see <http://www.gnu.org/licenses/>.
30 *
31 */
32#ifndef SHARK_OBJECTIVEFUNCTIONS_RADIUSMARGINQUOTIENT_H
33#define SHARK_OBJECTIVEFUNCTIONS_RADIUSMARGINQUOTIENT_H
34
35
41
42namespace shark {
43
44
45///
46/// \brief radius margin quotions for binary SVMs
47///
48/// \par
49/// The RadiusMarginQuotient is the quotient \f$ R^2 / \rho^2 \f$
50/// of the radius R of the smallest sphere containing the
51/// training data and the margin \f$\rho\f$ of a binary hard margin
52/// support vector machine. Both distances depend on the
53/// kernel function, and thus on its parameters.
54/// The radius margin quotient is a common objective
55/// function for the adaptation of the kernel parameters
56/// of a binary hard-margin SVM.
57/// \ingroup kerneloptimization
58template<class InputType, class CacheType = float>
59class RadiusMarginQuotient : public AbstractObjectiveFunction< RealVector, double >
60{
61public:
62 typedef CacheType QpFloatType;
63
66
69
70 /// \brief Constructor.
78
79
80 /// \brief From INameable: return the class name.
81 std::string name() const
82 { return "RadiusMarginQuotient"; }
83
84 std::size_t numberOfVariables()const{
86 }
87
88 /// \brief Evaluate the radius margin quotient.
89 ///
90 /// \par
91 /// The parameters are passed into the kernel, and the
92 /// radius-margin quotient is computed w.r.t. the
93 /// kernel-induced metric.
94 double eval(SearchPointType const& parameters) const{
95 SIZE_CHECK(parameters.size() == mep_kernel->numberOfParameters());
96 SHARK_RUNTIME_CHECK(! m_dataset.empty(), "[RadiusMarginQuotient::eval] call setDataset first");
98
99
100 mep_kernel->setParameterVector(parameters);
101
102 Result result = computeRadiusMargin();
103
104 return result.w2 * result.R2;
105 }
106
107 /// \brief Evaluate the radius margin quotient and its first derivative.
108 ///
109 /// \par
110 /// The parameters are passed into the kernel, and the
111 /// radius-margin quotient and its derivative are computed
112 /// w.r.t. the kernel-induced metric.
113 double evalDerivative(SearchPointType const& parameters, FirstOrderDerivative& derivative) const{
114 SHARK_RUNTIME_CHECK(! m_dataset.empty(), "[RadiusMarginQuotient::evalDerivative] call setDataset first");
115 SIZE_CHECK(parameters.size() == mep_kernel->numberOfParameters());
117
118 mep_kernel->setParameterVector(parameters);
119
120 Result result = computeRadiusMargin();
121
124 result.w2*(to_diagonal(result.beta)-outer_prod(result.beta,result.beta))
125 -result.R2*outer_prod(result.alpha,result.alpha)
126 );
127
128
129 return result.w2 * result.R2;
130 }
131
132protected:
133 struct Result{
134 RealVector alpha;
135 RealVector beta;
136 double w2;
137 double R2;
138 };
139
141 std::size_t ell = m_dataset.numberOfElements();
142
144 Result result;
145 {
147 CachedMatrixType cache(&km);
148 typedef CSVMProblem<CachedMatrixType> SVMProblemType;
149 typedef SvmShrinkingProblem<SVMProblemType> ProblemType;
150
151 SVMProblemType svmProblem(cache,m_dataset.labels(),1e100);
152 ProblemType problem(svmProblem);
153
154 QpSolver< ProblemType> solver(problem);
156 solver.solve(stop, &prop);
157 result.w2 = 2.0 * prop.value;
158 result.alpha = problem.getUnpermutedAlpha();
159 }
160 {
161 // create and solve the radius problem (also a quadratic program)
163 CachedMatrixType cache(&km);
164 typedef BoxedSVMProblem<CachedMatrixType> SVMProblemType;
165 typedef SvmShrinkingProblem<SVMProblemType> ProblemType;
166
167 // Setup the problem
168 RealVector linear(ell);
169 for (std::size_t i=0; i<ell; i++){
170 linear(i) = 0.5 * km(i, i);
171 }
172 SVMProblemType svmProblem(cache,linear,0.0,1.0);
173 ProblemType problem(svmProblem);
174
175 //solve it
176 QpSolver< ProblemType> solver(problem);
178 solver.solve(stop, &prop);
179 result.R2 = 2.0 * prop.value;
180 result.beta = problem.getUnpermutedAlpha();
181 }
182 return result;
183 }
184
185 KernelType* mep_kernel; ///< underlying parameterized kernel object
186 DatasetType m_dataset; ///< labeled data for radius and (hard) margin computation
187
188};
189
190
191}
192#endif