Reputation: 25
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
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
Reputation: 66815
You basically have two options:
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.
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