Algorithm-LibLinear
view release on metacpan or search on metacpan
src/liblinear/linear.cpp view on Meta::CPAN
break;
}
case L1R_LR:
{
problem prob_col;
feature_node *x_space = NULL;
transpose(prob, &x_space ,&prob_col);
solve_l1r_lr(&prob_col, param, w, Cp, Cn, primal_solver_tol);
delete [] prob_col.y;
delete [] prob_col.x;
delete [] x_space;
break;
}
case L2R_LR_DUAL:
{
iter = solve_l2r_lr_dual(prob, param, w, Cp, Cn, dual_solver_max_iter);
if(iter >= dual_solver_max_iter)
{
info("\nWARNING: reaching max number of iterations\nSwitching to use -s 0\n\n");
// primal_solver_tol obtained from eps for dual may be too loose
primal_solver_tol *= 0.1;
l2r_lr_fun fun_obj(prob, param, C);
NEWTON newton_obj(&fun_obj, primal_solver_tol);
newton_obj.set_print_string(liblinear_print_string);
newton_obj.newton(w);
}
break;
}
case L2R_L2LOSS_SVR:
{
l2r_l2_svr_fun fun_obj(prob, param, C);
NEWTON newton_obj(&fun_obj, primal_solver_tol);
newton_obj.set_print_string(liblinear_print_string);
newton_obj.newton(w);
break;
}
case L2R_L1LOSS_SVR_DUAL:
{
iter = solve_l2r_l1l2_svr(prob, param, w, dual_solver_max_iter);
if(iter >= dual_solver_max_iter)
info("\nWARNING: reaching max number of iterations\nUsing -s 11 may be faster (also see FAQ)\n\n");
break;
}
case L2R_L2LOSS_SVR_DUAL:
{
iter = solve_l2r_l1l2_svr(prob, param, w, dual_solver_max_iter);
if(iter >= dual_solver_max_iter)
{
info("\nWARNING: reaching max number of iterations\nSwitching to use -s 11\n\n");
// primal_solver_tol obtained from eps for dual may be too loose
primal_solver_tol *= 0.001;
l2r_l2_svr_fun fun_obj(prob, param, C);
NEWTON newton_obj(&fun_obj, primal_solver_tol);
newton_obj.set_print_string(liblinear_print_string);
newton_obj.newton(w);
}
break;
}
default:
fprintf(stderr, "ERROR: unknown solver_type\n");
break;
}
delete[] C;
}
// Calculate the initial C for parameter selection
static double calc_start_C(const problem *prob, const parameter *param)
{
int i;
double xTx, max_xTx;
max_xTx = 0;
for(i=0; i<prob->l; i++)
{
xTx = 0;
feature_node *xi=prob->x[i];
while(xi->index != -1)
{
double val = xi->value;
xTx += val*val;
xi++;
}
if(xTx > max_xTx)
max_xTx = xTx;
}
double min_C = 1.0;
if(param->solver_type == L2R_LR)
min_C = 1.0 / (prob->l * max_xTx);
else if(param->solver_type == L2R_L2LOSS_SVC)
min_C = 1.0 / (2 * prob->l * max_xTx);
else if(param->solver_type == L2R_L2LOSS_SVR)
{
double sum_y, loss, y_abs;
double delta2 = 0.1;
sum_y = 0, loss = 0;
for(i=0; i<prob->l; i++)
{
y_abs = fabs(prob->y[i]);
sum_y += y_abs;
loss += max(y_abs - param->p, 0.0) * max(y_abs - param->p, 0.0);
}
if(loss > 0)
min_C = delta2 * delta2 * loss / (8 * sum_y * sum_y * max_xTx);
else
min_C = INF;
}
return pow( 2, floor(log(min_C) / log(2.0)) );
}
static double calc_max_p(const problem *prob)
{
int i;
double max_p = 0.0;
for(i = 0; i < prob->l; i++)
max_p = max(max_p, fabs(prob->y[i]));
return max_p;
}
src/liblinear/linear.cpp view on Meta::CPAN
int l = prob->l;
int n = prob->n;
int w_size = prob->n;
model *model_ = Malloc(model,1);
if(prob->bias>=0)
model_->nr_feature=n-1;
else
model_->nr_feature=n;
model_->param = *param;
model_->bias = prob->bias;
if(check_regression_model(model_))
{
model_->w = Malloc(double, w_size);
if(param->init_sol != NULL)
for(i=0;i<w_size;i++)
model_->w[i] = param->init_sol[i];
else
for(i=0;i<w_size;i++)
model_->w[i] = 0;
model_->nr_class = 2;
model_->label = NULL;
train_one(prob, param, model_->w, 0, 0);
}
else if(check_oneclass_model(model_))
{
model_->w = Malloc(double, w_size);
model_->nr_class = 2;
model_->label = NULL;
solve_oneclass_svm(prob, param, model_->w, &(model_->rho));
}
else
{
int nr_class;
int *label = NULL;
int *start = NULL;
int *count = NULL;
int *perm = Malloc(int,l);
// group training data of the same class
group_classes(prob,&nr_class,&label,&start,&count,perm);
model_->nr_class=nr_class;
model_->label = Malloc(int,nr_class);
for(i=0;i<nr_class;i++)
model_->label[i] = label[i];
// calculate weighted C
double *weighted_C = Malloc(double, nr_class);
for(i=0;i<nr_class;i++)
weighted_C[i] = param->C;
for(i=0;i<param->nr_weight;i++)
{
for(j=0;j<nr_class;j++)
if(param->weight_label[i] == label[j])
break;
if(j == nr_class)
fprintf(stderr,"WARNING: class label %d specified in weight is not found\n", param->weight_label[i]);
else
weighted_C[j] *= param->weight[i];
}
// constructing the subproblem
feature_node **x = Malloc(feature_node *,l);
for(i=0;i<l;i++)
x[i] = prob->x[perm[i]];
int k;
problem sub_prob;
sub_prob.l = l;
sub_prob.n = n;
sub_prob.x = Malloc(feature_node *,sub_prob.l);
sub_prob.y = Malloc(double,sub_prob.l);
for(k=0; k<sub_prob.l; k++)
sub_prob.x[k] = x[k];
// multi-class svm by Crammer and Singer
if(param->solver_type == MCSVM_CS)
{
model_->w=Malloc(double, n*nr_class);
for(i=0;i<nr_class;i++)
for(j=start[i];j<start[i]+count[i];j++)
sub_prob.y[j] = i;
Solver_MCSVM_CS Solver(&sub_prob, nr_class, weighted_C, param->eps);
Solver.Solve(model_->w);
}
else
{
if(nr_class == 2)
{
model_->w=Malloc(double, w_size);
int e0 = start[0]+count[0];
k=0;
for(; k<e0; k++)
sub_prob.y[k] = +1;
for(; k<sub_prob.l; k++)
sub_prob.y[k] = -1;
if(param->init_sol != NULL)
for(i=0;i<w_size;i++)
model_->w[i] = param->init_sol[i];
else
for(i=0;i<w_size;i++)
model_->w[i] = 0;
train_one(&sub_prob, param, model_->w, weighted_C[0], weighted_C[1]);
}
else
{
model_->w=Malloc(double, w_size*nr_class);
double *w=Malloc(double, w_size);
for(i=0;i<nr_class;i++)
{
int si = start[i];
int ei = si+count[i];
k=0;
for(; k<si; k++)
sub_prob.y[k] = -1;
for(; k<ei; k++)
sub_prob.y[k] = +1;
for(; k<sub_prob.l; k++)
sub_prob.y[k] = -1;
if(param->init_sol != NULL)
for(j=0;j<w_size;j++)
w[j] = param->init_sol[j*nr_class+i];
else
for(j=0;j<w_size;j++)
w[j] = 0;
train_one(&sub_prob, param, w, weighted_C[i], param->C);
for(j=0;j<w_size;j++)
model_->w[j*nr_class+i] = w[j];
}
free(w);
}
}
free(x);
free(label);
free(start);
free(count);
free(perm);
free(sub_prob.x);
free(sub_prob.y);
free(weighted_C);
}
return model_;
}
void cross_validation(const problem *prob, const parameter *param, int nr_fold, double *target)
{
int i;
int *fold_start;
int l = prob->l;
int *perm = Malloc(int,l);
if (nr_fold > l)
{
nr_fold = l;
fprintf(stderr,"WARNING: # folds > # data. Will use # folds = # data instead (i.e., leave-one-out cross validation)\n");
}
fold_start = Malloc(int,nr_fold+1);
for(i=0;i<l;i++) perm[i]=i;
for(i=0;i<l;i++)
{
int j = i+rand()%(l-i);
swap(perm[i],perm[j]);
}
for(i=0;i<=nr_fold;i++)
fold_start[i]=i*l/nr_fold;
for(i=0;i<nr_fold;i++)
{
int begin = fold_start[i];
int end = fold_start[i+1];
int j,k;
struct problem subprob;
subprob.bias = prob->bias;
subprob.n = prob->n;
subprob.l = l-(end-begin);
subprob.x = Malloc(struct feature_node*,subprob.l);
subprob.y = Malloc(double,subprob.l);
k=0;
for(j=0;j<begin;j++)
{
subprob.x[k] = prob->x[perm[j]];
subprob.y[k] = prob->y[perm[j]];
++k;
}
for(j=end;j<l;j++)
{
subprob.x[k] = prob->x[perm[j]];
subprob.y[k] = prob->y[perm[j]];
++k;
}
struct model *submodel = train(&subprob,param);
for(j=begin;j<end;j++)
target[perm[j]] = predict(submodel,prob->x[perm[j]]);
free_and_destroy_model(&submodel);
free(subprob.x);
free(subprob.y);
}
free(fold_start);
free(perm);
}
void find_parameters(const problem *prob, const parameter *param, int nr_fold, double start_C, double start_p, double *best_C, double *best_p, double *best_score)
{
// prepare CV folds
int i;
int *fold_start;
int l = prob->l;
int *perm = Malloc(int, l);
struct problem *subprob = Malloc(problem,nr_fold);
if (nr_fold > l)
{
nr_fold = l;
fprintf(stderr,"WARNING: # folds > # data. Will use # folds = # data instead (i.e., leave-one-out cross validation)\n");
}
fold_start = Malloc(int,nr_fold+1);
for(i=0;i<l;i++) perm[i]=i;
for(i=0;i<l;i++)
{
int j = i+rand()%(l-i);
swap(perm[i],perm[j]);
}
for(i=0;i<=nr_fold;i++)
fold_start[i]=i*l/nr_fold;
for(i=0;i<nr_fold;i++)
{
int begin = fold_start[i];
int end = fold_start[i+1];
int j,k;
subprob[i].bias = prob->bias;
subprob[i].n = prob->n;
subprob[i].l = l-(end-begin);
subprob[i].x = Malloc(struct feature_node*,subprob[i].l);
subprob[i].y = Malloc(double,subprob[i].l);
k=0;
for(j=0;j<begin;j++)
{
subprob[i].x[k] = prob->x[perm[j]];
subprob[i].y[k] = prob->y[perm[j]];
++k;
}
for(j=end;j<l;j++)
{
subprob[i].x[k] = prob->x[perm[j]];
subprob[i].y[k] = prob->y[perm[j]];
++k;
}
}
struct parameter param_tmp = *param;
*best_p = -1;
if(param->solver_type == L2R_LR || param->solver_type == L2R_L2LOSS_SVC)
{
if(start_C <= 0)
start_C = calc_start_C(prob, ¶m_tmp);
double max_C = 1024;
start_C = min(start_C, max_C);
double best_C_tmp, best_score_tmp;
find_parameter_C(prob, ¶m_tmp, start_C, max_C, &best_C_tmp, &best_score_tmp, fold_start, perm, subprob, nr_fold);
*best_C = best_C_tmp;
*best_score = best_score_tmp;
}
else if(param->solver_type == L2R_L2LOSS_SVR)
{
double max_p = calc_max_p(prob);
int num_p_steps = 20;
double max_C = 1048576;
*best_score = INF;
src/liblinear/linear.cpp view on Meta::CPAN
if(fp==NULL) return -1;
char *old_locale = setlocale(LC_ALL, NULL);
if (old_locale)
{
old_locale = strdup(old_locale);
}
setlocale(LC_ALL, "C");
int nr_w;
if(model_->nr_class==2 && model_->param.solver_type != MCSVM_CS)
nr_w=1;
else
nr_w=model_->nr_class;
fprintf(fp, "solver_type %s\n", solver_type_table[param.solver_type]);
fprintf(fp, "nr_class %d\n", model_->nr_class);
if(model_->label)
{
fprintf(fp, "label");
for(i=0; i<model_->nr_class; i++)
fprintf(fp, " %d", model_->label[i]);
fprintf(fp, "\n");
}
fprintf(fp, "nr_feature %d\n", nr_feature);
fprintf(fp, "bias %.17g\n", model_->bias);
if(check_oneclass_model(model_))
fprintf(fp, "rho %.17g\n", model_->rho);
fprintf(fp, "w\n");
for(i=0; i<w_size; i++)
{
int j;
for(j=0; j<nr_w; j++)
fprintf(fp, "%.17g ", model_->w[i*nr_w+j]);
fprintf(fp, "\n");
}
setlocale(LC_ALL, old_locale);
free(old_locale);
if (ferror(fp) != 0 || fclose(fp) != 0) return -1;
else return 0;
}
//
// FSCANF helps to handle fscanf failures.
// Its do-while block avoids the ambiguity when
// if (...)
// FSCANF();
// is used
//
#define FSCANF(_stream, _format, _var)do\
{\
if (fscanf(_stream, _format, _var) != 1)\
{\
fprintf(stderr, "ERROR: fscanf failed to read the model\n");\
EXIT_LOAD_MODEL()\
}\
}while(0)
// EXIT_LOAD_MODEL should NOT end with a semicolon.
#define EXIT_LOAD_MODEL()\
{\
setlocale(LC_ALL, old_locale);\
free(model_->label);\
free(model_);\
free(old_locale);\
return NULL;\
}
struct model *load_model(const char *model_file_name)
{
FILE *fp = fopen(model_file_name,"r");
if(fp==NULL) return NULL;
int i;
int nr_feature;
int n;
int nr_class;
double bias;
double rho;
model *model_ = Malloc(model,1);
parameter& param = model_->param;
// parameters for training only won't be assigned, but arrays are assigned as NULL for safety
param.nr_weight = 0;
param.weight_label = NULL;
param.weight = NULL;
param.init_sol = NULL;
model_->label = NULL;
char *old_locale = setlocale(LC_ALL, NULL);
if (old_locale)
{
old_locale = strdup(old_locale);
}
setlocale(LC_ALL, "C");
char cmd[81];
while(1)
{
FSCANF(fp,"%80s",cmd);
if(strcmp(cmd,"solver_type")==0)
{
FSCANF(fp,"%80s",cmd);
int i;
for(i=0;solver_type_table[i];i++)
{
if(strcmp(solver_type_table[i],cmd)==0)
{
param.solver_type=i;
break;
}
}
if(solver_type_table[i] == NULL)
{
fprintf(stderr,"unknown solver type.\n");
EXIT_LOAD_MODEL()
}
}
else if(strcmp(cmd,"nr_class")==0)
{
FSCANF(fp,"%d",&nr_class);
model_->nr_class=nr_class;
}
else if(strcmp(cmd,"nr_feature")==0)
{
FSCANF(fp,"%d",&nr_feature);
model_->nr_feature=nr_feature;
}
else if(strcmp(cmd,"bias")==0)
{
FSCANF(fp,"%lf",&bias);
model_->bias=bias;
}
else if(strcmp(cmd,"rho")==0)
{
FSCANF(fp,"%lf",&rho);
model_->rho=rho;
}
else if(strcmp(cmd,"w")==0)
{
break;
}
else if(strcmp(cmd,"label")==0)
{
int nr_class = model_->nr_class;
model_->label = Malloc(int,nr_class);
for(int i=0;i<nr_class;i++)
FSCANF(fp,"%d",&model_->label[i]);
}
else
{
fprintf(stderr,"unknown text in model file: [%s]\n",cmd);
EXIT_LOAD_MODEL()
}
}
nr_feature=model_->nr_feature;
if(model_->bias>=0)
n=nr_feature+1;
else
n=nr_feature;
int w_size = n;
int nr_w;
if(nr_class==2 && param.solver_type != MCSVM_CS)
nr_w = 1;
else
nr_w = nr_class;
model_->w=Malloc(double, w_size*nr_w);
for(i=0; i<w_size; i++)
{
int j;
for(j=0; j<nr_w; j++)
FSCANF(fp, "%lf ", &model_->w[i*nr_w+j]);
}
setlocale(LC_ALL, old_locale);
free(old_locale);
if (ferror(fp) != 0 || fclose(fp) != 0) return NULL;
return model_;
}
int get_nr_feature(const model *model_)
{
return model_->nr_feature;
}
int get_nr_class(const model *model_)
{
return model_->nr_class;
}
void get_labels(const model *model_, int* label)
{
if (model_->label != NULL)
for(int i=0;i<model_->nr_class;i++)
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(idx < 0 || idx > model_->nr_feature)
return 0;
if(check_regression_model(model_) || check_oneclass_model(model_))
return w[idx];
else
{
if(label_idx < 0 || label_idx >= nr_class)
return 0;
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 and one-class SVM 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)
{
if(check_oneclass_model(model_))
{
fprintf(stderr, "ERROR: get_decfun_bias can not be called for a one-class SVM model\n");
return 0;
}
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);
}
double get_decfun_rho(const struct model *model_)
{
if(check_oneclass_model(model_))
return model_->rho;
else
{
fprintf(stderr, "ERROR: get_decfun_rho can be called only for a one-class SVM model\n");
return 0;
}
}
void free_model_content(struct model *model_ptr)
{
free(model_ptr->w);
model_ptr->w = NULL;
free(model_ptr->label);
model_ptr->label = NULL;
}
void free_and_destroy_model(struct model **model_ptr_ptr)
{
struct model *model_ptr = *model_ptr_ptr;
if(model_ptr != NULL)
{
free_model_content(model_ptr);
free(model_ptr);
*model_ptr_ptr = NULL;
}
}
void destroy_param(parameter* param)
{
free(param->weight_label);
param->weight_label = NULL;
free(param->weight);
param->weight = NULL;
free(param->init_sol);
param->init_sol = NULL;
}
const char *check_parameter(const problem *prob, const parameter *param)
{
if(param->eps <= 0)
return "eps <= 0";
if(param->C <= 0)
return "C <= 0";
if(param->p < 0 && param->solver_type == L2R_L2LOSS_SVR)
return "p < 0";
if(prob->bias >= 0 && param->solver_type == ONECLASS_SVM)
return "prob->bias >=0, but this is ignored in ONECLASS_SVM";
if(param->regularize_bias == 0)
{
if(prob->bias != 1.0)
return "To not regularize bias, must specify -B 1 along with -R";
if(param->solver_type != L2R_LR
&& param->solver_type != L2R_L2LOSS_SVC
&& param->solver_type != L1R_L2LOSS_SVC
&& param->solver_type != L1R_LR
&& param->solver_type != L2R_L2LOSS_SVR)
return "-R option supported only for solver L2R_LR, L2R_L2LOSS_SVC, L1R_L2LOSS_SVC, L1R_LR, and L2R_L2LOSS_SVR";
}
if(param->solver_type != L2R_LR
( run in 1.978 second using v1.01-cache-2.11-cpan-13bb782fe5a )