我想在libsvm中使用RBF内核学习简单的xor问题。当我使用XOR问题训练java libsvm时:
x y 0,0 -1 0,1 1 1,0 1 1,1 -1
如果我使用svm.svm_predict,我得到的用于对测试向量(0,0)进行分类的结果为-1,但如果我使用svm.svm_predict_probability则为+1。即使返回的概率也是相反的。我使用的代码和结果如下。谁能告诉我我在这里做错了什么?
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 :(得分:3)
我已经向林志仁询问过XOR问题,因为我遇到了同样的问题
来自答案:
- for -b 1,在内部我们需要做5倍的简历。鉴于实例很少,可能会出现奇怪的结果
这意味着,对于许多相同的输入,它可以工作。复制/粘贴输入向量5-6次,有20个条目而不是4个,它将起作用。
这也意味着svm_predict只会在数据足够大的情况下为您提供正确答案,svm_predict_probability。不要忘记,output for both methods isn't identical
答案 1 :(得分:2)
据我所知,概率输出向量的顺序与libsvm在训练数据中遇到类的顺序相同。确保您首先拥有0级的所有示例(例如,使用标签1),然后使用第1级(例如使用标签-1),将使输出按照您可能期望的方式进行。当使用matlab界面进行训练时,这对我有用,但对于c和java版本应该是相同的。
答案 2 :(得分: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;
但这似乎并没有解决问题。希望这是朝着正确方向迈出的一步。
答案 3 :(得分:0)
我不知道libsvm,但是从其他库中判断你可能只是误解了概率输出的意义 - 它可能不是它处于“正”类的概率,而是存在于类的中。第一个输入样本,在您的情况下具有-1的标签。因此,如果您重新排序样本,以便第一个样本的标签为+1,则可能会得到您期望的输出。
答案 4 :(得分:0)
您的最后一个索引在训练和测试数据中应为-1。