17

我知道交叉验证用于选择好的参数。找到它们后,我需要在没有 -v 选项的情况下重新训练整个数据。

但我面临的问题是,在我使用 -v 选项进行训练后,我得到了交叉验证准确度(例如 85%)。没有模型,我看不到 C 和 gamma 的值。在这种情况下,我该如何重新培训?

顺便说一句,我应用了 10 倍交叉验证。例如

optimization finished, #iter = 138
nu = 0.612233
obj = -90.291046, rho = -0.367013
nSV = 165, nBSV = 128
Total nSV = 165
Cross Validation Accuracy = 98.1273%

需要一些帮助。

为了获得最好的 C 和 gamma,我使用了 LIBSVM FAQ 中提供的这段代码

bestcv = 0;
for log2c = -6:10,
  for log2g = -6:3,
    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('(best c=%g, g=%g, rate=%g)\n',bestc, bestg, bestcv);
  end
end

另一个问题:使用 -v 选项后的交叉验证准确性是否类似于我们在没有 -v 选项的情况下进行训练并使用该模型进行预测时得到的准确性?这两个精度相似吗?

另一个问题:交叉验证通过避免过度拟合基本上提高了模型的准确性。因此,在改进之前,它需要有一个模型。我对吗?除此之外,如果我有不同的模型,那么交叉验证的准确性会有所不同吗?我对吗?

再问一个问题:在交叉验证准确率中,C 和 gamma 的值是多少呢?

图表是这样的 在此处输入图像描述

那么 C 的值为 2 并且 gamma = 0.0078125。但是当我用新参数重新训练模型时。该值与 99.63% 不同。有什么理由吗?提前致谢...

4

2 回答 2

31

这里的-v选项实际上是为了避免过度拟合问题(而不是使用整个数据进行训练,而是对折叠执行 N 折交叉验证训练N-1并在剩余折叠上进行测试,一个 at-a-时间,然后报告平均准确度)。因此,它仅将交叉验证精度(假设您有分类问题,否则回归的均方误差)作为标量数而不是实际的 SVM 模型返回。

如果要执行模型选择,则必须使用交叉验证(类似于helper python 脚本)实现网格搜索,以找到和grid.py的最佳值。Cgamma

这应该不难实现:使用 MESHGRID 创建一个值网格,使用(C,gamma)5 折交叉验证对所有对训练 SVM 模型进行整体迭代,并选择具有最佳 CV 精度的值......

例子:

%# read some training data
[labels,data] = libsvmread('./heart_scale');

%# grid of parameters
folds = 5;
[C,gamma] = meshgrid(-5:2:15, -15:2:3);

%# grid search, and cross-validation
cv_acc = zeros(numel(C),1);
for i=1:numel(C)
    cv_acc(i) = svmtrain(labels, data, ...
                    sprintf('-c %f -g %f -v %d', 2^C(i), 2^gamma(i), folds));
end

%# pair (C,gamma) with best accuracy
[~,idx] = max(cv_acc);

%# contour plot of paramter selection
contour(C, gamma, reshape(cv_acc,size(C))), colorbar
hold on
plot(C(idx), gamma(idx), 'rx')
text(C(idx), gamma(idx), sprintf('Acc = %.2f %%',cv_acc(idx)), ...
    'HorizontalAlign','left', 'VerticalAlign','top')
hold off
xlabel('log_2(C)'), ylabel('log_2(\gamma)'), title('Cross-Validation Accuracy')

%# now you can train you model using best_C and best_gamma
best_C = 2^C(idx);
best_gamma = 2^gamma(idx);
%# ...

等高线图

于 2012-01-28T22:34:32.687 回答
1

如果您使用整个数据集来确定参数,然后在该数据集上进行训练,您将过度拟合您的数据。理想情况下,您将划分数据集,对一部分(使用 CV)进行参数搜索,然后使用另一部分使用 CV 进行训练和测试。如果你同时使用整个数据集,你会得到更好的结果吗?当然,但是您的模型可能无法很好地概括。如果要确定模型的真实性能,则需要单独进行参数选择。

于 2012-02-27T08:22:19.840 回答