Lib svm, how to convert MyModel.mat to MyModel.model

前端 未结 1 1178
盖世英雄少女心
盖世英雄少女心 2020-12-16 08:06

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)?<

相关标签:
1条回答
  • 2020-12-16 08:10

    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');\n");
            fake_answer(plhs);
            return;
        }
        if(!mxIsStruct(prhs[0])) {
            mexPrintf("model file should be a struct array\n");
            fake_answer(plhs);
            return;
        }
        if(!mxIsChar(prhs[1]) || mxGetM(prhs[1])!=1) {
            mexPrintf("filename should be given as char(s)\n");
            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\n", 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 
    .
    .
    
    0 讨论(0)
提交回复
热议问题