问: 已有哪些学校的课程应用了libsvm?
德国弗赖堡大学,计算机科学学院应用科学系
数学与计算机科学部. Faculteit der Exacte Wetenschappen 荷兰,自由大学(VU).
威斯康辛大学-麦迪逊分校,电子工程与计算机工程系
以色列,以色列理工学院.
佛罗里达州立大学 计算机与信息科学系.
肯尼亚,奈洛比大学,计算机科学学院.
冰岛大学,应用数学与计算机科学学院.
2005,芝加哥大学,机器学习夏季学校,SVM课件.
[Go Top]
--------------------------------------------------------------------------------
问: 我在那里能够找到libsvm的文件 ?
软件包中有一个 README 文件,里面详细说明了所有参数选项、数据格式以及库函数的调用。在python目录下,模型选择工具和python界面的libsvm各有一个README文件。 初学者可以通过A practical guide to support vector classification 了解如何训练和检验数据.论文LIBSVM : a library for support vector machines 详细讨论了libsvm的使用.
[Go Top]
--------------------------------------------------------------------------------
问: 以前版本的libsvm都有什么变化?
详见变化日志.
你可以到这里下载以前版本的libsvm .
[Go Top]
--------------------------------------------------------------------------------
问: 如果我想引用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}}
}
[Go Top]
--------------------------------------------------------------------------------
问: 如果我想在我的软件中应用svm,是否存在软件许可问题?
Libsvm许可文件 ("修改了的BSD许可文件") 和其他许多软件的许可文件都是兼容的,如 GPL. 因此你很容易就可以把libsvm应用到你的软件中,你还可以将它应用到商业产品中.
[Go Top]
--------------------------------------------------------------------------------
问: 是否有一系列基于libsvm的附加工具?
是的,详见libsvm tools
[Go Top]
--------------------------------------------------------------------------------
问: 在Unix操作系统中, 出现了"error in loading shared libraries"(“在装载共享库时发生错误”)或者"cannot open shared object file."(无法打开共享目标文件“) 这是为什么?
如果你在一台机器上编译代码,然后到另外一台有着不兼容库的机器上运行,这种情况酒会经常发生。你在那台机器上可以重新编译一下,或者用静态连接。
[Go Top]
--------------------------------------------------------------------------------
问:修改源代码后,如果想在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
那么,你很有可能是选择了一个错误的工程类型。
[Go Top]
--------------------------------------------------------------------------------
问: 我是MS Windows用户,在这些预编译的exe文件中,为什么只有一个(SVM_toy)运行?
你应当打开命令窗口,然后输入svmtrain.exe,这样就可以在DOS窗口中看到所有的选项了。你可以到README文件中看到一些例子
[Go Top]
--------------------------------------------------------------------------------
问:为什么有时我在training/model 文件中看不到所有的数据属性呢?W
libsvm应用了所谓的”稀疏“格式,这样零值就不用存储了。例如,有下面属性的数据
1 0 2 0
将被替换为:
1:1 3:2
[Go Top]
--------------------------------------------------------------------------------
问:如果我的数据是非数值型的,可以用libsvm吗?
目前libsvm只支持数值型的数据。因此,你必须将非数值型的转为数值型的数据。比如,你可以用二进制属性来替代原来的类别属性。
[Go Top]
--------------------------------------------------------------------------------
问:为什么要采用稀疏格式呢? 密集数据在训练时候会不会很慢?
这是个具有争议的话题。将系数向量赋值给核函数是比较慢的,因此总的训练时间至少是采用密集格式的2倍或3倍。 但是,我们不支持密集格式的数据,因为我们不能够处理极度稀疏的数据。代码的简洁也是我们考虑的一个因素。目前我们决定只支持稀疏格式的数据。
[Go Top]
--------------------------------------------------------------------------------
问: 训练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.
[Go Top]
--------------------------------------------------------------------------------
问:关于模型文件,您能否解释的更详细一点?
在参数后面,每一条线代表一个支持向量。 支持向量按照先列出的标签列出(即类标签列表中,第一类的支持向量首先分组,然后依次类推)
如果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| |
+-+-+-+--------------------+
[Go Top]
--------------------------------------------------------------------------------
问: 在缓缓存中,是否可以用浮点型或者双精度型来存储数据?
当你在缓存中存入更多的数据时,我们默认的是浮点型.一般情况下,这样就很好了,但是对于少数困难的情况(如C非常非常大)解将是巨大的数字。这时,仅用浮点型,数值的精度可能就不够了。
[Go Top]
--------------------------------------------------------------------------------
问:怎样选择核函数?
通常我们建议你首先采用RBF核函数。Keerthi 和 Lin 的最近的研究( 下载论文) 表明如果模型选择RBF的话,就没有必要再考虑线性核函数了。采用sigmoid核函数的矩阵不一定会正有界,而且通常它的准确性也不如RBF(可参见Lin和Lin的论文 此处下载). 多项式核函数还不错,但是如果度数很高的话,数值困难就会发生(考虑到(<1)的d次幂会趋向0,(>1)的d次幂会趋向无穷)
[Go Top]
--------------------------------------------------------------------------------
问: libsvm是否可以用来专门处理线性SVM?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.你可以参考前面有关如何选取核函数的问题。
[Go Top]
--------------------------------------------------------------------------------
问: 自由支持向量特别大,我该怎么办?
当数据过拟和时,这种情况会经常发生. 如果数据的属性值范围特别大,你可以尝试调整它们的范围。这样合适参数的域可能会很大。注意:libsvm里包含有数据调整程序的,即svm_scale.
[Go Top]
--------------------------------------------------------------------------------
问: 我是否可以用同样的方法来调整训练数据和检验数据的范围?
是的, 可以按照以下方法:
svm-scale -s scaling_parameters train_data > scaled_train_data
svm-scale -r scaling_parameters test_data > scaled_test_data
[Go Top]
--------------------------------------------------------------------------------
问:将属性值限制到[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]规划保持了输入数据的稀疏特性,因此可能会节省计算时间。
[Go Top]
--------------------------------------------------------------------------------
问: 预测准确率很低,应该如何改进?
可以用python目下的grid.py来寻找合适的参数,grid.py是一个用来选择模型参数的工具。关于模型选择的重要性,你可以参考我的谈话: A practical guide to support vector classification
[Go Top]
--------------------------------------------------------------------------------
问: 我的数据是不平衡的,libsvm能解决这样的问题吗?
可以。libsvm有一个-wi选项。例如,你用:
svm-train -s 0 -c 10 -w1 1 -w-1 5 data_file
则对类别“-1”的惩罚就较大。注意-w选项仅用在C-SVC中。
[Go Top]
--------------------------------------------------------------------------------
问: nu-SVC和C-SVC有什么不同之处?
除了参数不同外,两者基本是一样的。C-SVC中,C的范围是0到无穷,nu-SVC中C的范围是[0 1]。 nu一个很好的特性是:它与支持向量的比率和训练误差的比率相关。
[Go Top]
--------------------------------------------------------------------------------
问: 程序一直运行,但却没有输出,应该怎么办?
你最好检查一下数据. 每一个训练/学习的数据都必须在一行,不可以分开。此外,你必须删除空行。
[Go Top]
--------------------------------------------------------------------------------
问: 程序一直运行(有输出,比如许多点)。应该怎么办?
从理论上讲,如果核矩阵式半正定的,libsvm可以保证收敛。2.4以后版本的libsvm还可以处理非半正定矩阵核,比如sigmoid(tanh)核。这样看来,你处理的情况是病态情况(比如参数过大或过小),这样机会发生数值困难。
[Go Top]
--------------------------------------------------------------------------------
问: 训练时间太长,应该怎么办?
对于大型问题,请确保有足够的缓存空间(即-m)。对于一些困难的情况(比如-c很大),会出现收敛很慢的情况. 你可以常识用一个较大点的终止可容忍偏差. 如果这样仍然不行,你可以和我们联系。我们会告诉你一些关于改善训练时间短小技巧。
[Go Top]
--------------------------------------------------------------------------------
问:我如何才能得到判决值?
对于回归,程序可以打印出判决值。对于分类,可以通过解几个二进制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)
[Go Top]
--------------------------------------------------------------------------------
问:怎样得到一个点到超平面的距离?
距离的表达式为: |decision_value| / |w|.我们有: |w|^2 = w^Tw = alpha^T Q alpha = 2*(dual_obj + sum alpha_i). 因此在svm.pp文件中,知道输出对偶目标值的语句,在后面加上打印输出 w^Tw的语句就可以了.
[Go Top]
--------------------------------------------------------------------------------
问:在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下载.
[Go Top]
--------------------------------------------------------------------------------
问:: 怎样才可以不让svm-train 和svm-predict 在屏幕上输出?
只要将svm.cpp中的:
#if 1
void info(char *fmt,...)
改为:
#if 0
void info(char *fmt,...)
[Go Top]
--------------------------------------------------------------------------------
问:我想用自己的核函数,但我发现两个核函数赋值子程序 k_function()和kernel_function().我应该修改哪个?
我们采用两个函数地原因是: 对于RBF核函数exp(-g |xi - xj|^2),如果我们先计算xi - xj然后平方,将有3n步操作.因此我们先考虑exp(-g (|xi|^2 - 2dot(xi,xj) +|xj|^2)),并先计算所有的|xi|^2,这样计算步骤将减小到2vn。这是对于训练,但是对于预测我们不能这样做,因此必须用一个有3n个步骤的常规子程序。如果你想使用自己的核函数,最简单的办法是:用你核函数的代码替换两个子程序中的任何一个核函数的代码。.
[Go Top]
--------------------------------------------------------------------------------
问:对于多分类SVM,libsvm采用的是什么方法 ? 为什么不用"1-against-the rest" 法 ?
对于多分类,我们采用的是1against 1法.我们的选择建立在以下对比的基础上: C.-W. Hsu and C.-J. Lin. A comparison of methods for multi-class support vector machines , IEEE Transactions on Neural Networks, 13(2002), 415-425.
"1agains1the rest"是个很好的方法,而且分类效果和"1-against-1."可以相比。但是我们采用后者,因为它训练的时间更短。
[Go Top]
--------------------------------------------------------------------------------
:做完交叉检验以后,为什么没有模型文件输出?
交叉检验只是为了寻找好的参数,寻找完后,你必须在不用-v选项的情况下,重新训练整个数据,才会得到模型文件。
[Go Top]
--------------------------------------------------------------------------------
问:对于交叉检验,我想使用随机划分,应该如何操作?
如果你用的是 GNU C库,默认的种子是1.因此你在运行svm-train -v后,总是得到相同的结果. 想用不同的种子,你可在svm-train.c中添加如下代码:
#include <time.h>
在子程序 do_cross_validation()的开始部分添加,
srand(time(0));
[Go Top]
--------------------------------------------------------------------------------
问:如果我想解决L2-svm 问题(即二次方误差项). 我应该怎样修改代码 ?
这十分简单. 以c-svc为例, 在svm.cpp中只要修改两个地方即可.
第一, 将solve_c_svc中的:
s.Solve(l, SVC_Q(*prob,*param,y), minus_ones, y,
alpha, Cp, Cn, param->eps, si, param->shrinking);
修改为:
s.Solve(l, SVC_Q(*prob,*param,y), minus_ones, y,
alpha, INF, INF, param->eps, si, param->shrinking);
第二:在SVC_Q类中, 声明C为私有变量:
double C;
在构造(constructor)中,将它赋给param.C:
this->C = param.C;
在子程序get_Q中, 在for循环之后,添加:
if(i >= start && i < len)
data[i] += 1/C;
对于一分类svm,以上修改完全一样。对于SVR,上面的if语句就没有必要了,你只要用一个简单的赋值语句即可:
data[real_i] += 1/C;