Как создать обучающие данные для libsvm (как структура svm_node)

Я пытаюсь обучить svm для простой проблемы xor программным путем, используя libsvm, чтобы понять, как работает библиотека. Проблема (я думаю), кажется, в том, что я неправильно создаю svm_node; возможно у меня есть проблемы с пониманием целых указателей на указатели. Кто-нибудь может помочь с этим? Сначала я строю матрицу для задачи xor, затем пытаюсь присвоить значения из матрицы svm_node (здесь я использую 2 шага, потому что мои реальные данные будут в матричном формате).

При тестировании модели я получаю неправильные значения (всегда -1).

В предыдущем вопросе я получил помощь с параметрами C и гаммой; теперь все должно быть в порядке, так как я получил правильные классификации для проблемы XOR, используя другие код. Еще раз спасибо, Педром!

Я искал ответы в нескольких местах, например, Readme и в примере SvmToy; не повезло однако.

Вот код, который выводит неправильные классификации …

Заранее спасибо!

//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;

5

Решение

Кажется, вы пытались заставить этот пример работать несколько недель. Я следовал стилю в svm-train.c, который идет с libsvm. Я использовал ваши значения для C и гаммы. Это работает. Я попробовал все пункты в примере XOR, и он дает правильные результаты.

Суть проблемы, с которой вы столкнулись, заключается в том, что вы не выделяете место для 4-х точек данных, с которыми вы тренируетесь, поэтому вы просто перезаписываете данные. Это типичная ошибка с указателями в C. Это может помочь вам разобраться с указателями в C / C ++.

Вот код:

#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;
}
10

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]