2011-05-13 23 views
4

我有简单的异或问题,我想学习使用libsvm中的RBF内核。当我使用XOR问题,像训练了Java LIBSVM:为什么svm_predict和svm_predict_probability在java libsvm中为xor问题提供了不同的结果?

 
x y 
0,0 -1 
0,1 1 
1,0 1 
1,1 -1 

结果我得到一个测试向量(0,0)分类为-1,如果我使用svm.svm_predict,但+1如果我使用SVM .svm_predict_probability。即使返回的概率也是相反的。我使用的代码和结果如下。任何人都可以告诉我我在做什么错在这里?

public static void main(String[] args) { 
    svm_problem sp = new svm_problem(); 
    svm_node[][] x = new svm_node[4][2]; 
    for (int i = 0; i < 4; i++) { 
     for (int j = 0; j < 2; j++) { 
      x[i][j] = new svm_node(); 
     } 
    } 
    x[0][0].value = 0; 
    x[0][1].value = 0; 

    x[1][0].value = 1; 
    x[1][1].value = 1; 

    x[2][0].value = 0; 
    x[2][1].value = 1; 

    x[3][0].value = 1; 
    x[3][1].value = 0; 


    double[] labels = new double[]{-1,-1,1,1}; 
    sp.x = x; 
    sp.y = labels; 
    sp.l = 4; 
    svm_parameter prm = new svm_parameter(); 
    prm.svm_type = svm_parameter.C_SVC; 
    prm.kernel_type = svm_parameter.RBF; 
    prm.C = 1000; 
    prm.eps = 0.0000001; 
    prm.gamma = 10; 
    prm.probability = 1; 
    prm.cache_size=1024; 
    System.out.println("Param Check " + svm.svm_check_parameter(sp, prm)); 
    svm_model model = svm.svm_train(sp, prm); 
    System.out.println(" PA "+ model.probA[0]); 
    System.out.println(" PB " + model.probB[0]); 
    System.out.println(model.sv_coef[0][0]); 
    System.out.println(model.sv_coef[0][1]); 
    System.out.println(model.sv_coef[0][2]); 
    System.out.println(model.sv_coef[0][3]); 
    System.out.println(model.SV[0][0].value + "\t" + model.SV[0][1].value); 
    System.out.println(model.SV[1][0].value + "\t" + model.SV[1][1].value); 
    System.out.println(model.SV[2][0].value + "\t" + model.SV[2][1].value); 
    System.out.println(model.SV[3][0].value + "\t" + model.SV[3][1].value); 
    System.out.println(model.label[0]); 
    System.out.println(model.label[1]); 
    svm_node[] test = new svm_node[]{new svm_node(), new svm_node()}; 
    test[0].value = 0; 
    test[1].value = 0; 
    double[] l = new double[2]; 
    double result_prob = svm.svm_predict_probability(model, test,l); 
    double result_normal = svm.svm_predict(model, test); 
    System.out.println("Result with prob " + result_prob); 
    System.out.println("Result normal " + result_normal); 
    System.out.println("Probability " + l[0] + "\t" + l[1]); 
} 

---------结果-------------

Param Check null 
* 
. 
. 
optimization finished, #iter = 3 
nu = 0.0010000908050150552 
obj = -2.000181612091545, rho = 0.0 
nSV = 4, nBSV = 0 
Total nSV = 4 
PA 3.2950351477129125 
PB -2.970957107176531E-12 
1.0000908039844314 
1.0000908060456788 
-1.0000908039844314 
-1.0000908060456788 
0.0 0.0 
1.0 1.0 
0.0 1.0 
1.0 0.0 
-1 
1 
Result with prob 1.0 
Result normal -1.0 
Probability 0.03571492727188865  0.9642850727281113 

显然,结果是完全相反的。这似乎发生在我选择作为测试的任何示例上。

有人可以对此有所了解吗? 在此先感谢

回答

0

我不知道libsvm,但从其他图书馆判断,你可能只是误解了概率输出的含义 - 它可能不是它是“正面”类的可能性,而是存在在第一个输入样本的类中,在你的情况下它的标签为-1。所以,如果您对样品进行重新排序以便第一个样品的标签为+1,则可能会得到您期望的输出。

+0

嗨,感谢您的回复,但我试图互换标签,但这似乎并不重要。它总是给错误的类别分配更高的概率,就好像有人忘记了撤销标志或什么的。 – Karthik 2011-05-17 10:37:05

1

这是只有一半的答案,因为我无法得到它要么工作...

我认为你是不正确的指定数据。 libsvm使用稀疏数据格式,这意味着每个svm_node都有一个索引和一个位置。这是一种效率度量,它允许您省略具有少量非零特征的大向量为零的特征。

所以,你的代码应该是:

x[0][0].index = 1; 
x[0][0].value = 0;  
x[0][1].index = 2; 
x[0][1].value = 0; 
x[1][0].index = 1; 
x[1][0].value = 1; 
x[1][1].index = 2; 
x[1][1].value = 1; 
x[2][0].index = 1; 
x[2][0].value = 0;  
x[2][1].index = 2; 
x[2][1].value = 1; 
x[3][0].index = 1; 
x[3][0].value = 1;  
x[3][1].index = 2; 
x[3][1].value = 0; 

test[0].index = 1; 
test[0].value = 0; 
test[1].index = 2; 
test[1].value = 0; 

这似乎并不虽然解决这个问题。希望这是朝着正确方向迈出的一步。

+0

谢谢,不知道索引的东西,会尝试将其添加到我的代码。 – Karthik 2011-05-19 04:38:04

+0

我会试着仔细看看它,我没有任何运气地摆弄参数。从查看文档和源代码,在正确训练的模型中,svm_predict和svm_predict_probability *应该输出相同的内容。 – Stompchicken 2011-05-19 08:26:28

2

据我所知,概率输出向量的顺序与libsvm在训练数据中遇到类的顺序相同。确保您首先拥有所有类0的例子(例如标签为1),然后是类1(例如标签为-1),将使输出成为您可能期望的方式。这对我使用matlab界面进行培训时有效,但对于c和java版本应该是一样的。

3

我问芷仁林约XOR问题,因为我有同样的问题,从回答

引文:

  • 为-b 1,在内部我们需要做的5-折叠cv。鉴于这么少的情况下,可能会出现

这意味着,奇怪的结果对于许多它的工作原理相同的输入。复制/粘贴输入矢量5-6次,有20个入口而不是4个,它会工作。

这意味着,也意味着svm_predict会给你总是正确的答案,只有当数据足够大时svm_predict_probability。不要忘了,那output for both methods isn't identical

0

你的最后一个指数应该是-1在训练和测试数据。

相关问题