如果你已经看完并理解了我的上一篇SVM的博客,那么接下来你要面对的是怎么应用SVM这个实际的问题,现在SVM里面应用最广泛的就是LIBSVM这个函数库,OpenCV中也基于LIBSVM推出了CvSVM 的函数。因此下面的内容,我主要是介绍一下LIBSVM的应用方法,主要是参考文献[1,2]。
LIBSVM是国立台湾大学 Chih-Jen Lin开发的一个SVM的函数库,他不但提供了编译好的可在Windows系列系统的执行文件,还提供了源代码,方便改进、修改以及在其它操作系统上应用;该软件对SVM所涉及的参数调节相对比较少,提供了很多的默认参数,利用这些默认参数可以解决很多问题;并提供了交互检验(Cross Validation)的功能。该软件包可在http://www.csie.ntu.edu.tw/~cjlin/免费获得。该软件可以解决C-SVM、ν-SVM、ε-SVR和ν-SVR等问题,包括基于一对一算法的多类模式识别问题。
上一篇博客中谈的内容是从理论出发的东西,但是在实际应用中,我们常常无法找到一个完美无缺的判别超平面,那么为了能够在这样子的不可分的集合中学习支持向量机,需要引入软间隔(soft margin)来进行分类,即是允许一些训练模式停留在判别超平面的“错误”一侧,或者说允许其他类的模式停留在间隔内,则上一篇博客中的公式(3)修改为:
其中为松弛变量,对应数据点偏离对应的间隔面(非分类超平面)的距离(见图1)。因此,最终的结果是margin可以比1小,但是当某些点出现这种margin比1小的情况时(这些点也称离散点),意味着我们放弃啦对这些点的精确分类,而这对分类器来说是一种损失,但是放弃这些点也带来了好处,就是分类面不必向这些点的方向移动,因而可以得到更大的几何margin。显然,我们必须权衡这种损失和好处。好处是明显的,我们得到的分类间隔越大,好处就越多。
图1 松弛变量
下面还有几点需要注意:
现在,我们来看看在实际应用中的C-SVM:
文献[1]中推荐的SVM使用步骤如下:
描述如下:
Data Preprocessing
Categorical Feature
SVM要求数据实例是实数向量,因此,我们必须先把它的类别特征转换成数值特征。这里推荐使用m个值去代表m类的特征。例如,一个三类特征{red,green,blue}可以表示成(0,0,1)(0,1,0)(1,0,0)。经验表明,当类别不是非常大时,这种特征类别编码方式更稳定
Scaling
Scaling在SVM中非常重要,这里推荐使用linearly scaling each attribute to the range [-1,+1] or [0,1]。
Model Selection
RBF Kernel
一般情况下,RBF Kernel 是一个合理的第一选择,可以首先尝试这个核函数。
Cross-validation and Grid-search
RBF核函数有两个参数:C和Gamma。针对一个给定的问题,需要通过参数搜索方法来获取他们的最优值。一个常用的方法是将训练数据分成2个部分,其中一部分为“未知的”,通过对未知数据的分类效果来反映系统分类性能。该方法的一个提升版本就是Cross-validation交叉验证。在v-fold交叉验证中,我们首先将数据分成v组,将每个子集分别做一次测试集,其余v-1组作为训练集,这样就会得到v个模型,用这v个模型最终的测试集的分类准确率作为v-fold cross-validation分类性能的指标。这里我们推荐使用“grid-search”,即尝试各个参数对(C,gamma),我们发现使用指数增长能更快找到最佳参数值。如
C = 2^(-5) 2^(-3) .... 2^15
gamma = 2^(-15) 2^(-13) ... 2^3
————————————————————————————————————————————————————————————
下面,我贴一个用SVM进行人脸识别的例子(效果很不好,特征和参数没细调)
close all; clc; clear; num = 25; M = 112;N = 92;accu = 0; suma = zeros(28,28); Gt = zeros(28,28); for ii = 1:1:num for k = 1:9 name1 = strcat('s',num2str(ii)); name2 = strcat(name1,'\'); name3 = strcat(num2str(k),'.bmp'); name4 = strcat(name2,name3); name = strcat('E:\快盘\文献阅读\DATAbase\ORLFACE\',name4); I = imread(name); if ndims(I)==3 I = rgb2gray(I); end I_re = imresize(I,[112 112]); temp = double(I_re(1:4:112,1:4:112)); suma = suma+temp; end end aver_A = suma/(num*9); for ii = 1:1:num for k =1:9 name1 = strcat('s',num2str(ii)); name2 = strcat(name1,'\'); name3 = strcat(num2str(k),'.bmp'); name4 = strcat(name2,name3); name = strcat('E:\快盘\文献阅读\DATAbase\ORLFACE\',name4); I=imread(name); if ndims(I)==3 I = rgb2gray(I); end I_re = imresize(I,[112 112]); temp = double(I_re(1:4:112,1:4:112)); Gt = Gt+(temp-aver_A)'*(temp-aver_A); end end Gt = Gt/(num*9); [v,d] = eigs(Gt,25); [eigenvalues, index] = sort(diag(d),'descend'); ratio = cumsum(eigenvalues)/sum(eigenvalues); xnum = find(ratio>.98); D_num = xnum(1); index_select = index(1:D_num); V_select = zeros(size(v,1),D_num); V_select(:,1:D_num) = v(:,index_select(1:D_num)); i_oo=1; for ii = 1:1:num for k = 1:9 name1 = strcat('s',num2str(ii)); name2 = strcat(name1,'\'); name3 = strcat(num2str(k),'.bmp'); name4 = strcat(name2,name3); name = strcat('E:\快盘\文献阅读\DATAbase\ORLFACE\',name4); I = imread(name); if ndims(I)==3 I = rgb2gray(I); end I_re = imresize(I,[112 112]); temp = double(I_re(1:4:112,1:4:112)); temp2 = temp*V_select; Y_matrix(i_oo,:) = reshape(temp2,1,588); i_oo=i_oo+1; end end t_label=[]; for ii = 1:1:num for jj = 1:9 t_label =[t_label,ii]; Y_label = t_label'; end end %% 现在准备开始建立model,为predict做准备 model = svmtrain(Y_label,Y_matrix); %% 测试部分 for ii = 1:1:num k = 10; name1 = strcat('s',num2str(ii)); name2 = strcat(name1,'\'); name3 = strcat(num2str(k),'.bmp'); name4 = strcat(name2,name3); name = strcat('E:\快盘\文献阅读\DATAbase\ORLFACE\',name4); I = imread(name); if ndims(I)==3 I = rgb2gray(I); end I_re = imresize(I,[112 112]); temp = double(I_re(1:4:112,1:4:112)); tempY = temp*V_select; X_test(ii,:) = reshape(tempY,1,588); end label_temp = [1:num];X_label=label_temp'; [predict_label, accuracy, dec_values] = svmpredict(X_label,X_test,model);
参考文献
[1] Hsu C W, Chang C C, Lin C J. A practical guide to support vector classification[J]. 2003.
[2] Chang C C, Lin C J. LIBSVM: a library for support vector machines[J]. ACM Transactions on Intelligent Systems and Technology (TIST), 2011, 2(3): 27.