最近搞了一段时间SVM,想用它来分类。我提前的特征是图像的HOG特征,采样数据是2340维的向量。网上描述libsvm的文章铺天盖地,几乎都是一样的,最恶心的是大多数都是说出了大体流程,很少有人说具体步骤的。即使有也是在使用 svm-train, svm-scale, svm-predict 等可执行文件。
经过一番摸索,终于成功的移植到了自己的程序中。有几个细节问题如下:
1、数据的scale处理
之前用libsvm和opencv里面的cvSvm都不能得到自己想要的结果,如果换成简单的样本数据,可以很好的分类,但是换成我的2340维的数据之后,结果就不对了,分类全是-1,有时候全是1。问题出现的原因是,特征数据没有归一化处理,这样会使大特征吃掉小特征,在BP神经网络里也存在类似的问题。很多文章里只是说做scale有助于参数的选择和解SVM的速度,其实,完全可以说的重要一些,对于数据相差比较大的情况下,不做scale处理,将得不到正确的分类结果。
libsvm的源码里面有这部分的源代码,但是太罗嗦了,他需要传递的参数也比较难懂。其实大可不必这么麻烦,这部分仅仅就是做了一个缩放处理,一个小函数即可搞定。
2、分类或者预测操作
libsvm的源码里面有这部分的文件svm-predict.c,程序实现的有点复杂,其实完全可以简化成一行代码。就是用函数svm_predict,传入两个参数,分别是加载进来的model文件和归一化之后的特征数据文件。