关于SVM参数c&g选取的总结帖[matlab-libsvm]

写了个程序 来选取SVM中参数 c和g的最佳值.
[写这个的目的是方便大家用这个小程序直接来寻找 c和g的最佳值,不用再另外编写东西了. 
其实原本libsvm C语言版本中有相应的子程序可以找到最佳的c和g,需装载python语言然后用py 那个画图 就可以找到最佳的c和g,我写了个matlab版本的.算是弥补了libsvm在matlab版本下的空缺. 

测试数据 还是我视频 里的wine data.

寻找最佳c和g的思想仍然是让c和g在一定的范围里跑(比如 c = 2^(-5),2^(-4),...,2^(5),g = 2^(-5),2^(-4),...,2^(5)),然后用cross validation的想法找到是的准确率最高的c和g,在这里我做了一点修改(纯粹是个人的一点小经验和想法),我改进的是: 因为会有不同的c和g都对应最高的的准确率,我把具有最小c的那组c和g认为是最佳的c和g,因为惩罚参数不能设置 太高,很高的惩罚参数能使得validation数据的准确率提高,但过高的惩罚参数c会造成过学习状态,反正从我用SVM到现在,往往都是惩罚参数c过高会导致最终测试集合的准确率并不是很理想.. 

在使用这个程序时也有小技巧,可以先大范围粗糙的找 比较理想的c和g,然后再细范围找更加理想的c和g.

比如首先让 c = 2^(-5),2^(-4),...,2^(5),g = 2^(-5),2^(-4),...,2^(5)在这个范围找比较理想的c和g,如图:
======

======
此时bestc = 0.5,bestg=1,bestacc = 98.8764[cross validation 的准确率]

最终测试集合的准确率 Accuracy = 96.6292% (86/89) (classification)
======
此时看到可以把c和g的范围缩小.还有步进的大小也可以缩小(程序里都有参数可以自己调节,也有默认值可不调节).
让 c = 2^(-2),2^(-1.5),...,2^(4),g = 2^(-4),2^(-3.5),...,2^(4)在这个范围找比较理想的c和g,如图:
=============

===============
此时bestc = 0.3536,bestg=0.7017,bestacc = 98.8764[cross validation 的准确率]
最终测试集合的准确率 Accuracy = 96.6292% (86/89) (classification)
===================
上面第二个的测试的代码

:

复制内容到剪贴板

代码:

load wine_SVM;

train_wine = [wine(1:30,:);wine(60:95,:);wine(131:153,:)];
train_wine_labels = [wine_labels(1:30);wine_labels(60:95);wine_labels(131:153)];

test_wine = [wine(31:59,:);wine(96:130,:);wine(154:178,:)];
test_wine_labels = [wine_labels(31:59);wine_labels(96:130);wine_labels(154:178)];

[train_wine,pstrain] = mapminmax(train_wine');
pstrain.ymin = 0;
pstrain.ymax = 1;
[train_wine,pstrain] = mapminmax(train_wine,pstrain);

[test_wine,pstest] = mapminmax(test_wine');
pstest.ymin = 0;
pstest.ymax = 1;
[test_wine,pstest] = mapminmax(test_wine,pstest);

train_wine = train_wine';
test_wine = test_wine';

[bestacc,bestc,bestg] = SVMcg(train_wine_labels,train_wine,-2,4,-4,4,3,0.5,0.5,0.9);

cmd = ['-c ',num2str(bestc),' -g ',num2str(bestg)];
model = svmtrain(train_wine_labels,train_wine,cmd);
[pre,acc] = svmpredict(test_wine_labels,test_wine,model);

============我写的那个选取SVM中参数c和g的最佳值.的程序的代码  SVMcg.m====================

复制内容到剪贴板

代码:

function [bestacc,bestc,bestg] = SVMcg(train_label,train,cmin,cmax,gmin,gmax,v,cstep,gstep,accstep)
%SVMcg cross validation by faruto
%Email:farutoliyang@gmail.com QQ:516667408 http://blog.sina.com.cn/faruto BNU
%last modified 2009.8.23
%Super Moderator @ www.ilovematlab.cn
%% about the parameters of SVMcg 
if nargin < 10
    accstep = 1.5;
end
if nargin < 8
    accstep = 1.5;
    cstep = 1;
    gstep = 1;
end
if nargin < 7
    accstep = 1.5;
    v = 3;
    cstep = 1;
    gstep = 1;
end
if nargin < 6
    accstep = 1.5;
    v = 3;
    cstep = 1;
    gstep = 1;
    gmax = 5;
end
if nargin < 5
    accstep = 1.5;
    v = 3;
    cstep = 1;
    gstep = 1;
    gmax = 5;
    gmin = -5;
end
if nargin < 4
    accstep = 1.5;
    v = 3;
    cstep = 1;
    gstep = 1;
    gmax = 5;
    gmin = -5;
    cmax = 5;
end
if nargin < 3
    accstep = 1.5;
    v = 3;
    cstep = 1;
    gstep = 1;
    gmax = 5;
    gmin = -5;
    cmax = 5;
    cmin = -5;
end
%% X:c Y:g cg:acc
[X,Y] = meshgrid(cmin:cstep:cmax,gmin:gstep:gmax);
[m,n] = size(X);
cg = zeros(m,n);
%% record acc with different c & g,and find the bestacc with the smallest c
bestc = 0;
bestg = 0;
bestacc = 0;
basenum = 2;
for i = 1:m
    for j = 1:n
        cmd = ['-v ',num2str(v),' -c ',num2str( basenum^X(i,j) ),' -g ',num2str( basenum^Y(i,j) )];
        cg(i,j) = svmtrain(train_label, train, cmd);
        
        if cg(i,j) > bestacc
            bestacc = cg(i,j);
            bestc = basenum^X(i,j);
            bestg = basenum^Y(i,j);
        end
        if ( cg(i,j) == bestacc && bestc > basenum^X(i,j) )
            bestacc = cg(i,j);
            bestc = basenum^X(i,j);
            bestg = basenum^Y(i,j);
        end
        
    end
end
%% to draw the acc with different c & g
[C,h] = contour(X,Y,cg,60:accstep:100);
clabel(C,h,'FontSize',10,'Color','r');
xlabel('log2c','FontSize',10);
ylabel('log2g','FontSize',10);
grid on;

=====================================


这样那个libsvm-matlab工具箱 我就有了自己的一个升级版本的了.大家可以把这个SVMcg.m加进去 一起用了...

里面有SVMcg.m使用说明.如下:
[bestacc,bestc,bestg] = SVMcg(train_label,train,cmin,cmax,gmin,gmax,v,cstep,gstep,accstep)

train_label:训练 集标签.要求与libsvm工具箱中要求一致.
train:训练集.要求与libsvm工具箱中要求一致.
cmin:惩罚参数c的变化范围的最小值(取以2为底的对数后),即 c_min = 2^(cmin).默认为 -5
cmax:惩罚参数c的变化范围的最大值(取以2为底的对数后),即 c_max = 2^(cmax).默认为 5
gmin:参数g的变化范围的最小值(取以2为底的对数后),即 g_min = 2^(gmin).默认为 -5
gmax:参数g的变化范围的最小值(取以2为底的对数后),即 g_min = 2^(gmax).默认为 5

v:cross validation的参数,即给测试集分为几部分进行cross validation.默认为 3
cstep:参数c步进的大小.默认为 1
gstep:参数g步进的大小.默认为 1
accstep:最后显示准确率图时的步进大小. 默认为 1.5
[上面这些参数大家可以更改以期达到最佳效果,也可不改用默认值] 


 

  • 3
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
MATLAB 中使用 libsvm 库进行 SVM 参数 C 和 Gamma 的调优可以使用 `libsvmtrain` 函数和 `libsvmpredict` 函数结合交叉验证来实现。以下是一个示例代码: ```matlab % 加载数据 load fisheriris X = meas(:,3:4); Y = species; % 定义参数搜索范围 Cs = 2.^(-5:15); Gammas = 2.^(-15:3); % 定义交叉验证模型 cv = cvpartition(Y,'KFold',10); % 初始化最优参数 bestC = NaN; bestGamma = NaN; bestAccuracy = 0; % 开始参数搜索 for i = 1:length(Cs) for j = 1:length(Gammas) % 定义 SVM 参数 svm_options = sprintf('-c %g -g %g', Cs(i), Gammas(j)); % 训练模型 model = libsvmtrain(Y, X, svm_options); % 计算交叉验证准确率 accuracy = sum(libsvmpredict(Y(cv.training(i)), X(cv.training(i),:), model)==Y(cv.training(i)))/sum(cv.training(i)); % 更新最优参数 if accuracy > bestAccuracy bestAccuracy = accuracy; bestC = Cs(i); bestGamma = Gammas(j); end end end % 输出最优参数 fprintf('Best C = %g, Best Gamma = %g, Cross-Validation Accuracy = %g\n',bestC,bestGamma,bestAccuracy); ``` 在这个示例代码中,我们加载了鸢尾花数据集,定义了参数搜索范围和交叉验证模型。接着,我们使用双重循环来搜索最优参数,并使用交叉验证来评估每个参数组合的准确率。最后,输出最优参数和交叉验证准确率。 需要注意的是,这个示例代码中使用的是 RBF 核函数。如果你使用的是其他核函数,需要相应地修改 SVM 参数。另外,这个示例代码中使用的是 K-Fold 交叉验证,如果你想使用其他交叉验证方法,也需要相应地修改代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值