2011-05-13 213 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在訓練和測試數據。

相關問題