Использование предварительно вычисленного ядра в libsvm приводит к его зависанию - PullRequest
2 голосов
/ 27 марта 2012

Мы два студента, которые хотят использовать одноклассный svm для распознавания кратких достойных предложений в текстовых документах.Мы уже реализовали функции подобия предложений для предложений, которые мы использовали для другого алгоритма.Теперь мы хотели бы использовать те же функции, что и ядра, для одноклассного svm в libsvm для java.

Мы используем перечисление PRECOMPUTED для поля kernel_type в нашем svm_parameter (param).В поле x нашего svm_problem (prob) у нас есть матрица ядра в форме:

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

, где K(x,y) - это значение ядра для подобия x и y,L - количество предложений для сравнения, i - текущий индекс строки (от 0 до L).Обучение ядра (svm.svm_train(prob, param)), похоже, иногда застревает в том, что кажется бесконечным циклом.

Неужели мы не поняли, как использовать перечисление PRECOMPUTED, или проблема кроется в другом месте?

1 Ответ

3 голосов
/ 28 марта 2012

Мы решили эту проблему

Оказывается, что «номера серий» в первом столбце должны быть от 1 до L, а не от 0 до L-1, что было нашей первоначальной нумерацией. Мы выяснили это, проверив источник в svm.java:

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 ...*/
    }
}

Причиной начала нумерации с 1 вместо 0 является то, что первый столбец строки используется в качестве индекса столбца при возврате значения K(i,j).

Пример

Рассмотрим эту матрицу Java:

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 }
};

Теперь libsvm нужно значение ядра K(i,j), скажем, i=1 и j=3. Выражение x[i][(int)(x[j][0].value)].value будет разбито на:

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

Сначала это было немного сложно, но изменение индексации решило нашу проблему. Надеюсь, это может помочь кому-то еще с подобными проблемами.

...