[size=medium]其他关于svm和libsvm的东西这里不再赘述,本文主要介绍下我在用libsvm过程中遇到的问题进行一下说明,网上资料大多数都是关于libsvm参数的一些说明,这里简单介绍下如何用java代码运行一个小
例子。
首先我们要下载libsvm jar包,然后我把svm_train,svm_scale,svm_predict三个类文件复制了出来,主要是了解一下内部实现。接着准备好训练数据集合测试数据集。数据文件格式如下,label是类别,index是feature即特征或者维,value是对应特征值。
class="java" name="code">
[label] [index1]:[value1] [index2]:[value2] ...
[label] [index1]:[value1] [index2]:[value2] ...
接下来就要开始对数据进行归一化处理,用到svm_scale类。
Usage: svm-scale [options] data_filename
options:
-l lower : x scaling lower limit (default -1)
-u upper : x scaling upper limit (default +1)
-y y_lower y_upper : y scaling limits (default: no y scaling)
-s save_filename : save scaling parameters to save_filename
-r restore_filename : restore scaling parameters from restore_filename
这里特别解释下-s -r参数,-s参数指定保存svm_scale扫描过后的归一化scale标准,-r表示读入的标准。我们因为同时要考虑训练集和测试集,所以这里需要两个参数。libsvm这里采用的是最大最小值归一化,默认的归一化范围是[-1,1],可以用参数-l和-u分别调整上界和下界,java代码如下。
String[] testArgs = {"-l","0", "-u","1","-s","chao-test-scale","UCI-breast-cancer-tra"};
svm_scale.main(testArgs);
String[] argvScaleTest ={"-r","chao-test-scale","UCI-breast-cancer-test"};
svm_scale.main(testArgs);
执行完之
后生成的chao-test-scale文件里面就是最后的scale标准,文件内容如下:
x
0.000000000000000 1.000000000000000
1 63375.00000000000 13454352.00000000
2 1.000000000000000 10.00000000000000
3 1.000000000000000 10.00000000000000
4 1.000000000000000 10.00000000000000
5 1.000000000000000 10.00000000000000
6 1.000000000000000 10.00000000000000
7 1.000000000000000 10.00000000000000
8 1.000000000000000 10.00000000000000
9 1.000000000000000 10.00000000000000
10 1.000000000000000 10.00000000000000
文件里面列出了归一化的区间0-1,每个feature的最大最小值,便于后面对整个集合做scale处理。有的遗憾的是svm_scale类没有直接提供参数指定生成scale的文件,不过它在执行过程中会输出整个scale后的文件,我们可以通过控制台直接重定向到新文件里面。
java svm_scale -s chao-test-scale train>train.scale
java svm_scale -s chao-test-scale test>test.scale
这样就将train训练集和test测试集全部scale成功,我们就可以开始训练和检测了,分别使用svm_train和svm_predict。
String[] trainArgs = {"train.scale"};
String modelFile = svm_train.main(trainArgs);
String[] testArgs = {"test.scale", modelFile, "result"};
Double accuracy = svm_predict.main(testArgs);
System.out.println("SVM Classification is done! The accuracy is " + accuracy);
另外从网上看到的使用libsvm的步骤如下:
1)按照LIBSVM软件包所要求的格式准备数据集;
2)对数据进行简单的缩放操作;
3)首要考虑选用RBF 核函数;
4)采用交叉验证选择最佳参数C与g ;
5)采用最佳参数C与g 对整个训练集进行训练获取支持向量机模型;
6)利用获取的模型进行测试与预测。
对应第4和5步,目前正在
研究阶段,了解到的只能使用grid.py来查找最佳参数,希望知道的人可以告知。等研究完之后再补充这点。
归一化处理可以加快运算速度,提高预测准确率。下面贴一下数据归一化之前的运行结果。
optimization finished, #iter = 1223
nu = 0.6996186233933985
obj = -271.992875483972, rho = 0.4257786283326366
nSV = 639, nBSV = 222
Total nSV = 639
Accuracy = 69.23076923076923% (27/39) (classification)
SVM Classification is done! The accuracy is 0.6923076923076923
归一之后的运行结果
optimization finished, #iter = 68
nu = 0.08154427324315143
obj = -44.22486456942005, rho = -0.8163705353889562
nSV = 61, nBSV = 48
Total nSV = 61
Accuracy = 89.74358974358975% (35/39) (classification)
SVM Classification is done! The accuracy is 0.8974358974358975
[/size]