bhavishya bhat
bhavishya bhat

Reputation: 25

how to train svm on multiple type features

I want to train svm on data set consisting of features p1, p2 , p3 . p1 is vector , p2 and p3 are integers on which i want to train . For e.g p1=[1,2,3], p2=4 , p3=5 X=[p1 , p2 , p3],but p1 itself is a vector, so X=[ [ 1 , 2 , 3 ], 4 , 5 ] and Y is output named label
but X can't take input in this form

clf.fit(X,Y) It gives error of form below: meaning X cannot take in this form array = np.array(array, dtype=dtype, order=order, copy=copy) ValueError: setting an array element with a sequence.

Upvotes: 0

Views: 757

Answers (2)

Suleiman
Suleiman

Reputation: 316

Here is a simple example

    #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);

To test

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;
}

Upvotes: 0

lejlot
lejlot

Reputation: 66815

You basically have two options:

  1. Convert your data to regular format and run typical SVM kernel, in your case if p1 is always 3-element, just flatten representation thus [[1,2,3],4,5] becomes [1,2,3,4,5] and you are good to go.

  2. Implement your own custom kernel function, that treats each part separately, since sum of two kernels is still a kernel, you can for example define K(x, y) = K([p1, p2, p3], [q1, q2, q3]) := K1(p1, q1) + K2([p2,p3], [q2,q3]). Now both K1 and K2 work on regular vectors, so you can define them in arbitrary manner and just use their sum as your "joint" kernel function. This approach is more complex, but gives you much freedom in how you define the way of dealing with your complex data.

Upvotes: 1

Related Questions