diff --git a/README b/README index dce2c1f1..882eaa39 100644 --- a/README +++ b/README @@ -153,6 +153,7 @@ options: -g gamma : set gamma in kernel function (default 1/num_features) -r coef0 : set coef0 in kernel function (default 0) -c cost : set the parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1) +-l lamb : set the parameter lambda of SSVM (C-SVC) for open-set recognition (default -1) -n nu : set the parameter nu of nu-SVC, one-class SVM, and nu-SVR (default 0.5) -p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1) -m cachesize : set cache memory size in MB (default 100) @@ -385,6 +386,7 @@ to classify new data. double cache_size; /* in MB */ double eps; /* stopping criteria */ double C; /* for C_SVC, EPSILON_SVR, and NU_SVR */ + double lamb; /* for SSVM (open-set recognition) */ int nr_weight; /* for C_SVC */ int *weight_label; /* for C_SVC */ double* weight; /* for C_SVC */ diff --git a/python/svm.py b/python/svm.py index ffcb35e2..cae04064 100644 --- a/python/svm.py +++ b/python/svm.py @@ -224,10 +224,10 @@ def __init__(self, y, x, isKernel=False): class svm_parameter(Structure): _names = ["svm_type", "kernel_type", "degree", "gamma", "coef0", - "cache_size", "eps", "C", "nr_weight", "weight_label", "weight", + "cache_size", "eps", "C", "lamb", "nr_weight", "weight_label", "weight", "nu", "p", "shrinking", "probability"] _types = [c_int, c_int, c_int, c_double, c_double, - c_double, c_double, c_double, c_int, POINTER(c_int), POINTER(c_double), + c_double, c_double, c_double, c_double, c_int, POINTER(c_int), POINTER(c_double), c_double, c_double, c_int, c_int] _fields_ = genFields(_names, _types) @@ -255,6 +255,7 @@ def set_to_default_values(self): self.nu = 0.5 self.cache_size = 100 self.C = 1 + self.lamb = -1 self.eps = 0.001 self.p = 0.1 self.shrinking = 1 @@ -304,6 +305,9 @@ def parse_options(self, options): elif argv[i] == "-c": i = i + 1 self.C = float(argv[i]) + elif argv[i] == "-l": + i = i + 1 + self.lamb = float(argv[i]) elif argv[i] == "-e": i = i + 1 self.eps = float(argv[i]) diff --git a/python/svmutil.py b/python/svmutil.py index a1a043ef..0d362103 100644 --- a/python/svmutil.py +++ b/python/svmutil.py @@ -74,6 +74,7 @@ def svm_train(arg1, arg2=None, arg3=None): -g gamma : set gamma in kernel function (default 1/num_features) -r coef0 : set coef0 in kernel function (default 0) -c cost : set the parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1) + -l lamb : set the parameter lamb of SSVM (C-SVC) for open-set recognition (default -1) -n nu : set the parameter nu of nu-SVC, one-class SVM, and nu-SVR (default 0.5) -p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1) -m cachesize : set cache memory size in MB (default 100) diff --git a/svm-train.c b/svm-train.c index b6ce987d..cd0d418d 100644 --- a/svm-train.c +++ b/svm-train.c @@ -29,6 +29,7 @@ void exit_with_help() "-g gamma : set gamma in kernel function (default 1/num_features)\n" "-r coef0 : set coef0 in kernel function (default 0)\n" "-c cost : set the parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1)\n" + "-l lamb : set the parameter lambda of SSVM (C-SVC) for open-set recognition (default -1)\n" "-n nu : set the parameter nu of nu-SVC, one-class SVM, and nu-SVR (default 0.5)\n" "-p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1)\n" "-m cachesize : set cache memory size in MB (default 100)\n" @@ -172,6 +173,7 @@ void parse_command_line(int argc, char **argv, char *input_file_name, char *mode param.nu = 0.5; param.cache_size = 100; param.C = 1; + param.lamb = -1; param.eps = 1e-3; param.p = 0.1; param.shrinking = 1; @@ -213,6 +215,9 @@ void parse_command_line(int argc, char **argv, char *input_file_name, char *mode case 'c': param.C = atof(argv[i]); break; + case 'l': + param.lamb = atof(argv[i]); + break; case 'e': param.eps = atof(argv[i]); break; diff --git a/svm.cpp b/svm.cpp index fa44818b..6f45e772 100644 --- a/svm.cpp +++ b/svm.cpp @@ -1447,9 +1447,10 @@ static void solve_c_svc( int i; + double alpha_epsilon = param->lamb >= 0 ? param->lamb * param->C : 0; for(i=0;iy[i] > 0 ? alpha_epsilon : 0; minus_ones[i] = -1; if(prob->y[i] > 0) y[i] = +1; else y[i] = -1; } @@ -2669,6 +2670,8 @@ int svm_save_model(const char *model_file_name, const svm_model *model) if(param.kernel_type == POLY || param.kernel_type == SIGMOID) fprintf(fp,"coef0 %.17g\n", param.coef0); + fprintf(fp,"lamb %g\n", param.lamb); + int nr_class = model->nr_class; int l = model->l; fprintf(fp, "nr_class %d\n", nr_class); @@ -2825,6 +2828,8 @@ bool read_model_header(FILE *fp, svm_model* model) FSCANF(fp,"%lf",¶m.gamma); else if(strcmp(cmd,"coef0")==0) FSCANF(fp,"%lf",¶m.coef0); + else if(strcmp(cmd,"lamb")==0) + FSCANF(fp,"%lf",¶m.lamb); else if(strcmp(cmd,"nr_class")==0) FSCANF(fp,"%d",&model->nr_class); else if(strcmp(cmd,"total_sv")==0) @@ -3086,6 +3091,15 @@ const char *svm_check_parameter(const svm_problem *prob, const svm_parameter *pa if(param->C <= 0) return "C <= 0"; + if(param->lamb < 0 && param->lamb != -1) + return "lamb < 0 and lamb != -1"; + if(param->lamb >= 1) + return "lamb >= 1"; + if(param->lamb >= 0 && svm_type != C_SVC) + return "lamb >= 0 and svm_type != C_SVC"; + if(param->lamb >= 0 && kernel_type != RBF) + return "lamb > 0 and kernel_type != RBF"; + if(svm_type == NU_SVC || svm_type == ONE_CLASS || svm_type == NU_SVR) diff --git a/svm.h b/svm.h index b0bf6ef0..04a650a7 100644 --- a/svm.h +++ b/svm.h @@ -37,6 +37,7 @@ struct svm_parameter double cache_size; /* in MB */ double eps; /* stopping criteria */ double C; /* for C_SVC, EPSILON_SVR and NU_SVR */ + double lamb; /* for SSVM (open-set recognition) */ int nr_weight; /* for C_SVC */ int *weight_label; /* for C_SVC */ double* weight; /* for C_SVC */