This function outputs the name of labels into an array called label.
For a regression model, label is unchanged.
+- Function: double get_decfun_coef(const struct model *model_, int feat_idx,
+ int label_idx);
+
+ This function gives the coefficient for the feature with feature index =
+ feat_idx and the class with label index = label_idx. Note that feat_idx
+ starts from 1, while label_idx starts from 0. If label_idx is not in the
+ valid range (0 to nr_class-1), then a NaN will be returned; and if feat_idx
+ is not in the valid range (1 to nr_feature), then a zero value will be
+ returned. For regression models, label_idx is ignored.
+
+- Function: double get_decfun_bias(const struct model *model_, int label_idx);
+
+ This function gives the bias term corresponding to the class with the
+ label_idx. For regression models, label_idx is ignored.
+
- Function: const char *check_parameter(const struct problem *prob,
const struct parameter *param);
train() and cross_validation(). It returns NULL if the
parameters are feasible, otherwise an error message is returned.
+- Function: int check_probability_model(const struct model *model);
+
+ This function returns 1 if the model supports probability output;
+ otherwise, it returns 0.
+
+- Function: int check_regression_model(const struct model *model);
+
+ This function returns 1 if the model is a regression model; otherwise
+ it returns 0.
+
- Function: int save_model(const char *model_file_name,
const struct model *model_);
model_->param = *param;
model_->bias = prob->bias;
- if(param->solver_type == L2R_L2LOSS_SVR ||
- param->solver_type == L2R_L1LOSS_SVR_DUAL ||
- param->solver_type == L2R_L2LOSS_SVR_DUAL)
+ if(check_regression_model(model_))
{
model_->w = Malloc(double, w_size);
model_->nr_class = 2;
if(nr_class==2)
{
- if(model_->param.solver_type == L2R_L2LOSS_SVR ||
- model_->param.solver_type == L2R_L1LOSS_SVR_DUAL ||
- model_->param.solver_type == L2R_L2LOSS_SVR_DUAL)
+ if(check_regression_model(model_))
return dec_values[0];
else
return (dec_values[0]>0)?model_->label[0]:model_->label[1];
label[i] = model_->label[i];
}
+// use inline here for better performance (around 20% faster than the non-inline one)
+static inline double get_w_value(const struct model *model_, int idx, int label_idx)
+{
+ int nr_class = model_->nr_class;
+ int solver_type = model_->param.solver_type;
+ const double *w = model_->w;
+
+ if(!check_regression_model(model_) && (label_idx < 0 || label_idx >= nr_class))
+ {
+ const double nan = 0.0/0.0;
+ return nan;
+ }
+ if(idx < 0 || idx > model_->nr_feature)
+ return 0;
+ if(check_regression_model(model_))
+ return w[idx];
+ else
+ {
+ if(nr_class == 2 && solver_type != MCSVM_CS)
+ {
+ if(label_idx == 0)
+ return w[idx];
+ else
+ return -w[idx];
+ }
+ else
+ return w[idx*nr_class+label_idx];
+ }
+}
+
+// feat_idx: starting from 1 to nr_feature
+// label_idx: starting from 0 to nr_class-1 for classification models;
+// for regression models, label_idx is ignored.
+double get_decfun_coef(const struct model *model_, int feat_idx, int label_idx)
+{
+ if(feat_idx > model_->nr_feature)
+ return 0;
+ return get_w_value(model_, feat_idx-1, label_idx);
+}
+
+double get_decfun_bias(const struct model *model_, int label_idx)
+{
+ int bias_idx = model_->nr_feature;
+ double bias = model_->bias;
+ if(bias <= 0)
+ return 0;
+ else
+ return bias*get_w_value(model_, bias_idx, label_idx);
+}
+
void free_model_content(struct model *model_ptr)
{
if(model_ptr->w != NULL)
model_->param.solver_type==L1R_LR);
}
+int check_regression_model(const struct model *model_)
+{
+ return (model_->param.solver_type==L2R_L2LOSS_SVR ||
+ model_->param.solver_type==L2R_L1LOSS_SVR_DUAL ||
+ model_->param.solver_type==L2R_L2LOSS_SVR_DUAL);
+}
+
void set_print_string_function(void (*print_func)(const char*))
{
if (print_func == NULL)
int get_nr_feature(const struct model *model_);
int get_nr_class(const struct model *model_);
void get_labels(const struct model *model_, int* label);
+double get_decfun_coef(const struct model *model_, int feat_idx, int label_idx);
+double get_decfun_bias(const struct model *model_, int label_idx);
void free_model_content(struct model *model_ptr);
void free_and_destroy_model(struct model **model_ptr_ptr);
const char *check_parameter(const struct problem *prob, const struct parameter *param);
int check_probability_model(const struct model *model);
+int check_regression_model(const struct model *model);
void set_print_string_function(void (*print_func) (const char*));
#ifdef __cplusplus
++total;
}
- if(model_->param.solver_type==L2R_L2LOSS_SVR ||
- model_->param.solver_type==L2R_L1LOSS_SVR_DUAL ||
- model_->param.solver_type==L2R_L2LOSS_SVR_DUAL)
+ if(check_regression_model(model_))
{
info("Mean squared error = %g (regression)\n",error/total);
info("Squared correlation coefficient = %g (regression)\n",
sumpt += predict_label*target_label;
++total;
}
- if(model_->param.solver_type==L2R_L2LOSS_SVR ||
- model_->param.solver_type==L2R_L1LOSS_SVR_DUAL ||
- model_->param.solver_type==L2R_L2LOSS_SVR_DUAL)
+ if(check_regression_model(model_))
{
info("Mean squared error = %g (regression)\n",error/total);
info("Squared correlation coefficient = %g (regression)\n",
>>> nr_class = model_.get_nr_class()
>>> class_labels = model_.get_labels()
>>> is_prob_model = model_.is_probability_model()
+ >>> is_regression_model = model_.is_regression_model()
+
+ The decision function is W*x + b, where
+ W is an nr_class-by-nr_feature matrix, and
+ b is a vector of size nr_class.
+ To access W_kj (i.e., coefficient for the k-th class and the j-th feature)
+ and b_k (i.e., bias for the k-th class), use the following functions.
+
+ >>> W_kj = model_.get_decfun_coef(feat_idx=j, label_idx=k)
+ >>> b_k = model_.get_decfun_bias(label_idx=k)
+
+ We also provide a function to extract w_k (i.e., the k-th row of W) and
+ b_k directly as follows.
+
+ >>> [w_k, b_k] = model_.get_decfun(label_idx=k)
+
+ Note that w_k is a Python list of length nr_feature, which means that
+ w_k[0] = W_k1.
+ For regression models, W is just a vector of length nr_feature. Either
+ set label_idx=0 or omit the label_idx parameter to access the coefficients.
+
+ >>> W_j = model_.get_decfun_coef(feat_idx=j)
+ >>> b = model_.get_decfun_bias()
+ >>> [W, b] = model_.get_decfun()
+
+ Note that in get_decfun_coef, get_decfun_bias, and get_decfun, feat_idx
+ starts from 1, while label_idx starts from 0. If label_idx is not in the
+ valid range (0 to nr_class-1), then a NaN will be returned; and if feat_idx
+ is not in the valid range (1 to nr_feature), then a zero value will be
+ returned. For regression models, label_idx is ignored.
Utility Functions
=================
liblinear.get_labels(self, labels)
return labels[:nr_class]
+ def get_decfun_coef(self, feat_idx, label_idx=0):
+ return liblinear.get_decfun_coef(self, feat_idx, label_idx)
+
+ def get_decfun_bias(self, label_idx=0):
+ return liblinear.get_decfun_bias(self, label_idx)
+
+ def get_decfun(self, label_idx=0):
+ w = [liblinear.get_decfun_coef(self, feat_idx, label_idx) for feat_idx in range(1, self.nr_feature+1)]
+ b = liblinear.get_decfun_bias(self, label_idx)
+ return (w, b)
+
def is_probability_model(self):
return (liblinear.check_probability_model(self) == 1)
+ def is_regression_model(self):
+ return (liblinear.check_regression_model(self) == 1)
+
def toPyModel(model_ptr):
"""
toPyModel(model_ptr) -> model
fillprototype(liblinear.get_nr_feature, c_int, [POINTER(model)])
fillprototype(liblinear.get_nr_class, c_int, [POINTER(model)])
fillprototype(liblinear.get_labels, None, [POINTER(model), POINTER(c_int)])
+fillprototype(liblinear.get_decfun_coef, c_double, [POINTER(model), c_int, c_int])
+fillprototype(liblinear.get_decfun_bias, c_double, [POINTER(model), c_int])
fillprototype(liblinear.free_model_content, None, [POINTER(model)])
fillprototype(liblinear.free_and_destroy_model, None, [POINTER(POINTER(model))])
fillprototype(liblinear.destroy_param, None, [POINTER(parameter)])
fillprototype(liblinear.check_parameter, c_char_p, [POINTER(problem), POINTER(parameter)])
fillprototype(liblinear.check_probability_model, c_int, [POINTER(model)])
+fillprototype(liblinear.check_regression_model, c_int, [POINTER(model)])
fillprototype(liblinear.set_print_string_function, None, [CFUNCTYPE(None, c_char_p)])
import os, sys
sys.path = [os.path.dirname(os.path.abspath(__file__))] + sys.path
from liblinear import *
+from liblinear import __all__ as liblinear_all
from ctypes import c_double
__all__ = ['svm_read_problem', 'load_model', 'save_model', 'evaluations',
- 'train', 'predict']
+ 'train', 'predict'] + liblinear_all
def svm_read_problem(data_file_name):
y = [0] * len(x)
ACC, MSE, SCC = evaluations(y, pred_labels)
l = len(y)
- if solver_type in [L2R_L2LOSS_SVR, L2R_L2LOSS_SVR_DUAL, L2R_L1LOSS_SVR_DUAL]:
+ if m.is_regression_model():
info("Mean squared error = %g (regression)" % MSE)
info("Squared correlation coefficient = %g (regression)" % SCC)
else: