2010-03-19 5 views
7

Ho cercato la rete per ~ 3 ore ma non sono riuscito a trovare ancora una soluzione. Voglio dare un kernel precalcolate per libsvm e classificare un set di dati, ma:Kernel precompilati con LibSVM in Python

  • Come si genera un kernel precalcolate? (Per esempio, qual è il kernel precalcolate di base per Iris data?)

  • Nella documentazione libsvm, si precisa che:

    Per i kernel precalcolate, il primo elemento di ogni istanza deve essere l'ID. Ad esempio,

     samples = [[1, 0, 0, 0, 0], [2, 0, 1, 0, 1], [3, 0, 0, 1, 1], [4, 0, 1, 1, 2]] 
         problem = svm_problem(labels, samples) 
         param = svm_parameter(kernel_type=PRECOMPUTED) 
    

Che è un ID? Non ci sono ulteriori dettagli su questo. Posso assegnare ID in modo sequenziale?

Qualsiasi aiuto di libsvm e un esempio di kernel precalcolato è molto apprezzato.

risposta

14

Prima di tutto, alcuni retroscena di kernel e SVM ...

Se si vuole pre-calcolare un kernel per n vettori (di qualsiasi dimensione), che cosa dobbiamo fare è calcolare la funzione del kernel tra ogni coppia di esempi. La funzione kernel prende due vettori e dà uno scalare, quindi puoi pensare a un kernel precompilato come una matrice di scalari nxn. Di solito è chiamato la matrice del kernel, o talvolta la matrice Gram.

Ci sono molti kernel differenti, il più semplice è il kernel lineare (noto anche come il prodotto scalare):

sum(x_i * y_i) for i in [1..N] where (x_1,...,x_N) (y_1,..,y_N) are vectors

In secondo luogo, cercando di rispondere il tuo problema ...

La documentazione sui kernel precompilati in libsvm è in realtà piuttosto buona ...

Assume the original training data has three four-feature instances 
and testing data has one instance: 

15 1:1 2:1 3:1 4:1 
45  2:3  4:3 
25   3:1 
15 1:1  3:1 

If the linear kernel is used, we have the following 
new training/testing sets: 

15 0:1 1:4 2:6 3:1 
45 0:2 1:6 2:18 3:0 
25 0:3 1:1 2:0 3:1 

15 0:? 1:2 2:0 3:1 

Ogni vettore qui nel secondo esempio è una riga nella matrice del kernel. Il valore a zero indice è il valore ID e sembra essere solo un conteggio sequenziale. Il valore all'indice 1 del primo vettore è il valore della funzione kernel del primo vettore dal primo esempio con se stesso (ovvero (1x1)+(1x1)+(1x1)+(1x1) = 4), il secondo è il valore della funzione kernel del primo vettore con il secondo (ovvero (1x3)+(1x3)=6). Segue così per il resto dell'esempio. Potete vedere che la matrice del kernel è simmetrica, come dovrebbe essere, perché K (x, y) = K (y, x).

Vale la pena sottolineare che il primo set di vettori è rappresentato in un formato sparse (cioè i valori mancanti sono zero), ma la matrice del kernel non è e non dovrebbe essere sparsa. Non so perché sia, sembra solo una cosa di libsvm.

+0

Risposta più utile! – JXITC

2

Questo è un semplice file di input del kernel personalizzato di due categorie 3 vettoriale che funziona correttamente.Spiegherò le parti (anche se si dovrebbe vedere anche la risposta di StompChicken):

1 0:1 1:10 2:12 3:21
2 0:2 1:12 2:19 3:30
1 0:3 1:21 2:30 3:130

Il primo numero di ogni riga è quale categoria a cui appartiene. La voce successiva in ciascuna riga è di forma 0: n e deve essere sequenziale, cioè
0: 1 al primo ingresso
0: 2 in seconda entrata
0: 3 in ingresso thrid

Una possibile ragione per questo è che libsvm restituisce valori alpha_i che vanno con i tuoi vettori nel file di output, ma per i kernel precalcolati i vettori non sono visualizzati (che potrebbero essere veramente enormi) piuttosto l'indice 0: n che è andato con quel vettore è mostrato per rendere il tuo output più facile da abbinare al tuo input. Soprattutto dal momento che l'output è non nello stesso ordine in cui li hai inseriti è raggruppato per categoria. È quindi molto utile per te quando leggi il file di input per essere in grado di abbinare gli output di libsvm con i tuoi input per avere quei valori 0: n. Qui potete vedere l'output

svm_type c_svc
kernel_type precalcolate
nr_class 2
total_sv 3
rho -1,53951
etichetta 1 2
nr_sv 2 1
SV
,4126650675419768 0: 1
0.03174528241667363 0: 3
-0.4444103499586504 0: 2

È importante notare che con i kernel precomputed non è possibile omettere le voci zero come è possibile con tutti gli altri kernel. Devono essere esplicitamente inclusi.

5

scikit-learn nasconde la maggior parte dei dettagli di libsvm durante la gestione dei kernel personalizzati. Puoi semplicemente passare una funzione arbitraria come kernel e calcolerà la matrice di grammi per te o passerà la matrice Gram precomputata del kernel.

Per il primo, la sintassi è:

>>> from scikits.learn import svm 
    >>> clf = svm.SVC(kernel=my_kernel) 

dove my_kernel è la funzione del kernel, e quindi è possibile chiamare clf.fit (x, y) e si calcola la matrice di kernel per voi. Nel secondo caso la sintassi è:

>>> from scikits.learn import svm 
    >>> clf = svm.SVC(kernel="precomputed") 

E quando si chiama clf.fit (X, Y), X deve essere la matrice k (X, X), dove k è il kernel. Vedi anche questo esempio per ulteriori dettagli:

http://scikit-learn.org/stable/auto_examples/svm/plot_custom_kernel.html