如何使用 libsvm matlab 固定参数成本和伽玛来提高准确性?

Posted

技术标签:

【中文标题】如何使用 libsvm matlab 固定参数成本和伽玛来提高准确性?【英文标题】:how can fixed parameters cost and gamma using libsvm matlab to improve accuracy? 【发布时间】:2015-09-20 09:19:27 【问题描述】:

我使用 libsvm 对包含 1000 个标签的数据库进行分类。我是 libsvm 的新手,我发现选择参数 c 和 g 来提高性能的问题。首先,这是我用来设置参数的程序:

  bestcv = 0;
for log2c = -1:3,
 for log2g = -4:1,
  cmd = ['-v 5 -c ', num2str(2^log2c), ' -g ', num2str(2^log2g)];
  cv = svmtrain(yapp, xapp, cmd);
  if (cv >= bestcv),
   bestcv = cv; bestc = 2^log2c; bestg = 2^log2g;
 end
  fprintf('%g %g %g (best c=%g, g=%g, rate=%g)\n', log2c, log2g, cv, bestc, bestg, bestcv);
end
end

因此,该程序给出 c = 8 和 g = 2,当我使用这些值时 c 和 g,我发现准确率为 55%。对于分类,我使用 svm one against all。

 numLabels=max(yapp);
 numTest=size(ytest,1);

   %# train one-against-all models
    model = cell(numLabels,1);
   for k=1:numLabels
      modelk = svmtrain(double(yapp==k),xapp, '  -c 1000 -g 10 -b 1 ');
    end

 %# get probability estimates of test instances using each model
 prob_black = zeros(numTest,numLabels);
   for k=1:numLabels
     [~,~,p] = svmpredict(double(ytest==k), xtest, modelk, '-b 1');
     prob_black(:,k) = p(:,modelk.Label==1);    %# probability of class==k
   end

 %# predict the class with the highest probability
 [~,pred_black] = max(prob_black,[],2);
 acc = sum(pred_black == ytest) ./ numel(ytest)    %# accuracy

问题是我需要更改这些参数以提高性能。例如,当我随机输入 c = 10000 和 g = 100 时,我发现了一个更好的准确率:70%。

请问我需要帮助,如何设置这些参数(c 和 g)以找到最佳准确率?提前谢谢你

【问题讨论】:

我不知道为什么人们投票结束这个问题。它具有统计内容:如何为 SVM 选择最佳超参数。仅仅因为 OP 还包含代码并不意味着它不适合这个论坛。 【参考方案1】:

超参数调优是机器学习中的一个重要问题。最简单的方法是您已经实现的方法:定义值网格,并在网格上计算模型,直到找到一些最佳组合。一个关键假设是网格本身是表面的一个很好的近似:它足够好,不会错过任何重要的东西,但又不会浪费时间计算与相邻值基本相同的值。一般来说,我不知道有什么方法可以提前知道网格的必要性。如图所示:假设全局最优值在 $(5,5)$ 并且函数在其他地方基本上是平坦的。如果您的网格是 $(0,0),(0,10),(10,10),(0,10)$,您将完全错过最佳值。同样,如果网格是 $(0,0), (-10,-10),(-10,0),(0,-10)$,那么您永远不会接近最佳值。在这两种情况下,您都没有希望自己找到最佳值。

对于带有 RBF 内核的 SVM,存在一些经验法则:$\gamma\in\2^-15,2^-14,...,2^5\$ 的网格而 $C \in \2^-5, 2^-4,...,2^15\$ 就是这样的推荐之一。

如果您在测试的网格值范围之外找到了更好的解决方案,这表明您应该定义一个更大的网格。但是较大的网格需要更多时间来评估,因此您要么必须承诺等待一段时间才能获得结果,要么转向更有效的方法来探索超参数空间。

另一种选择是随机搜索:定义要尝试的 SVM 数量的“预算”,并生成要测试的随机元组。这种方法主要用于基准测试目的,因为它完全不智能。

网格搜索和随机搜索都具有易于并行实现的优点。

更好的选择属于全局优化领域。 Marc Claeson 等人设计了Optunity 包,它使用粒子群优化。我的研究集中在高效全局优化算法 (EGO) 的改进上,该算法建立了一个高斯过程作为超参数响应面的近似值,并使用它来做出有根据的预测,即哪些超参数元组最有可能在当前的基础上得到改进最佳估计。

假设您已经在某个超参数元组 $(\gamma, C)$ 上评估了 SVM,并且它具有一些样本外性能指标 $y$。受 EGO 启发的方法的一个优点是它假设 $(\gamma,C)$ 附近的值 $y^*$ 将“接近”$y$,因此我们不一定需要花时间探索那些附近的元组,特别是如果 $y-y_min$ 非常大(其中 $y_min$ 是我们发现的最小 $y$ 值)。 EGO 将在它估计有很大改进可能性的点上识别和评估 SVM,因此它将智能地在超参数空间中移动:在理想情况下,它将跳过性能低下的区域而专注于高性能区域。

【讨论】:

谢谢你的回复,但是这句话是什么意思''希望你的网格足够好/足够大,不会错过更好的元组“,我怎么能假设这个? 感谢您对答案的澄清,我认为这是我的问题。你能帮我解决这个问题吗? @yosra 我的回答提供了四种解决方案:搜索更大的网格、使用随机搜索、使用粒子群优化或使用 EGO。

以上是关于如何使用 libsvm matlab 固定参数成本和伽玛来提高准确性?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中移植 MATLAB libSVM 参数

libsvm 交叉验证与 matlab 中的预计算内核

在 Matlab 的 LibSVM 中指定权重

如何在 Matlab 中使用 libsvm?

Matlab中两个同名函数

如何设置 LIBSVM Matlab 接口?