Algorithm-LibLinear
view release on metacpan or search on metacpan
src/liblinear/linear.cpp view on Meta::CPAN
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <locale.h>
#include "linear.h"
#include "newton.h"
int liblinear_version = LIBLINEAR_VERSION;
typedef signed char schar;
template <class T> static inline void swap(T& x, T& y) { T t=x; x=y; y=t; }
#ifndef min
template <class T> static inline T min(T x,T y) { return (x<y)?x:y; }
#endif
#ifndef max
template <class T> static inline T max(T x,T y) { return (x>y)?x:y; }
#endif
template <class S, class T> static inline void clone(T*& dst, S* src, int n)
{
dst = new T[n];
memcpy((void *)dst,(void *)src,sizeof(T)*n);
}
#define INF HUGE_VAL
#define Malloc(type,n) (type *)malloc((n)*sizeof(type))
static void print_string_stdout(const char *s)
{
fputs(s,stdout);
fflush(stdout);
}
static void print_null(const char *s) {}
static void (*liblinear_print_string) (const char *) = &print_string_stdout;
#if 1
static void info(const char *fmt,...)
{
char buf[BUFSIZ];
va_list ap;
va_start(ap,fmt);
vsprintf(buf,fmt,ap);
va_end(ap);
(*liblinear_print_string)(buf);
}
#else
static void info(const char *fmt,...) {}
#endif
class sparse_operator
{
public:
static double nrm2_sq(const feature_node *x)
{
double ret = 0;
while(x->index != -1)
{
ret += x->value*x->value;
x++;
}
return ret;
}
static double dot(const double *s, const feature_node *x)
{
double ret = 0;
while(x->index != -1)
{
src/liblinear/linear.cpp view on Meta::CPAN
double predict_probability(const struct model *model_, const struct feature_node *x, double* prob_estimates)
{
if(check_probability_model(model_))
{
int i;
int nr_class=model_->nr_class;
int nr_w;
if(nr_class==2)
nr_w = 1;
else
nr_w = nr_class;
double label=predict_values(model_, x, prob_estimates);
for(i=0;i<nr_w;i++)
prob_estimates[i]=1/(1+exp(-prob_estimates[i]));
if(nr_class==2) // for binary classification
prob_estimates[1]=1.-prob_estimates[0];
else
{
double sum=0;
for(i=0; i<nr_class; i++)
sum+=prob_estimates[i];
for(i=0; i<nr_class; i++)
prob_estimates[i]=prob_estimates[i]/sum;
}
return label;
}
else
return 0;
}
static const char *solver_type_table[]=
{
"L2R_LR", "L2R_L2LOSS_SVC_DUAL", "L2R_L2LOSS_SVC", "L2R_L1LOSS_SVC_DUAL", "MCSVM_CS",
"L1R_L2LOSS_SVC", "L1R_LR", "L2R_LR_DUAL",
"", "", "",
"L2R_L2LOSS_SVR", "L2R_L2LOSS_SVR_DUAL", "L2R_L1LOSS_SVR_DUAL",
"", "", "", "", "", "", "",
"ONECLASS_SVM", NULL
};
int save_model(const char *model_file_name, const struct model *model_)
{
int i;
int nr_feature=model_->nr_feature;
int n;
const parameter& param = model_->param;
if(model_->bias>=0)
n=nr_feature+1;
else
n=nr_feature;
int w_size = n;
FILE *fp = fopen(model_file_name,"w");
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);
}
( run in 1.079 second using v1.01-cache-2.11-cpan-ceb78f64989 )