通过交叉验证方法利用训练集找到分类的最佳参数,不但能够高淮确率的预测训练集而且要合理的预测测试集,使得测试集的分类准确率也维持在一个较高水平,即使得得到的SVM分类器的学习能力和推广能力保持一个平衡.避免过学习和欠学习状況发生。
交叉验证方法就是让c和g在一定的范围内取值,对于取定得c和g把训练集作为原始数裾集利用K - CV方法得到在此组c和g下训练集验证分类准确率,最终取使得训练集验证分类准确率最高的那组c和g做为最佳的参数,但有一个问题就是可能会有多组的c和g对应于最高的验证分类准确率,这种情况怎么处理?这里采用的手段是选取能够适到最高验证分类准确率巾参数r最小的那组c和g做为最佳的参数,如果对应最小的c有多组g,就选取搜索到的第一组c和g做为最佳的参数。这样做的理由是:过高的c会导致过学习状态发生,即训练集分类准确率很高而测试集分类准确率很低(分类器的泛化能力降低),所以在能够达到最高验证分类准确率中的所有的成对的c和g中认为较小的惩罚参数c是更佳的选择对象。
%% 清空环境变量
clear
clc
%% 导入数据
load BreastTissue_data.mat
% 随机产生训练集和测试集
n = randperm(size(matrix,1));
% 训练集——80个样本
train_matrix = matrix(n(1:80),:);
train_label = label(n(1:80),:);
% 测试集——26个样本
test_matrix = matrix(n(81:end),:);
test_label = label(n(81:end),:);
%% 数据归一化
[Train_matrix,PS] = mapminmax(train_matrix');
Train_matrix = Train_matrix';
Test_matrix = mapminmax('apply',test_matrix',PS);
Test_matrix = Test_matrix';
%% SVM创建/训练(RBF核函数)
% 寻找最佳c/g参数——交叉验证方法
[c,g] = meshgrid(-10:0.2:10,-10:0.2:10);
[m,n] = size(c);
cg = zeros(m,n);
eps = 10^(-4);
v = 5;
bestc = 1;
bestg = 0.1;
bestacc = 0;
for i = 1:m
for j = 1:n
cmd = ['-v ',num2str(v),' -t 2',' -c ',num2str(2^c(i,j)),' -g ',num2str(2^g(i,j))];
cg(i,j) = svmtrain(train_label,Train_matrix,cmd);
if cg(i,j) > bestacc
bestacc = cg(i,j);
bestc = 2^c(i,j);
bestg = 2^g(i,j);
end
if abs( cg(i,j)-bestacc )<=eps && bestc > 2^c(i,j)
bestacc = cg(i,j);
bestc = 2^c(i,j);
bestg = 2^g(i,j);
end
end
end
cmd = [' -t 2',' -c ',num2str(bestc),' -g ',num2str(bestg)];
% 创建/训练SVM模型
model = svmtrain(train_label,Train_matrix,cmd);
%% SVM仿真测试
[predict_label_1,accuracy_1] = svmpredict(train_label,Train_matrix,model);
[predict_label_2,accuracy_2] = svmpredict(test_label,Test_matrix,model);
result_1 = [train_label predict_label_1];
result_2 = [test_label predict_label_2];
%% 绘图
figure