如何在多种类型的功能上训练svm

时间:2017-03-18 09:17:06

标签: machine-learning svm libsvm

我想在由特征p1,p2,p3组成的数据集上训练svm。 p1是向量,p2和p3是我要训练的整数。例如,p1 = [1,2,3],p2 = 4,p3 = 5 X = [p1,p2,p3],但p1本身是一个向量,所以X = [[1,2,3],4,5],Y输出名为标签
但是X不能以这种形式输入

clf.fit(X,Y) 它给出了以下形式的错误:意味着X不能采用这种形式   array = np.array(array,dtype = dtype,order = order,copy = copy) ValueError:使用序列设置数组元素。

2 个答案:

答案 0 :(得分:1)

您基本上有两个选择:

  1. 将您的数据转换为常规格式并运行典型的SVM内核,在您的情况下,如果p1始终为3元素,则只展平表示,因此[[1,2,3],4,5]变为[1, 2,3,4,5]你很高兴。

  2. 实现自己的自定义内核函数,分别处理每个部分,因为两个内核的总和仍然是内核,例如可以定义K(x,y)= K([p1,p2,p3] ,[q1,q2,q3]):= K1(p1,q1)+ K2([p2,p3],[q2,q3])。现在K1和K2都处理常规向量,因此您可以以任意方式定义它们,并将它们的和用作“关节”核函数。这种方法更复杂,但您可以自由地定义处理复杂数据的方式。

答案 1 :(得分:0)

这是一个简单的例子

    #include <opencv2/ml.hpp>
    using namespace cv::ml;

        // Set up training data
                int labels[4] = { -1, -1, 1, 1}; //Negative and Positive class
                Mat labelsMat(4, 1, CV_32SC1, labels);

            //training data inputs
                float a1 = 1, a2 = 2; //negative
                float b1 = 2, b2 = 1; //negative
                float c1 = 3, c2 = 4; //positive
                float d1 = 4, d2 = 3; //positive

float trainingData[4][2] = {{ a1, a2 },{ b1, b2 },{ c1, c2 },{ d1, d2 };


Mat trainingDataMat(20, 2, CV_32FC1, trainingData);

    // Set up SVM's parameters
    Ptr<SVM> svm = SVM::create();
    svm->setType(SVM::C_SVC);
    svm->setKernel(SVM::RBF);
    svm->setC(10);
    svm->setGamma(0.01);
    svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 500, 1e-6));

    // Train the SVM with given parameters
    Ptr<TrainData> td = TrainData::create(trainingDataMat, ROW_SAMPLE, labelsMat);
    svm->train(td);

测试

float   t1 = 2, t2 = 2;
float   testing[1][2] = { { t1,t2 } };
Mat     testData(1, 2, CV_32FC1, testing);
Mat     results;

svm->predict(testData, results);
Mat vec[2];

results.copyTo(vec[0]);
for (int i = 0; i < 2; i++)
{
    cout << vec[i] << endl;
}