SVM最初是为二进制分类而设计的。然后,它们被扩展到处理多类问题。其思想是将问题分解为许多二元类问题,然后将它们组合起来以获得预测。
一种被称为一对一的方法,构建尽可能多的二元分类器,每个分类器都经过训练,将一个类与其他类分离。为了预测新实例,我们选择决策函数值最大的分类器。
另一种称为一对一的方法(我相信它在LibSVM中使用),构建k(k-1)/2
二元分类器,训练以将每对类彼此分离,并使用多数投票方案(最大获胜策略)来确定输出预测。
还有其他方法,如使用纠错输出码(ECOC)来构建许多有点冗余的二进制分类器,并使用这种冗余来获得更稳健的分类(使用与汉明码相同的思想)。
示例(一对一):
%# load dataset
load fisheriris
[g gn] = grp2idx(species); %# nominal class to numeric
%# split training/testing sets
[trainIdx testIdx] = crossvalind( HoldOut , species, 1/3);
pairwise = nchoosek(1:length(gn),2); %# 1-vs-1 pairwise models
svmModel = cell(size(pairwise,1),1); %# store binary-classifers
predTest = zeros(sum(testIdx),numel(svmModel)); %# store binary predictions
%# classify using one-against-one approach, SVM with 3rd degree poly kernel
for k=1:numel(svmModel)
%# get only training instances belonging to this pair
idx = trainIdx & any( bsxfun(@eq, g, pairwise(k,:)) , 2 );
%# train
svmModel{k} = svmtrain(meas(idx,:), g(idx), ...
BoxConstraint ,2e-1, Kernel_Function , polynomial , Polyorder ,3);
%# test
predTest(:,k) = svmclassify(svmModel{k}, meas(testIdx,:));
end
pred = mode(predTest,2); %# voting: clasify as the class receiving most votes
%# performance
cmat = confusionmat(g(testIdx),pred);
acc = 100*sum(diag(cmat))./sum(cmat(:));
fprintf( SVM (1-against-1):
accuracy = %.2f%%
, acc);
fprintf( Confusion Matrix:
), disp(cmat)
以下是输出示例:
SVM (1-against-1):
accuracy = 93.75%
Confusion Matrix:
16 0 0
0 14 2
0 1 15