将libsvm模型结构从matlab保存到.model文件,可以用C ++读取

时间:2016-04-29 19:08:18

标签: c++ matlab libsvm

我有两个问题:

  1. 我按照帖子Lib svm, how to convert MyModel.mat to MyModel.model中的说明进行操作 我尝试使用以下方法在Mac OSx El Capitan上构建svm_savemodel.c: mex svm_savemodel.c并发生以下情况:
  2. 使用' Xcode与Clang'建立。使用mex未定义的符号用于体系结构x86_64时出错:" _matlab_matrix_to_model",引自:svm_savemodel.o中的_mexFunction" _svm_free_and_destroy_model",引自:svm_savemodel.o中的_mexFunction" _svm_save_model&#34 ;,引自:svm_savemodel.o中的_mexFunction ld:找不到架构x86_64 clang的符号:错误:链接器命令失败,退出代码为1(使用-v查看调用) 任何人都可以建议一些解决方案吗?

    1. 所以我正在考虑编写一个matlab代码,它将matlab中的模型结构转换为可以用C ++读取的MyModel.model文件 这篇文章Libsvm model file format No model number讨论了需要在.model文件中保存的参数。
    2. 我正在研究回归问题,所以在我的情况下,标签条目不会出现。除此之外还有什么我需要照顾的吗?

      谢谢。

1 个答案:

答案 0 :(得分:0)

我修改了How to create training data for libsvm (as an svm_node struct)处的代码以进行回归,并查看了模型保存的格式

{ struct svm_parameter param; //由parse_command_line设置 struct svm_problem prob; //由read_problem设置 // struct svm_model * model; struct svm_node * x_space;

int main(int argc, const char * argv[]) {
char input_file_name[1024];
char model_file_name[1024] = "MyModel" ;
const char *error_msg;

param.svm_type = EPSILON_SVR;
param.eps = 1e-3;
param.C = 1;
//param.kernel_type = RBF;
param.degree = 3;


//Problem definition-------------------------------------------------------------
prob.l = 8;

//x values matrix of xor values
double matrix[prob.l][2];
matrix[0][0] = 0.1;
matrix[0][1] = 0.2;

matrix[1][0] = 0.2;
matrix[1][1] = 0.3;

matrix[2][0] = 0.4;
matrix[2][1] = 0.5;

matrix[3][0] = 0.8;
matrix[3][1] = 0.9;

matrix[4][0] = 0.6;
matrix[4][1] = 0.7;

matrix[5][0] = 0.55;
matrix[5][1] = 0.65;

matrix[6][0] = 0.45;
matrix[6][1] = 0.55;

matrix[7][0] = 0.65;
matrix[7][1] = 0.75;

svm_node** x = Malloc(svm_node*,prob.l);

//Trying to assign from matrix to svm_node training examples
for (int row = 0;row <prob.l; row++){
    svm_node* x_space = Malloc(svm_node,3);
    for (int col = 0;col < 2;col++){
        x_space[col].index = col;
        x_space[col].value = matrix[row][col];
    }
    x_space[2].index = -1;      //Each row of properties should be terminated with a -1 according to the readme
    x[row] = x_space;
}

prob.x = x;

//yvalues
prob.y = Malloc(double,prob.l);
prob.y[0] = 0.15;
prob.y[1] = 0.25;
prob.y[2] = 0.45;
prob.y[3] = 0.85;
prob.y[4] = 0.65;
prob.y[5] = 0.6;
prob.y[6] = 0.5;
prob.y[7] = 0.7;

//Train model---------------------------------------------------------------------
svm_model *model = svm_train(&prob,&param);
//svm_model *model = svm_load_model(model_file_name);

//Test model----------------------------------------------------------------------
svm_node* testnode = Malloc(svm_node,3);
testnode[0].index = 0;
testnode[0].value = 0.6;
testnode[1].index = 1;
testnode[1].value = 0.7;
testnode[2].index = -1;

//This works correctly:
double retval = svm_predict(model,testnode);

    svm_save_model(model_file_name, model);
printf("retval: %f\n",retval);


svm_destroy_param(&param);
free(prob.y);
free(prob.x);
free(x_space);

return 0;

} }

然后我在matlab中编写了下面的代码来保存在matlab中生成的svm模型结构,我可以在C ++中读取保存的模型

{ 负载(&#39; ClassificationMATLAB.mat&#39); %使用svm struct of model打开mat文件,struct的变量名是&#39; svm&#39; FID =的fopen(&#39;为MyModel&#39;&#39; W&#39);

fprintf(fid,&#39;%s%s \ n&#39;,&#39; svm_type&#39;,&#39; epsilon_svr&#39;); fprintf(fid,&#39;%s%s \ n&#39;,&#39; kernel_type&#39;,&#39; rbf&#39;); %rbf fprintf(fid,&#39;%s%s \ n&#39;,&#39; nr_class&#39;,&#39; 2&#39;); %fprintf(fid,&#39;%s%s \ n&#39;,&#39; degree&#39;,&#39; 3&#39;);

fprintf(fid,&#39;%s%s \ n&#39;,&#39; total_sv&#39;,num2str(svm.totalSV)); fprintf(fid,&#39;%s%s \ n&#39;,&#39; rho&#39;,num2str(svm.rho));

fprintf中(FID,&#39;%S \ n&#39;&#39; SV&#39);

FullSVs =满(svm.SVs);

表示i = 1:长度(svm.SVs)

fprintf(fid, '%s', num2str(svm.sv_coef(i)));
fprintf(fid, '%s %s\n', [' 0:' num2str(FullSVs(i,1))],[' 1:' num2str(FullSVs(i,2))]);

端 FCLOSE(FID);

}