我想在由特征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:使用序列设置数组元素。
答案 0 :(得分:1)
您基本上有两个选择:
将您的数据转换为常规格式并运行典型的SVM内核,在您的情况下,如果p1始终为3元素,则只展平表示,因此[[1,2,3],4,5]变为[1, 2,3,4,5]你很高兴。
实现自己的自定义内核函数,分别处理每个部分,因为两个内核的总和仍然是内核,例如可以定义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;
}