LibSVM 的准确度下降

Posted

技术标签:

【中文标题】LibSVM 的准确度下降【英文标题】:Accuracy of LibSVM decreases 【发布时间】:2012-02-15 05:51:16 【问题描述】:

得到我的 testlabel 和 trainlabel 后,我在 libsvm 上实现了 SVM,我得到了 97.4359% 的准确率。 ( c = 1 和 g = 0.00375)

model = svmtrain(TrainLabel, TrainVec, '-c 1 -g 0.00375');
[predict_label, accuracy, dec_values] = svmpredict(TestLabel, TestVec, model);

找到最好的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(TrainLabel,TrainVec, 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 = 0.125

我再次实现模型:

 model = svmtrain(TrainLabel, TrainVec, '-c 8 -g 0.125');
[predict_label, accuracy, dec_values] = svmpredict(TestLabel, TestVec, model);

我得到了 82.0513% 的准确率

如何降低准确性?不应该增加吗?还是我做错了什么?

【问题讨论】:

我不熟悉 LibSVM 的 Matlab API,但你确定 cv = svmtrain(TrainLabel,TrainVec, cmd); 会给你准确率吗? 这是他们在 LIBSVM 常见问题解答中给出的:csie.ntu.edu.tw/~cjlin/libsvm/faq.html 在我如何使用 MATLAB 接口进行参数选择? 【参考方案1】:

您在参数调优期间获得的准确度偏高,因为您预测的数据与您正在训练的数据相同。这对于参数调整通常很好。

但是,如果您希望这些准确度能够准确估计最终测试集上的真实泛化误差,那么您必须添加额外的交叉验证或其他重采样方案。

这是一篇非常清晰的论文,概述了一般问题(但在特征选择的类似背景下):http://www.pnas.org/content/99/10/6562.abstract

编辑

我通常会添加交叉验证,例如:

n     = 95 % total number of observations
nfold = 10 % desired number of folds

% Set up CV folds
inds = repmat(1:nfold, 1, mod(nfold, n))
inds = inds(randperm(n))

% Loop over folds
for i = 1:nfold
  datapart = data(inds ~= i, :)

  % do some stuff

  % save results
end

% combine results

【讨论】:

如何添加额外的交叉验证包? 只是为了澄清:LIBSVM 不这样做吗?您只需要输入“-v n”,其中 n 是折叠数。 是的,它可以...我只是不熟悉 libsvm 的 MATLAB 接口。这段代码是如何更普遍地做到这一点。只需确保有 2 层 CV……所以对于这些外部/外部折叠中的每一个,都会有一整套单独的调整 CV 折叠。如果你做 10 倍的 CV,那就意味着 10*10 = 100 倍。 额外的层是交叉验证的额外包装。我说的对吗?【参考方案2】:

要进行交叉验证,您应该拆分训练数据。在这里,您测试训练数据以找到您的最佳参数集。这不是一个好的衡量标准。您应该使用以下伪代码:

for param = set of parameter to test
  [trainTrain,trainVal] = randomly split (trainSet); %%% you can repeat that several times and take the mean accuracy
  model = svmtrain(trainTrain, param);
  acc = svmpredict(trainVal, model);
  if accuracy is the best
     bestPAram = param
  end
end

【讨论】:

这是他们在 LIBSVM 常见问题解答中给出的:csie.ntu.edu.tw/~cjlin/libsvm/faq.html 如何使用 MATLAB 接口进行参数选择?

以上是关于LibSVM 的准确度下降的主要内容,如果未能解决你的问题,请参考以下文章

使用 LIBSVM 进行分类的 100% 准确度 - 可能有啥问题?

LIBSVM:未知的预测标签给出的准确度为 0%

帮助——LibSVM 100% 的准确度?

如何使用 Libsvm - SVM_Predict.exe 计算“准确度”

为啥 LibSvm 准确率不超过 50%?

libsvm 准确吗?