36 class SupportVectorMachine :
public MelonModel<T> {
38 std::shared_ptr<const SvmData>
_data;
39 std::unique_ptr<kernel::StationaryKernel<double, T>>
_kernel;
64 T
_calculate_prediction(std::vector<T> input, std::vector<T> internalVariables,
const bool fullSpace, std::vector<T>& constraints);
119 void get_fullspace_variables(
size_t& variableNumber, std::vector<std::string>& variableNames, std::vector<std::pair<double, double>>& variableBounds);
156 class SupportVectorRegression :
public SupportVectorMachine<T> {
197 _data = std::dynamic_pointer_cast<const SvmData>(modelData);
198 if (_data ==
nullptr) {
199 throw(
MelonException(
" Error while loading support vector machine: Incorrect type of passed data object. The data object must be of type SvmData."));
212 switch (_data->kernelFunction) {
214 _kernel = std::unique_ptr<kernel::KernelRBF<double, T>>(
new kernel::KernelRBF<double, T>(_data->kernelParameters.front()));
224 return _calculate_prediction(input, internalVariables,
true, constraints);
226 catch (
const std::exception& e) {
227 throw(
MelonException(
" Encountered a fatal error while evaluating support vector machine. Terminating.", e));
230 throw(
MelonException(
" Encountered a fatal error while evaluating support vector machine. Terminating."));
240 std::vector<T> dummyInternalVariables;
241 std::vector<T> dummyConstraints;
243 return _calculate_prediction(input, dummyInternalVariables,
false, dummyConstraints);
245 catch (
const std::exception& e) {
246 throw(
MelonException(
" Encountered a fatal error while evaluating support vector machine. Terminating.", e));
249 throw(
MelonException(
" Encountered a fatal error while evaluating support vector machine. Terminating."));
263 if (input.size() != _data->supportVectors.at(0).size()) {
264 throw MelonException(
" Error while calculating svm prediction: Incorrect input dimension. In reduced space mode evaluation the size of the variables vector must be equal to the input dimension of the svm.");
267 size_t variablesSize = get_number_of_full_space_variables();
268 if (internalVariables.size() != variablesSize) {
269 throw MelonException(
" Error while calculating svm prediction: Incorrect input dimension. In full space mode evaluation the size of the variables vector be equal to the number of internal variables.");
273 auto variableIterator = internalVariables.begin();
274 if (this->_modelLoaded) {
280 std::vector<T> scaledInput = _inputScaler->scale(input);
282 this->_set_constraints(constraints, scaledInput, variableIterator);
289 std::vector<T> kernelValues;
290 kernelValues.reserve(_data->supportVectors.size());
291 for (
auto& iSupportVector: _data->supportVectors) {
292 T distance = _kernel->calculate_distance(iSupportVector, scaledInput);
294 this->_set_constraints(constraints, distance, variableIterator);
297 T kernelValue = _kernel->evaluate_kernel(distance);
299 this->_set_constraints(constraints, kernelValue, variableIterator);
302 kernelValues.push_back(kernelValue);
309 T result = _decision_function(kernelValues);
311 this->_set_constraints(constraints, result, variableIterator);
318 T output = _outputScaler->descale({ result }).front();
320 this->_set_constraints(constraints, output, variableIterator);
326 throw MelonException{
" Error while calculating support vector machine prediction: No model was loaded yet." };
335 return dot_product(this->_data->dualCoefficients, input) + this->_data->rho;
343 return dot_product(this->_data->dualCoefficients, input) + this->_data->rho;
351 size_t variableNumber;
352 std::vector<std::string> variableNames;
353 std::vector<std::pair<double, double>> variableBounds;
354 get_fullspace_variables(variableNumber, variableNames, variableBounds);
355 return variableNumber;
365 variableNames.clear();
366 variableBounds.clear();
370 auto n = this->_data->supportVectors.at(0).size();
371 auto lbs = std::vector<double>(n, 1e6);
372 auto ubs = std::vector<double>(n, -1e6);
373 for (
auto iSupportVector : this->_data->supportVectors) {
374 for (
int i = 0; i < iSupportVector.size(); i++) {
375 auto xi = iSupportVector[i];
376 if (xi < lbs[i]) lbs[i] = xi;
377 if (xi > ubs[i]) ubs[i] = xi;
380 double maxSquaredDistance = 0;
381 for (
size_t i = 0; i < lbs.size(); i++) {
382 maxSquaredDistance = maxSquaredDistance + (ubs[i] - lbs[i])*(ubs[i] - lbs[i]);
387 variableNumber += 2 * _data->dualCoefficients.size();
388 for (
int i = 0; i < _data->dualCoefficients.size(); i++) {
389 variableNames.push_back(
"squared_distance_" + std::to_string(i));
390 variableNames.push_back(
"kernel_value_" + std::to_string(i));
391 variableBounds.push_back(std::make_pair(0., maxSquaredDistance));
392 variableBounds.push_back(std::make_pair(0., 1.0));
395 double sum_alpha = 0;
396 for (
auto alpha : this->_data->dualCoefficients) {
397 sum_alpha = sum_alpha + alpha;
400 variableNames.push_back(
"prediction");
401 if (this->_data->kernelFunction ==
RBF) {
402 variableBounds.push_back(std::make_pair(0, (sum_alpha - this->_data->rho)));
405 variableBounds.push_back(std::make_pair(-1e6, 1e6));