2014-01-22 10 views
5

Ich versuche, ein SVM für ein einfaches XOR-Problem programmatisch mithilfe von libsvm zu trainieren, um zu verstehen, wie die Bibliothek funktioniert. Das Problem (denke ich) scheint zu sein, dass ich svm_node falsch konstruiere; vielleicht habe ich Probleme, die ganzen Zeiger auf Zeiger Sache zu verstehen. Könnte jemand dabei helfen? Ich konstruiere zuerst eine Matrix für das XOR-Problem und versuche dann, Werte von der Matrix svm_node zuzuweisen (ich verwende hier zwei Schritte, weil meine realen Daten im Matrixformat vorliegen).Wie erstellt man Trainingsdaten für libsvm (als svm_node-Struktur)

Beim Testen des Modells bekomme ich falsche Werte (immer -1).

In einer vorherigen Frage habe ich Hilfe mit den Parametern C und Gamma bekommen; Diese sollten jetzt OK sein, da ich korrekte Klassifikationen für das XOR-Problem mit anderen code bekommen habe. Danke nochmal Pedrom!

Ich habe an mehreren Stellen nach Antworten gesucht, z.B. die Readme und im SvmToy Beispiel; kein Glück jedoch.

Hier ist der Code, der falsche Einstufungen gibt ...

Vielen Dank im Voraus!

//Parameters--------------------------------------------------------------------- 
svm_parameter param; 
param.svm_type = C_SVC; 
param.kernel_type = RBF; 
param.degree = 3; 
param.gamma = 0.5; 
param.coef0 = 0; 
param.nu = 0.5; 
param.cache_size = 100; 
param.C = 1; 
param.eps = 1e-3; 
param.p = 0.1; 
param.shrinking = 1; 
param.probability = 0; 
param.nr_weight = 0; 
param.weight_label = NULL; 
param.weight = NULL; 


//Problem definition------------------------------------------------------------- 
svm_problem prob; 

//Length, 4 examples 
prob.l = 4; 

//x values matrix of xor values 
QVector< QVector<double> >matrix; 
QVector<double>row(2); 

row[0] = 1;row[1] = 1; 
matrix.push_back(row); 
row[0] = 1;row[1] = 0; 
matrix.push_back(row); 
row[0] = 0;row[1] = 1; 
matrix.push_back(row); 
row[0] = 0;row[1] = 0; 
matrix.push_back(row); 

//This part i have trouble understanding 
svm_node* x_space = new svm_node[3]; 
svm_node** x = new svm_node *[prob.l]; 

//Trying to assign from matrix to svm_node training examples 
for (int row = 0;row < matrix.size(); row++){ 
    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 = new double[prob.l]; 
prob.y[0] = -1; 
prob.y[1] = 1; 
prob.y[2] = 1; 
prob.y[3] = -1; 

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


//Test model---------------------------------------------------------------------- 
svm_node* testnode = new svm_node[3]; 
testnode[0].index = 0; 
testnode[0].value = 1; 
testnode[1].index = 1; 
testnode[1].value = 0; 
testnode[2].index = -1; 

//Should return 1 but returns -1 
double retval = svm_predict(model,testnode); 
qDebug()<<retval; 
+0

vielleicht unter Eclipse dieses Beispiel zu bekommen laufen kann mir jemand helfen? http://stackoverflow.com/questions/35370588/c-eclipse-libsvm-install-setup –

Antwort

10

Es scheint, Sie haben versucht, dieses Beispiel für Wochen zu arbeiten. Ich folgte dem Stil in svm-train.c, das mit libsvm kommt. Ich habe deine Werte für C und Gamma verwendet. Es funktioniert. Ich habe alle Punkte im XOR-Beispiel ausprobiert und es liefert korrekte Ergebnisse.

Die Zusammenfassung des Problems, das Sie haben, ist, dass Sie nicht Platz für die 4 Datenpunkte zuweisen, mit denen Sie trainieren, also überschreiben Sie einfach die Daten. Das ist ein typischer Fehler mit Zeigern in C. Es kann Ihnen helfen, Zeiger in C/C++ aufzuhellen.

Hier ist der Code:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <errno.h> 
#include "svm.h" 
#define Malloc(type,n) (type *)malloc((n)*sizeof(type)) 

struct svm_parameter param;  // set by parse_command_line 
struct svm_problem prob;  // set by read_problem 
struct svm_model *model; 
struct svm_node *x_space; 

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

    param.svm_type = C_SVC; 
    param.kernel_type = RBF; 
    param.degree = 3; 
    param.gamma = 0.5; 
    param.coef0 = 0; 
    param.nu = 0.5; 
    param.cache_size = 100; 
    param.C = 1; 
    param.eps = 1e-3; 
    param.p = 0.1; 
    param.shrinking = 1; 
    param.probability = 0; 
    param.nr_weight = 0; 
    param.weight_label = NULL; 
    param.weight = NULL; 


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

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

    matrix[1][0] = 1; 
    matrix[1][1] = 0; 

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

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


    //This part i have trouble understanding 
    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] = -1; 
    prob.y[1] = 1; 
    prob.y[2] = 1; 
    prob.y[3] = -1; 

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


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

    //This works correctly: 
    double retval = svm_predict(model,testnode); 
    printf("retval: %f\n",retval); 


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

    return 0; 
} 
+1

Danke für die Erklärung und den Code! Jetzt ist klar, warum es nicht funktioniert hat. – JCR