软件包中有一个 README 文件,里面详细说明了所有参数选项、数据格式以及库函数的调用。在python目录下,模型选择工具和python界面的libsvm各有一个README文件。 初学者可以通过A practical guide to support vector classification 了解如何训练和检验数据.论文LIBSVM : a library for support vector machines 详细讨论了libsvm的使用.
[Go Top]
问: 以前版本的libsvm都有什么变化?
详见变化日志. 你可以到这里下载以前版本的libsvm .
问: 如果我想引用libsvm, 我应该引用哪篇论文?
请引用以下论文: Chih-Chung Chang and Chih-Jen Lin, LIBSVM : a library for support vector machines, 2001. Software available at http://www.csie.ntu.edu.tw/~cjlin/libsvm bibtex格式如下:
@Manual{CC01a,
author = {Chih-Chung Chang and Chih-Jen Lin},
title = {{LIBSVM}: a library for support vector machines},
year = {2001},
note = {Software available at \url{http://www.csie.ntu.edu.tw/~cjlin/libsvm}}
}
问: 如果我想在我的软件中应用svm,是否存在软件许可问题?
Libsvm许可文件 ("修改了的BSD许可文件") 和其他许多软件的许可文件都是兼容的,如 GPL. 因此你很容易就可以把libsvm应用到你的软件中,你还可以将它应用到商业产品中.
问: 是否有一系列基于libsvm的附加工具?
是的,详见libsvm tools
问: 在Unix操作系统中, 出现了"error in loading shared libraries"(“在装载共享库时发生错误”)或者"cannot open shared object file."(无法打开共享目标文件“) 这是为什么?
如果你在一台机器上编译代码,然后到另外一台有着不兼容库的机器上运行,这种情况酒会经常发生。你在那台机器上可以重新编译一下,或者用静态连接。
问:修改源代码后,如果想在MS窗口中建立一个“svm-toy”的图形界面,我该怎么做?
你可以通过选择 "Win32 Project"来建立一个工程。另外对于"svm-train"和 "svm-predict" ,你需要选择"Win32 Console Project"。对于libsvm2.5以后的版本,你还可以通过Makefile.win来实现。详见README。
如果你没有用Makefile.win并出现了以下连接错误:LIBCMTD.lib(wwincrt0.obj) : error LNK2001: unresolved external symbol
_wWinMain@16
那么,你很有可能是选择了一个错误的工程类型。
问: 我是MS Windows用户,在这些预编译的exe文件中,为什么只有一个(SVM_toy)运行? 你应当打开命令窗口,然后输入svmtrain.exe,这样就可以在DOS窗口中看到所有的选项了。你可以到README文件中看到一些例子
问:为什么有时我在training/model 文件中看不到所有的数据属性呢?W
libsvm应用了所谓的”稀疏“格式,这样零值就不用存储了。例如,有下面属性的数据
1 0 2 0
将被替换为: 1:1 3:2
问:如果我的数据是非数值型的,可以用libsvm吗? 目前libsvm只支持数值型的数据。因此,你必须将非数值型的转为数值型的数据。比如,你可以用二进制属性来替代原来的类别属性。
问:为什么要采用稀疏格式呢? 密集数据在训练时候会不会很慢? 这是个具有争议的话题。将系数向量赋值给核函数是比较慢的,因此总的训练时间至少是采用密集格式的2倍或3倍。 但是,我们不支持密集格式的数据,因为我们不能够处理极度稀疏的数据。代码的简洁也是我们考虑的一个因素。目前我们决定只支持稀疏格式的数据。
问: 训练C-SVM时,其输出结果如下, 它们代表什么意思?
optimization finished, #iter = 219
nu = 0.431030
obj = -100.877286, rho = 0.424632
nSV = 132, nBSV = 107
Total nSV = 132 obj 是对偶SVM问题的最优目标值. rho 是判决函数sgn(w^Tx - rho)的偏项. nSV 和 nBSV 分别代表支持向量和边界支持向量 (即alpha_i = C)的个数. nu-svm 在某中程度上可以看作 C-SVM的等价形式,不过其中的 C被替换为 nu. nu 仅表明了相应的参数. 更详细的解释请看libsvm document.
问:关于模型文件,您能否解释的更详细一点?
在参数后面,每一条线代表一个支持向量。 支持向量按照先列出的标签列出(即类标签列表中,第一类的支持向量首先分组,然后依次类推)
如果k是类别的总数,那么每个支持向量的前面就有k-1个y*alpha系数,其中alpha代表如下二分类问题的对偶解:
1 vs j, 2 vs j, ..., j-1 vs j, j vs j+1, j vs j+2, ..., j vs k
并且在前j-1个系数中,y=+1, 其余的k-j个系数中y=-1.例如,对于4分类问题,文件看起来结构如下:
+-+-+-+--------------------+
|1|1|1| |
|v|v|v| 类别1的支持向量 |
|2|3|4| |
+-+-+-+--------------------+
|1|2|2| |
|v|v|v| 类别2的支持向量 |
|2|3|4| |
+-+-+-+--------------------+
|1|2|3| |
|v|v|v| 类别3的支持向量 |
|3|3|4| |
+-+-+-+--------------------+
|1|2|3| |
|v|v|v| 类别4的支持向量 |
|4|4|4| |
+-+-+-+--------------------+
问: 在缓缓存中,是否可以用浮点型或者双精度型来存储数据? 当你在缓存中存入更多的数据时,我们默认的是浮点型.一般情况下,这样就很好了,但是对于少数困难的情况(如C非常非常大)解将是巨大的数字。这时,仅用浮点型,数值的精度可能就不够了。
通常我们建议你首先采用RBF核函数。Keerthi 和 Lin 的最近的研究( 下载论文) 表明如果模型选择RBF的话,就没有必要再考虑线性核函数了。采用sigmoid核函数的矩阵不一定会正有界,而且通常它的准确性也不如RBF(可参见Lin和Lin的论文 此处下载). 多项式核函数还不错,但是如果度数很高的话,数值困难就会发生(考虑到(<1)的d次幂会趋向0,(>1)的d次幂会趋向无穷)
不是的,目前libsvm用同样的方法处理线性/非线性SVMs. 注意:如果采用线性核函数,一些技巧可能会节省训练/检验的时间。 因此libsvm对线性SVM并不时特别有效,尤其是采用很大的C的问题,这些问题数据的数值比其属性值要大得多。你可以:
- 仅用很大的C.下面的论文表明了:当C大于一个确定的阀值以后,判决函数是相同的。
S. S. Keerthi and C.-J. Lin. Asymptotic behaviors of support vector machines with Gaussian kernel . Neural Computation, 15(2003), 1667-1689.
- 尝试用bsvm, 它有个对解决线性SVMs很有效的方法.你可以在下面的研究中找到更详细的内容:
K.-M. Chung, W.-C. Kao, T. Sun, and C.-J. Lin. Decomposition Methods for Linear Support Vector Machines. Neural Computation, 16(2004), 1689-1704.
另外,你并没必要一定要解决线性SVMs.你可以参考前面有关如何选取核函数的问题。
当数据过拟和时,这种情况会经常发生. 如果数据的属性值范围特别大,你可以尝试调整它们的范围。这样合适参数的域可能会很大。注意:libsvm里包含有数据调整程序的,即svm_scale.
问: 我是否可以用同样的方法来调整训练数据和检验数据的范围?
是的, 可以按照以下方法: svm-scale -s scaling_parameters train_data > scaled_train_data svm-scale -r scaling_parameters test_data > scaled_test_data
问:将属性值限制到[0,1],是否比限制到 [-1,1]有很大的不同?
对于线性规划方法,如果采用可RBF核函数并进行了参数的选择,两者是没什么不同的。假设Mi和mi分别代表第i个属性的最大值和最小值.规划到[0,1]即:
x'=(x-mi)/(Mi-mi)
对于[-1 1]:
x''=2(x-mi)/(Mi-mi)-1.
在RBF核函数中:
x'-y'=(x-y)/(Mi-mi), x''-y''=2(x-y)/(Mi-mi).
因此在[0,1]数据规划中用(C,g),和[-1 1]数据规划中用(C,g/2)是一样的。
尽管性能相同,但是计算机时间可能不同。对于有许多零入口的数据, [0,1]规划保持了输入数据的稀疏特性,因此可能会节省计算时间。
可以用python目下的grid.py来寻找合适的参数,grid.py是一个用来选择模型参数的工具。关于模型选择的重要性,你可以参考我的谈话: A practical guide to support vector classification
可以。libsvm有一个-wi选项。例如,你用:
svm-train -s 0 -c 10 -w1 1 -w-1 5 data_file
则对类别“-1”的惩罚就较大。注意-w选项仅用在C-SVC中。
问: nu-SVC和C-SVC有什么不同之处?
除了参数不同外,两者基本是一样的。C-SVC中,C的范围是0到无穷,nu-SVC中C的范围是[0 1]。 nu一个很好的特性是:它与支持向量的比率和训练误差的比率相关。
你最好检查一下数据. 每一个训练/学习的数据都必须在一行,不可以分开。此外,你必须删除空行。
从理论上讲,如果核矩阵式半正定的,libsvm可以保证收敛。2.4以后版本的libsvm还可以处理非半正定矩阵核,比如sigmoid(tanh)核。这样看来,你处理的情况是病态情况(比如参数过大或过小),这样机会发生数值困难。
对于大型问题,请确保有足够的缓存空间(即-m)。对于一些困难的情况(比如-c很大),会出现收敛很慢的情况. 你可以常识用一个较大点的终止可容忍偏差. 如果这样仍然不行,你可以和我们联系。我们会告诉你一些关于改善训练时间短小技巧。
对于回归,程序可以打印出判决值。对于分类,可以通过解几个二进制SVMs来实现多分类,因此你可以通过调用子程序svm_predict_values来实现输出判决值。然后可以通过子程序svm_get_labels得到相应的标签值。详见软件包中的README文件。
我们并不推荐以下操作,但是如果你要得到二分类的标签值+1和-1(注:这里的+1、-1和5、10的含义是不一样的),你只要在svm.cpp文件中的 svm_predict_values(model, x, dec_values) 后面添加:printf("%f\n",dec_values[0]*model->label[0])就可以了。
正(负)判决值对应的值为+1(-1)
距离的表达式为: |decision_value| / |w|.我们有: |w|^2 = w^Tw = alpha^T Q alpha = 2*(dual_obj + sum alpha_i). 因此在svm.pp文件中,知道输出对偶目标值的语句,在后面加上打印输出 w^Tw的语句就可以了.
问:在linux操作系统上,对于一些问题,如果用很大的缓存(即很大的-m),有时候会出现“段错误”("segmentation fault“),为什么?
在32位机器上,最大可设地址空间为4GB。Linux核将其分成3:1,即:用户的空间为3GB,核空间为1G。尽管用户有3GB的存储空间,但是最大动态分配内存只有2GB。因此如果你将-m设为2G,内存将被耗尽。因此svm-train运行时候如果需要更多内存,程序就无法运行。详见此文.
有两中方法可以解决这个问题。如果你的机器支持Intel的物理地址扩展,你可以在Linux核中起用HIGHMEM64G选项,这样用户和核都将分配到4G的空间. 此外, 你还可以使用`tub'软件,它将为动态分配内存 elimate the 2G boundary . `tub' 可以到http://www.bitwagon.com/tub.html下载.