首页 文章

SVM回归的交叉验证

提问于
浏览
0

我想执行交叉验证,为SVR(支持向量回归)的RBF内核选择最佳参数Gamma和C.我正在使用LIBSVM . 我有一个包含4组3D网格的数据库 . 我的问题是:我使用的这种方法可以进行4倍交叉验证吗?我认为,为了选择RBF Kernal的参数C和Gamma,我必须最小化预测值和groud_truth_values之间的误差 .

我还有另一个问题,我在交叉验证时得到这个NAN值(平方相关系数= nan(回归))

这是我写的代码:

[C,gamma] = meshgrid(-5:2:15, -15:2:3); %range of values for C and 
                                        %gamma

%# grid search, and cross-validation

for m=1:numel(C)

    for k=1:4 
        fid1 = fopen(sprintf('list_learning_%d.txt',k), 'rt'); 
        i=1;

        while feof(fid1) == 0 
            tline = fgetl(fid1); 
            v= load(tline);
            v=normalize(v);
            matrix_feature_tmp(i,:)=v;
            i=i+1;
        end  

        fclose(fid1);

        % I fill matrix_feature_train of size m by n via matrix_feature_tmp

        %%construction of the test matrix
       fid2 = fopen(sprintf('liste_features_test%d.txt',k), 'rt'); 
       i=1;

       while feof(fid2) == 0 
           tline = fgetl(fid2); 
           v= load(tline);
           v=normalize(v);
           matrice_feature_test_tmp(i,:)=v;
           i=i+1;
       end  

       fclose(fid2);

       %I fill matrix_feature_test of size m by k via matrix_feature_test_tmp

       mos_learning=load(sprintf('mos_learning_%d.txt',k));
       mos_wanted=load(sprintf('mos_test%d.txt',k));

       model = svmtrain(mos_learning, matrix_feature_train',sprintf('- 
       s %f -t %f -c %f -g %f -p %f  ',3,2 ,2^C(m),2^gamma(m),1 ));

       [y_hat, Acc, projection] = svmpredict(mos_wanted,
                                  matrix_feature_test', model);
       MSE_Test = mean((y_hat-mos_wanted).^2);
       vecc_error(k)=MSE_Test;

       end
       mean_vec_error_fold(m)=mean(vecc_error);
end

%select the best gamma and C 
[~,idx]=min(mean_vec_error_fold);

best_C = 2^C(idx);
best_gamma = 2^gamma(idx);

%training with best parameters
%for example
 model = svmtrain(mos_learning1, matrice_feature_train1',sprintf('-s   
          %f -t %f -c %f -g %f -p %f  ',3,2 ,best_C, best_gamma,1 ));

[y_hat_final, Acc, projection] = svmpredict(mos_test1,matrice_feature_test1', 
                           model);

1 回答

  • 1

    根据您的描述,不读取您的代码,听起来您没有进行交叉验证 . 交叉验证要求您选择一个参数集(即 Cgamma 的值)并保持这些参数恒定使用 k-1 folds进行训练, 1 fold进行测试并执行此 k 次,以便您将每个折叠用作测试集一旦 . 然后汇总这些 k 测试的误差/准确度度量,这是用于对在所有数据上训练的模型的那些参数进行排名的度量 . 将此交叉验证错误称为您使用的参数集 . 然后,您可以针对一系列不同的参数重复此过程,并选择具有最佳精度/最低CV误差的参数集 . 您的最终模型将根据您的所有数据进行培训 .

    你的代码对我来说没有意义 . 看看这个片段

    folds = 4; 
    for i=1:numel(C)
        cv_acc(i) = svmtrain(ground_truth, matrice_feature_train', ...
                    sprintf(' -s %d -t %d -c %f -g %f -p %d -v %d',3,2, 
                    2^C(i), 2^gamma(i), 1, 4)); %Kernel RBF
    end
    

    cv_acc 包含什么?对我而言,它包含实际的SVM模型(如果使用MATLAB工具箱,则为 SVMStruct ,如果使用LIBSVM,则为其他内容) . 如果您使用循环来更改哪些折叠用作训练集,那就没问题 . 但是,您已使用它们来更改 gammaC 参数的值,这是不正确的 . 但是你以后调用 min(cv_acc); 所以我现在猜你认为对 smvtrain 的调用实际上是否返回了训练错误?我不知道你怎么能在这样的结构数组上有意义地调用 min ,但我可能错了 . 但即便如此,您实际上并不想最大限度地减少训练错误,您希望最小化交叉验证错误,这是您运行的测试错误的总和,与您的训练错误无关 .

    现在它已经完成了这个错误,因为你没有向我们展示 gammaC 的向量,但奇怪的是只有1个循环而不是嵌套循环来迭代这些(除非你把它们安排成真值表但是我不信) . 您需要测试 C 的每个潜在值,并与 gamma 的每个值配对 . 目前,您似乎只为 C 中的每个值尝试了1个不同的 gamma 值 .

    查看this answer以查看与SVM一起使用的交叉验证示例 .

相关问题