如果你已经看完并理解了我的上一篇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.