我有一段文本,想通过使用JAVA API添加特征来进行训练。根据示例,构建训练集的主要类是svm_problem。看起来svm_node代表一个模式(index是特征,value是该特征的权重)。
我所做的是使用一个映射(只是为了简化问题),它保持特征与索引之间的关联。对于每个我的权重>示例,我创建一个新节点:
svm_node currentNode = new svm_node(); int index = feature.getIndexInMap(); double value = feature.getWeight(); currentNode.index = index; currentNode.value = value;
我的直觉正确吗?svm_problem.y指的是什么?它指的是标签的索引吗?svm_problem.l只是两个向量的长度吗?
回答:
你的直觉非常接近,但svm_node是一个模式而不是特征。变量svm_problem.y是一个包含每个模式标签的数组,而svm_problem.l是训练集的大小。
另外,请注意svm_parameter.nr_weight是每个标签的权重(如果你的训练集不平衡时很有用),但如果你不打算使用它,你必须将其值设置为零。
让我给你展示一个简单的C++示例:
#include "svm.h"#include <iostream>using namespace std;int main(){ svm_parameter params; params.svm_type = C_SVC; params.kernel_type = RBF; params.C = 1; params.gamma = 1; params.nr_weight = 0; params.p= 0.0001; svm_problem problem; problem.l = 4; problem.y = new double[4]{1,-1,-1,1}; problem.x = new svm_node*[4]; { problem.x[0] = new svm_node[3]; problem.x[0][0].index = 1; problem.x[0][0].value = 0; problem.x[0][1].index = 2; problem.x[0][1].value = 0; problem.x[0][2].index = -1; } { problem.x[1] = new svm_node[3]; problem.x[1][0].index = 1; problem.x[1][0].value = 1; problem.x[1][1].index = 2; problem.x[1][1].value = 0; problem.x[1][2].index = -1; } { problem.x[2] = new svm_node[3]; problem.x[2][0].index = 1; problem.x[2][0].value = 0; problem.x[2][1].index = 2; problem.x[2][1].value = 1; problem.x[2][2].index = -1; } { problem.x[3] = new svm_node[3]; problem.x[3][0].index = 1; problem.x[3][0].value = 1; problem.x[3][1].index = 2; problem.x[3][1].value = 1; problem.x[3][2].index = -1; } for(int i=0; i<4; i++) { cout << problem.y[i] << endl; } svm_model * model = svm_train(&problem, ¶ms); svm_save_model("mymodel.svm", model); for(int i=0; i<4; i++) { double d = svm_predict(model, problem.x[i]); cout << "Prediction " << d << endl; } /* We should free the memory at this point. But this example is large enough already */ }