如何使用支持向量机(SVM)进行多类分类

55

在每本书和例子中,他们总是只展示二元分类(两类),新向量可以属于任何一类。

问题在于我有4类(c1,c2,c3,c4)。 我有4个类的训练数据。

对于新的向量,输出应该为

C1 80%(获胜者)

c2 10%

c3 6%

c4 4%

如何做到这一点? 我打算使用libsvm(因为它最受欢迎)。 我不太了解它。 如果你们中的任何人之前使用过,请告诉我应该使用什么具体命令。

8个回答

41

LibSVM使用“一对一”方法处理多类学习问题。从常见问题解答中可以了解到:

问: Libsvm用于多类SVM的方法是什么?为什么不使用“一对其余”方法?

答:使用的是“一对一”方法。我们在进行以下比较后选择了这种方法:C.-W. Hsu 和 C.-J. Lin. 多类支持向量机方法比较, IEEE Transactions on Neural Networks, 13 (2002), 415-425。

“一对其余”是一种良好的方法,其性能与“一对一”相当。我们之所以选择后者,仅因其训练时间更短。


22

常用的方法有One vs. Rest和One vs. One。 在第一种方法中,您将获得n个分类器,并且最终的类将具有最高分数。 在第二种方法中,通过所有分类器的多数投票来获得最终的类。

据我所知,libsvm支持多类别分类的两种策略。


4
我以前认为libsvm只支持一对一的分类方式,但它的表现非常出色。 - Steve Tjoa

7
您可以通过选择类集的随机分割来将多类分类问题转化为二元问题,递归地进行。这种方法并不一定比同时进行学习效果更差或更低效,因为子学习问题需要的示例较少,因为分区问题较小。(这可能需要最多常数阶时间,例如长两倍的时间)。它也可能导致更精确的学习。
我并不一定推荐这种方法,但这是您问题的一个答案,并且是一种可应用于任何二元学习算法的通用技术。

1

0

与二元预测相比没有什么特别的。以下是基于SVM进行三类预测的示例。

install.packages("e1071")
library("e1071")
data(iris)
attach(iris)
## classification mode
# default with factor response:
model <- svm(Species ~ ., data = iris)
# alternatively the traditional interface:
x <- subset(iris, select = -Species)
y <- Species
model <- svm(x, y) 
print(model)
summary(model)
# test with train data
pred <- predict(model, x)
# (same as:)
pred <- fitted(model)
# Check accuracy:
table(pred, y)
# compute decision values and probabilities:
pred <- predict(model, x, decision.values = TRUE)
attr(pred, "decision.values")[1:4,]
# visualize (classes by color, SV by crosses):
plot(cmdscale(dist(iris[,-5])),
     col = as.integer(iris[,5]),
     pch = c("o","+")[1:150 %in% model$index + 1])

0

它没有特定的开关(命令)用于多类预测。如果您的训练数据集包含两个以上的类别,它会自动处理多类预测。


0

对于使用SVM进行多类分类的情况;不是(一对一)也不是(一对REST)。

相反,学习一个二元分类器,其中特征向量为(x,y),其中x是数据,y是与数据相关联的正确标签。

训练间隔是正确类别值和最近其他类别值之间的差异。

在推理中选择具有最大(x,y)值的“y”。

y = arg_max(y') W.(x,y') [W是权重向量,(x,y)是特征向量]

请访问链接: https://nlp.stanford.edu/IR-book/html/htmledition/multiclass-svms-1.html#:~:text=It%20is%20also%20a%20simple,the%20label%20of%20structural%20SVMs%20


0
data=load('E:\dataset\scene_categories\all_dataset.mat');
    meas = data.all_dataset;
    species = data.dataset_label;
    [g gn] = grp2idx(species);                      %# nominal class to numeric

%# split training/testing sets
[trainIdx testIdx] = crossvalind('HoldOut', species, 1/10);
%# 1-vs-1 pairwise models
num_labels = length(gn);
clear gn;
num_classifiers = num_labels*(num_labels-1)/2;
pairwise = zeros(num_classifiers ,2);
row_end = 0;
for i=1:num_labels - 1
    row_start = row_end + 1;
    row_end = row_start + num_labels - i -1;
    pairwise(row_start : row_end, 1) = i;
    count = 0;
    for j = i+1 : num_labels        
        pairwise( row_start + count , 2) = j;
        count = count + 1;
    end    
end
clear row_start row_end count i j num_labels num_classifiers;
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), ...
                 'Autoscale',true, 'Showplot',false, 'Method','QP', ...
                 'BoxConstraint',2e-1, 'Kernel_Function','rbf', 'RBF_Sigma',1);

    %# 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):\naccuracy = %.2f%%\n', acc);
fprintf('Confusion Matrix:\n'), disp(cmat)

8
你能否添加一些描述以帮助用户理解吗?如果仅仅给出代码而没有任何解释,你的回答价值会减少:/ - goto
all_dataset.mat 共有15个类别,我使用基于构建一对多二元SVM分类器的多分类SVM。 - lin0Xu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接