如何为 libsvm 创建训练数据(作为 svm_node 结构)
Posted
技术标签:
【中文标题】如何为 libsvm 创建训练数据(作为 svm_node 结构)【英文标题】:How to create training data for libsvm (as an svm_node struct) 【发布时间】:2014-02-13 03:00:01 【问题描述】:我正在尝试使用 libsvm 以编程方式为一个简单的异或问题训练一个支持向量机,以了解该库的工作原理。问题(我认为)似乎是我错误地构造了 svm_node ;也许我很难理解指向指针的整个指针。有人可以帮忙吗?我首先为 xor 问题构建一个矩阵,然后尝试将矩阵中的值分配给 svm_node(我在这里使用 2 个步骤,因为我的真实数据将采用矩阵格式)。
在测试模型时,我得到不正确的值(总是 -1)。
在上一个问题中,我得到了参数 C 和 gamma 的帮助;这些现在应该没问题,因为我使用其他code 对 xor 问题进行了正确分类。再次感谢佩德罗姆!
我在几个地方搜索了答案,例如自述文件和 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,¶m);
//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;
【问题讨论】:
也许任何人都可以帮助我让这个示例在 Eclipse 下运行? ***.com/questions/35370588/… 【参考方案1】:看来您已经尝试让这个示例运行好几个星期了。我遵循了 libsvm 附带的 svm-train.c 中的样式。我使用了你的 C 和 gamma 值。这是工作。我尝试了 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,¶m);
//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(¶m);
free(prob.y);
free(prob.x);
free(x_space);
return 0;
【讨论】:
感谢您的解释和代码!现在很清楚为什么它不起作用了。以上是关于如何为 libsvm 创建训练数据(作为 svm_node 结构)的主要内容,如果未能解决你的问题,请参考以下文章