2012-03-27 5 views
2

Wir sind zwei Studenten, die one-Klasse-Svm für die Erkennung von summarisch Sätze in Textdokumenten verwenden möchten. Wir haben bereits Satzähnlichkeitsfunktionen für Sätze implementiert, die wir für einen anderen Algorithmus verwendet haben. Wir möchten nun die gleichen Funktionen wie Kernel für eine Ein-Klassen-Svm in libsvm für Java verwenden.Die Verwendung von vorberechneten Kernel in libsvm verursacht, dass es stecken bleibt

Wir verwenden die PRECOMPUTED enum für die kernel_type Feld in unserem svm_parameter (param). Im x Bereich unserer svm_problem (prob) haben wir die Kernmatrix auf dem Formular:

0:i 1:K(xi,x1) ... L:K(xi,xL) 

wo K(x,y) der Kernel-Wert für die Ähnlichkeit von x ist und y, L ist die Anzahl der Sätze zu vergleichen und i ist der aktuelle Zeilenindex (0 bis L). Das Training des Kernels (svm.svm_train(prob, param)) scheint manchmal in einer scheinbar endlosen Schleife stecken zu bleiben.

Haben wir missverstanden, wie man die PRECOMPUTED enum verwendet, oder liegt das Problem anderswo?

Antwort

2

Wir lösten dieses Problem

Es stellt sich heraus, dass die „Seriennummern“ in der ersten Spalte 1-L gehen muss, nicht 0-L-1, die unsere ursprüngliche Nummerierung war. Wir fanden dies aus, indem die Quelle in svm.java Inspizieren:

double kernel_function(int i, int j) 
{ 
    switch(kernel_type) 
    { 
     /* ... snip ...*/ 
     case svm_parameter.PRECOMPUTED: 
      return x[i][(int)(x[j][0].value)].value; 
     /* ... snip ...*/ 
    } 
} 

Der Grund für das Starten der Numerierung in 1 statt 0, ist, dass die erste Spalte einer Zeile als Spaltenindex verwendet wird, wenn K(i,j) den Wert zurückkehrt.

Beispiel

diese Java-Matrix vor:

double[][] K = new double[][] { 
    double[] { 1, 1.0, 0.1, 0.0, 0.2 }, 
    double[] { 2, 0.5, 1.0, 0.1, 0.4 }, 
    double[] { 3, 0.2, 0.3, 1.0, 0.7 }, 
    double[] { 4, 0.6, 0.5, 0.5, 1.0 } 
}; 

Nun muss LIBSVM den Wert Kernel K(i,j) für etwa i=1 und j=3. Der Ausdruck x[i][(int)(x[j][0].value)].value wird brechen auf:

x[i] -> x[1] -> second row in K   -> [2, 0.5, 1.0, 0.1, 0.4] 
x[j][0] -> x[3][0] -> fourth row, first column -> 4 
x[i][(int)(x[j][0].value)].value -> x[1][4] -> 0.4 

Das war ein bisschen chaotisch zunächst zu erkennen, aber die Änderung der Indizierung gelöst unser Problem. Hoffentlich könnte dies jemand anderem mit ähnlichen Problemen helfen.

Verwandte Themen