/* ----------------------------------------------------------------------- *//** * * @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 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 double LinearSVM::epsilon = 0.; template bool LinearSVM::is_svc = false; template void LinearSVM::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 void LinearSVM::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 double LinearSVM::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 typename Tuple::dependent_variable_type LinearSVM::predict( const model_type &model, const independent_variables_type &x) { return dot(model, x); } } // namespace convex } // namespace modules } // namespace madlib #endif