Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
186 views
in Technique[技术] by (71.8m points)

c++ - Lib svm, how to convert MyModel.mat to MyModel.model

I have a .mat file which could be easily read by matlab, but I need to convert it a C++ readable .model file. is there a way to do it (by hands, or maybe programmatically)?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You could load the data matrix in MATLAB as any regular MAT-file:

load data.mat

then use the MEX function libsvmwrite which comes with the libsvm MATLAB interface, to write it to the so called "sparse" format:

libsvmwrite('data.txt', label_vector, instance_matrix)

If you are talking about trained models not data, a quick search revealed this page (I haven't personally tested it).


EDIT:

Ok, it appears that the code I mentioned needs some tweaking. Below is my modified version. I tested it using the latest libSVM-3.12, with VS2010 as compiler:

svm_savemodel.c

#include "../svm.h"
#include "mex.h"
#include "svm_model_matlab.h"

static void fake_answer(mxArray *plhs[])
{
    plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL);
}

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    struct svm_model *model;
    char *filename;
    const char *error_msg;
    int status;

    // check input
    if(nrhs != 2) {
        mexPrintf("Usage: svm_savemodel(model, 'filename');
");
        fake_answer(plhs);
        return;
    }
    if(!mxIsStruct(prhs[0])) {
        mexPrintf("model file should be a struct array
");
        fake_answer(plhs);
        return;
    }
    if(!mxIsChar(prhs[1]) || mxGetM(prhs[1])!=1) {
        mexPrintf("filename should be given as char(s)
");
        fake_answer(plhs);
        return;
    }

    // convert MATLAB struct to C struct
    model = matlab_matrix_to_model(prhs[0], &error_msg);
    if(model == NULL) {
        mexPrintf("Error: can't read model: %s
", error_msg);
        fake_answer(plhs);
        return;
    }

    // get filename
    filename = mxArrayToString(prhs[1]);

    // save model to file
    status = svm_save_model(filename,model);
    if (status != 0) {
        mexWarnMsgTxt("Error occured while writing to file.");
    }

    // destroy model
    svm_free_and_destroy_model(&model);
    mxFree(filename);

    // return status value (0: success, -1: failure)
    plhs[0] = mxCreateDoubleScalar(status);

    return;
}

Assuming you compiled the above MEX file, here is an example usage:

[labels, data] = libsvmread('./heart_scale');
model = svmtrain(labels, data, '-c 1 -g 0.07');
svm_savemodel(model, 'mymodel.model');

The text file created looks like:

mymodel.model

svm_type c_svc
kernel_type rbf
gamma 0.07
nr_class 2
total_sv 130
rho 0.426412
label 1 -1
nr_sv 63 67
SV
1 1:0.166667 2:1 3:-0.333333 4:-0.433962 5:-0.383562 6:-1 7:-1 8:0.0687023 9:-1 10:-0.903226 11:-1 12:-1 13:1 
0.6646947579781318 1:0.125 2:1 3:0.333333 4:-0.320755 5:-0.406393 6:1 7:1 8:0.0839695 9:1 10:-0.806452 12:-0.333333 13:0.5 
.
.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...