blob: 136d73b6bd5df90300f3dc751ef76a54e6b9e008 [file] [log] [blame]
/* ----------------------------------------------------------------------- *//**
*
* @file linear_svm.hpp
*
*//* ----------------------------------------------------------------------- */
#ifndef MADLIB_MODULES_CONVEX_TASK_LINEAR_SVM_HPP_
#define MADLIB_MODULES_CONVEX_TASK_LINEAR_SVM_HPP_
namespace madlib {
namespace modules {
namespace convex {
// Use Eigen
using namespace madlib::dbal::eigen_integration;
template <class Model, class Tuple>
class LinearSVM {
public:
typedef Model model_type;
typedef Tuple tuple_type;
typedef typename Tuple::independent_variables_type
independent_variables_type;
typedef typename Tuple::dependent_variable_type dependent_variable_type;
static double epsilon;
static bool is_svc;
static void gradient(
const model_type &model,
const independent_variables_type &x,
const dependent_variable_type &y,
model_type &gradient);
static void gradientInPlace(
model_type &model,
const independent_variables_type &x,
const dependent_variable_type &y,
const double &stepsize);
static double loss(
const model_type &model,
const independent_variables_type &x,
const dependent_variable_type &y);
static dependent_variable_type predict(
const model_type &model,
const independent_variables_type &x);
};
template <class Model, class Tuple>
double LinearSVM<Model, Tuple >::epsilon = 0.;
template <class Model, class Tuple>
bool LinearSVM<Model, Tuple >::is_svc = false;
template <class Model, class Tuple>
void
LinearSVM<Model, Tuple>::gradient(
const model_type &model,
const independent_variables_type &x,
const dependent_variable_type &y,
model_type &gradient) {
double wx = dot(model, x);
if (is_svc) {
if (1 - wx * y > 0) {
double c = -y; // minus for "-loglik"
gradient += c * x;
}
}
else {
double wx_y = wx - y;
double c = wx_y > 0 ? 1. : -1.;
if (c*wx_y - epsilon > 0.)
gradient += c * x;
}
}
template <class Model, class Tuple>
void
LinearSVM<Model, Tuple>::gradientInPlace(
model_type &model,
const independent_variables_type &x,
const dependent_variable_type &y,
const double &stepsize) {
double wx = dot(model, x);
if (is_svc) {
if (1. - wx * y > 0.) {
double c = -y; // minus for "-loglik"
model -= stepsize * c * x;
}
}
else {
double wx_y = wx - y;
double c = wx_y > 0 ? 1. : -1.;
if (c*wx_y - epsilon > 0.)
model -= stepsize * c * x;
}
}
template <class Model, class Tuple>
double
LinearSVM<Model, Tuple>::loss(
const model_type &model,
const independent_variables_type &x,
const dependent_variable_type &y) {
double wx = dot(model, x);
double distance = 0.;
if (is_svc) {
distance = 1. - wx * y;
}
else {
distance = fabs(wx - y) - epsilon;
}
return distance > 0. ? distance : 0.;
}
template <class Model, class Tuple>
typename Tuple::dependent_variable_type
LinearSVM<Model, Tuple>::predict(
const model_type &model,
const independent_variables_type &x) {
return dot(model, x);
}
} // namespace convex
} // namespace modules
} // namespace madlib
#endif