关于SVM参数的优化选取,国际上并没有公认统一的最好的方法,现在目前常用的方法就是让c和g在一定的范围内取值,对于取定的c和g对于把训练集作为原始数据集利用K-CV方法得到在此组c和g下训练集验证分类准确率,最终取使得训练集验证分类准确率最高的那组c和g做为最佳的参数,但有一个问题就是可能会有多组的c和g对应于最高的验证分类准确率,这种情况怎么处理?这里采用的手段是选取能够达到最高验证分类准确率中参数c最小的那组c和g做为最佳的参数,如果对应最小的c有多组g,就选取搜索到的第一组c和g做为最佳的参数。这样做的理由是:过高的c会导致过学习状态发生,即训练集分类准确率很高而测试集分类准确率很低(分类器的泛化能力降低),所以在能够达到最高验证分类准确率中的所有的成对的c和g中认为较小的惩罚参数c是更佳的选择对象。
- 以上的寻参思想在libsvm-mat-2.89-3[FarutoUltimate3.0]工具箱中已经实现SVMcgForClass.m (分类问题寻优)、SVMcgForRegress.m (回归问题参数寻优):
- [bestCVaccuracy,bestc,bestg]=SVMcgForClass(train_label,train,cmin,cmax,gmin,gmax,v,cstep,gstep,accstep)
输入:
train_label:训练集的标签,格式要求与svmtrain相同。
train:训练集,格式要求与svmtrain相同。
cmin,cmax:惩罚参数c的变化范围,即在[2cmin,2cmax]范围内寻找最佳的参数c,默认值为cmin=-8,cmax=8,即默认惩罚参数c的范围是[2(-8),28]。
gmin,gmax:RBF核参数g的变化范围,即在[2gmin,2gmax]范围内寻找最佳的RBF核参数g,默认值为gmin=-8,gmax=8,即默认RBF核参数g的范围是[2(-8),28]。
v:进行Cross Validation过程中的参数,即对训练集进行v-fold Cross Validation,默认为3,即默认进行3折CV过程。
cstep,gstep:进行参数寻优是c和g的步进大小,即c的取值为2cmin,2(cmin+cstep),…,2cmax,,g的取值为2gmin,2(gmin+gstep),…,2gmax,默认取值为cstep=1,gstep=1。
accstep:最后参数选择结果图中准确率离散化显示的步进间隔大小([0,100]之间的一个数),默认为4.5。
输出:
bestCVaccuracy:最终CV意义下的最佳分类准确率。
bestc:最佳的参数c。
bestg:最佳的参数g。 - 网格参数寻优函数(回归问题):SVMcgForRegress[bestCVmse,bestc,bestg]= SVMcgForRegress(train_label,train,cmin,cmax,gmin,gmax,v,cstep,gstep,msestep)
其输入输出与SVMcgForClass类似,这里不再赘述。
%% IV. SVM模型创建/训练
%%
% %首先进行粗略选择:
% [bestmse,bestc,bestg] = SVMcgForRegress(tn_train,pn_train,-8,8,-8,8);
%
% % 打印粗略选择结果
% disp(‘打印粗略选择结果’);
% str = sprintf( ‘Best Cross Validation MSE = %g Best c = %g Best g = %g’,bestmse,bestc,bestg);
% disp(str);
%
% % 根据粗略选择的结果图再进行精细选择:
% [bestmse,bestc,bestg] = SVMcgForRegress(tn_train,pn_train,-4,4,-4,4,3,0.5,0.5,0.05);
%
% % 打印精细选择结果
% disp(‘打印精细选择结果’);
% str = sprintf( ‘Best Cross Validation MSE = %g Best c = %g Best g = %g’,bestmse,bestc,bestg);
% disp(str);
%%
% 2. 创建/训练SVM
cmd= [’ -t 2’,’ -c 1.4142’,’ -g 0.0625’,’ -s 3 -p 0.01’];
%cmd = [’ -t 2’,’ -c ‘,num2str(bestc),’ -g ‘,num2str(bestg),’ -s 3 -p 0.01’];
model = svmtrain(tn_train,pn_train,cmd);
%% V. SVM仿真预测
[Predict_1,error_1,dec_values] = svmpredict(tn_train,pn_train,model);
[Predict_2,error_2,dec_values] = svmpredict(tn_test,pn_test,model);
%%
% 1. 反归一化
predict_1 = mapminmax(‘reverse’,Predict_1,outputps);
predict_2 = mapminmax(‘reverse’,Predict_2,outputps);