libsvm svm_node 和 svm_predict

libsvm svm_node and svm_predict

我对如何正确使用libSVM C++代码有些疑惑。 使用我自己的数据矩阵,我使用作者提供的 svm-train exe 训练了一个二进制 SVM 分类器。我还使用 svm-predict 可执行文件测试了模型。训练和测试矩阵已按照作者的建议创建:

标签1:val_1.......n:val_n

标签1:val_1.......n:val_n

标签1:val_1.......n:val_n

.....

标签1:val_1.......n:val_n

该模型似乎以这种方式运行良好。

目前我正在尝试做的是从 C++ 应用程序加载模型并请求分类。我认为问题是当我创建 svm_node 数组时,我所做的是以下

Mat featureVector = ....; //opencv matrix 1 rows x n cols
int n = featureVector.cols;
struct svm_node *x = (struct svm_node *) malloc((n+1)*sizeof(struct svm_node));

int nonZero = 0;
for(int i = 0; i < n; i++){
    //Escape zero values
    if(featureVector.at<float>(0,i) != 0){
        x[nonZero].index = i+1; //libsvm index start from 1
        x[nonZero].value = featureVector.at<float>(0,i);
        nonZero++;
    }
}
x[nonZero].index = -1;//requested by libSVM

x = (struct svm_node *) realloc(x, (nonZero+1) * sizeof(struct svm_node));

//finally ask for prediction
int prediction = svm_predict(model, x);

分类器总是产生相同的结果。我不确定如果我不这样做,我是否必须转义零值,结果是一样的。有谁知道我做错了什么吗?

我设法解决了问题,我的代码中的错误是第一个特征的起始索引。因此,与我在其他 post 中读到的相反,libsvm 索引从零开始。使用以下代码,分类器可以正常工作:

int n = featureVector.cols;
struct svm_node *x = (struct svm_node *) malloc((n+1)*sizeof(struct svm_node));

for(int i = 0; i < n; i++){

        x[i].index = i; 
        x[i].value = featureVector.at<float>(0,i);

}

x[n].index = -1;

我还删除了跳零控件。 希望这可以帮助别人!

来源 svm-predict.c 代码来自作者。

你需要在训练集中有相同数量的样本。举个例子; classA 有 500 个实例。 classB 有 500 个实例。否则,您将获得与您在训练集中使用的较大 class 相同的所有结果。