SVM multi-classes(un contre tous)

je sais que LIBSVM ne permet qu'une seule classification lorsqu'il s'agit de SVM à classes multiples. Cependant, je voudrais le peaufiner un peu pour effectuer la classification un-contre-tous. J'ai essayé de faire un contre tous ci-dessous. Est-ce la bonne démarche?

le code:

TrainLabel;TrainVec;TestVec;TestLaBel;
u=unique(TrainLabel);
N=length(u);
if(N>2)
    itr=1;
    classes=0;
    while((classes~=1)&&(itr<=length(u)))
        c1=(TrainLabel==u(itr));
        newClass=c1;
        model = svmtrain(TrainLabel, TrainVec, '-c 1 -g 0.00154'); 
        [predict_label, accuracy, dec_values] = svmpredict(TestLabel, TestVec, model);
        itr=itr+1;
    end
itr=itr-1;
end

j'ai peut-être fait des erreurs. J'aimerais entendre quelques commentaires. Grâce.

Deuxième Partie: Comme disait grapeot : J'ai besoin de faire La mise en commun des ressources (ou le vote en tant que solution simplifiée) pour arriver à la réponse finale. Je ne suis pas sûr de savoir comment faire. J'ai besoin d'aide; j'ai vu le fichier python mais pas encore très sûr. J'ai besoin d'aide.

12
demandé sur Amro 2012-01-21 17:26:02

3 réponses

%# Fisher Iris dataset
load fisheriris
[~,~,labels] = unique(species);   %# labels: 1/2/3
data = zscore(meas);              %# scale features
numInst = size(data,1);
numLabels = max(labels);

%# split training/testing
idx = randperm(numInst);
numTrain = 100; numTest = numInst - numTrain;
trainData = data(idx(1:numTrain),:);  testData = data(idx(numTrain+1:end),:);
trainLabel = labels(idx(1:numTrain)); testLabel = labels(idx(numTrain+1:end));
%# train one-against-all models
model = cell(numLabels,1);
for k=1:numLabels
    model{k} = svmtrain(double(trainLabel==k), trainData, '-c 1 -g 0.2 -b 1');
end

%# get probability estimates of test instances using each model
prob = zeros(numTest,numLabels);
for k=1:numLabels
    [~,~,p] = svmpredict(double(testLabel==k), testData, model{k}, '-b 1');
    prob(:,k) = p(:,model{k}.Label==1);    %# probability of class==k
end

%# predict the class with the highest probability
[~,pred] = max(prob,[],2);
acc = sum(pred == testLabel) ./ numel(testLabel)    %# accuracy
C = confusionmat(testLabel, pred)                   %# confusion matrix
10
répondu lakesh 2012-02-04 07:33:05

du code je peux voir que vous essayez d'abord de transformer les étiquettes en "une certaine classe" vs "pas cette classe", et puis invoquer LibSVM pour faire de la formation et des tests. Quelques questions et suggestions:

  1. pourquoi utilisez-vous l'original TrainingLabel pour la formation? À mon avis, devrait-il être model = svmtrain(newClass, TrainVec, '-c 1 -g 0.00154'); ?
  2. avec un mécanisme d'entraînement modifié, vous devez également modifier la partie prédiction, comme l'utilisation de la sommation pour déterminer la finale étiquette. L'utilisation du commutateur -b dans LibSVM pour activer la sortie de probabilité améliorera également la précision.
4
répondu grapeot 2012-01-21 13:48:18

au lieu des estimations de probabilité, vous pouvez également utiliser les valeurs de décision comme suit

[~,~,d] = svmpredict(double(testLabel==k), testData, model{k});
prob(:,k) = d * (2 * model{i}.Label(1) - 1);

pour atteindre le même but.

1
répondu Venkata 2012-09-28 11:53:33