libsvmのmatlabインタフェースですが,Version 3.14, November 2012 の段階では,学習結果の構造体に目的関数の値が入っていません.
ここのページに修正方法が記載されておりましたので,実際にどこをどのように修正するかをメモしておきます.
環境はMac OS 10.7.5, Matlab 2012b 64bit, i686-apple-darwin11-llvm-g++-4.2 です
libsvm provides its matlab interface. However, in the current version (Version 3.14, November 2012), the output structure generated by svmtrain does NOT include an objective value.
Referring to here, this article shows a concrete instruction to modify libsvm.
NOTE: confirmed in Mac OS 10.7.5, Matlab 2012b 64bit, i686-apple-darwin11-llvm-g++-4.2 for compilation
svm.cpp
//
// decision_function
//
struct decision_function
{
double *alpha;
double rho;
// ADD THE FIELD "OBJ"
double obj;
//
};
...
static decision_function svm_train_one(
const svm_problem *prob, const svm_parameter *param,
double Cp, double Cn)
{
...
decision_function f;
f.alpha = alpha;
f.rho = si.rho;
// COPY THE OBJECTIVE VALUE TO THE ADDED FIELD
f.obj=si.obj;
//
return f;
}
...
svm_model *svm_train(const svm_problem *prob, const svm_parameter *param)
{
...
decision_function f = svm_train_one(prob,param,0,0);
model->rho = Malloc(double,1);
model->rho[0] = f.rho;
// COPY THE OBJECTIVE VALUE TO A MODEL INSTANCE
model->obj = Malloc(double ,1);
model->obj[0]=f.obj;
//
...
// build output
model->nr_class = nr_class;
// COPY THE OBJECTIVE VALUE TO A MODEL INSTANCE
model->obj = Malloc(double,p);
for(i=0;i<p;i++)
model->obj[i]=f[i].obj;
//
svm.h
struct svm_model
{
...
int free_sv; /* 1 if svm_model is created by svm_load_model*/
/* 0 if svm_model is created by svm_train */
// ADD THE FIELD "OBJ"
double* obj;
//
};
svm_model_matlab.c
#define NUM_OF_RETURN_FIELD 12 // CHANGE # FILEDS FROM 11 TO 12
...
static const char *field_names[] = {
"Parameters",
"nr_class",
"totalSV",
"rho",
// ADD THE FIELD "OBJ"
"obj",
//
"Label",
"sv_indices",
"ProbA",
"ProbB",
"nSV",
"sv_coef",
"SVs"
};
...
// rho
n = model->nr_class*(model->nr_class-1)/2;
rhs[out_id] = mxCreateDoubleMatrix(n, 1, mxREAL);
ptr = mxGetPr(rhs[out_id]);
for(i = 0; i < n; i++)
ptr[i] = model->rho[i];
out_id++;
// COPY THE OBJECTIVE VALUE IN A MODEL INSTANCE
n = model->nr_class*(model->nr_class-1)/2;
rhs[out_id] = mxCreateDoubleMatrix(n, 1, mxREAL);
ptr = mxGetPr(rhs[out_id]);
for(i = 0; i < n; i++)
ptr[i] = model->obj[i];
out_id++;
//
...
model->rho = NULL;
// INSERT NULL TO OBJ
model->obj = NULL;
//
// rho
n = model->nr_class * (model->nr_class-1)/2;
model->rho = (double*) malloc(n*sizeof(double));
ptr = mxGetPr(rhs[id]);
for(i=0;i<n;i++)
model->rho[i] = ptr[i];
id++;
// COPY THE OBJECTIVE VALUE IN A MODEL INSTANCE
n = model->nr_class * (model->nr_class-1)/2;
model->obj = (double*) malloc(n*sizeof(double));
ptr = mxGetPr(rhs[id]);
for(i=0;i<n;i++)
model->obj[i] = ptr[i];
id++;
//