我们是两个学生想要使用一流的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)
是x
和y
相似度的内核值,L
是要比较的句子数,i
是当前行索引(0
到L
)。
内核(svm.svm_train(prob, param)
)的训练似乎有时会被“卡住”在看似无限循环的东西中。
我们是否误解了如何使用PRECOMPUTED
枚举,或问题是否存在于其他地方?
答案 0 :(得分:3)
我们解决了这个问题
事实证明,第一列中的“序列号”需要从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
一开始意识到这有点乱,但改变索引解决了我们的问题。希望这可能会帮助其他有类似问题的人。