2012-01-20 14 views
5

Dopo aver ottenuto il mio testlabel e trainlabel, ho implementato SVM su libsvm e ho ottenuto una precisione del 97,4359%. (C = 1 e g = 0,00375)Precisione di LibSVM decrementa

model = svmtrain(TrainLabel, TrainVec, '-c 1 -g 0.00375'); 
[predict_label, accuracy, dec_values] = svmpredict(TestLabel, TestVec, model); 

dopo aver trovato la migliore C e G,

bestcv = 0; 
for log2c = -1:3, 
    for log2g = -4:1, 
    cmd = ['-v 5 -c ', num2str(2^log2c), ' -g ', num2str(2^log2g)]; 
    cv = svmtrain(TrainLabel,TrainVec, cmd); 
    if (cv >= bestcv), 
     bestcv = cv; bestc = 2^log2c; bestg = 2^log2g; 
    end 
    fprintf('%g %g %g (best c=%g, g=%g, rate=%g)\n', log2c, log2g, cv, bestc, bestg, bestcv); 
    end 
end 

c = 8 e g = 0,125

implemento nuovo modello:

model = svmtrain(TrainLabel, TrainVec, '-c 8 -g 0.125'); 
[predict_label, accuracy, dec_values] = svmpredict(TestLabel, TestVec, model); 

ottengo una precisione del 82,0513%

Come è possibile che la precisione diminuisca? non dovrebbe aumentare? O sto facendo qualche errore?

+0

io non sono a conoscenza di Matlab API LibSVM, ma sei sicuro 'cv = svmtrain (TrainLabel, TrainVec, cmd);' vi darà la precisione? –

+0

questo è ciò che hanno fornito nelle FAQ di LIBSVM: http://www.csie.ntu.edu.tw/~cjlin/libsvm/faq.html in Come posso utilizzare l'interfaccia MATLAB per la selezione dei parametri? – lakesh

risposta

4

Le precisioni ottenute durante la sintonizzazione dei parametri sono state spostate verso l'alto perché stavate predicando gli stessi dati che stavate allenando. Questo spesso va bene per la sintonizzazione dei parametri.

Tuttavia, se si desidera che tali precisioni siano stime accurate dell'errore di generalizzazione vero sul set di test finale, è necessario aggiungere un ulteriore ciclo di convalida incrociata o altro schema di ricampionamento.

Ecco un chiaro documento che delinea la questione generale (ma in un contesto simile di selezione delle funzioni): http://www.pnas.org/content/99/10/6562.abstract

EDIT:

solito aggiungo convalida croce come:

n  = 95 % total number of observations 
nfold = 10 % desired number of folds 

% Set up CV folds 
inds = repmat(1:nfold, 1, mod(nfold, n)) 
inds = inds(randperm(n)) 

% Loop over folds 
for i = 1:nfold 
    datapart = data(inds ~= i, :) 

    % do some stuff 

    % save results 
end 

% combine results 
+0

come si aggiunge un ulteriore ciclo di validazione incrociata? – lakesh

+0

@lakesh Vedi modifica. In bocca al lupo! –

+0

solo per chiarire: LIBSVM non lo fa? tutto ciò che devi digitare è "-v n" dove n è il numero di volte. – lakesh

1

Per eseguire la convalida incrociata, è necessario suddividere i dati di allenamento. Qui puoi testare i dati di allenamento per trovare il miglior set di parametri. Questa non è una buona misura. Si dovrebbe usare il seguente codice pseudo:

for param = set of parameter to test 
    [trainTrain,trainVal] = randomly split (trainSet); %%% you can repeat that several times and take the mean accuracy 
    model = svmtrain(trainTrain, param); 
    acc = svmpredict(trainVal, model); 
    if accuracy is the best 
    bestPAram = param 
    end 
end 
+0

cosa c'è di sbagliato nel mio codice? fa iterare per trovare il migliore c e gamma ... – lakesh

+0

questo era quello che davano nelle FAQ di LIBSVM: csie.ntu.edu.tw/~cjlin/libsvm/faq.html sotto Come potrei usare l'interfaccia MATLAB per la selezione dei parametri? – lakesh

+0

Sto già facendo la validazione incrociata nel mio codice .. – lakesh