我想执行交叉验证,为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);
答案 0 :(得分:1)
根据您的描述,在不阅读代码的情况下,听起来您没有进行交叉验证。交叉验证要求您选择参数集(即C
和gamma
的值)并保持这些参数不变,使用k-1
折叠进行训练,1
折叠以进行测试并执行此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,则为其他内容)。如果您使用循环来更改哪些折叠用作训练集,那就没问题。但是,您已使用它们来更改gamma
和C
参数的值,这是不正确的。但是,您稍后致电min(cv_acc);
,因此我现在猜测您认为对smvtrain
的调用实际上是否返回了培训错误?我不知道如何在一系列结构上有意义地调用min
,但我可能错了。但即便如此,您实际上并不想最大限度地减少训练错误,您希望最大限度地减少交叉验证错误,这是您k
运行中 test 错误的总和并且与您的培训错误无关。
现在我们无法确切地知道你是否已经做错了,因为你没有向我们展示gamma
和C
的向量,但它是&#39 ;奇怪的是只有1个循环而不是嵌套循环来迭代这些(除非你把它们安排成真值表,但我怀疑)。您需要测试与C
的每个值配对的gamma
的每个潜在值。目前,您似乎只为gamma
中的每个值尝试了C
的1个不同值。
查看this answer以查看与SVM一起使用的交叉验证示例。