在libsvm中使用预先计算的内核会导致它被卡住

时间:2012-03-27 14:16:18

标签: java kernel libsvm

我们是两个学生想要使用一流的svm来检测文本文档中的总结值句。我们已经为句子实现了句子相似度函数,我们将其用于另一种算法。我们现在想要在libsvm for java中使用与内核相同的函数来实现单类svm。

我们在PRECOMPUTED(param)的kernel_type字段中使用svm_parameter枚举。在svm_problem(prob)的x字段中,我们在表单上有内核矩阵:

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

其中K(x,y)xy相似度的内核值,L是要比较的句子数,i是当前行索引(0L)。 内核(svm.svm_train(prob, param))的训练似乎有时会被“卡住”在看似无限循环的东西中。

我们是否误解了如何使用PRECOMPUTED枚举,或问题是否存在于其他地方?

1 个答案:

答案 0 :(得分:3)

我们解决了这个问题

事实证明,第一列中的“序列号”需要从1转到L,而不是0L-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=1j=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

一开始意识到这有点乱,但改变索引解决了我们的问题。希望这可能会帮助其他有类似问题的人。