如何在多种类型特征上训练 svm

how to train svm on multiple type features

我想在包含特征 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 输出命名为 label
但 X 不能接受这种形式的输入

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

你基本上有两个选择:

  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 都在常规向量上工作,因此您可以任意定义它们,只需将它们的总和用作 "joint" 核函数。这种方法比较复杂,但在定义处理复杂数据的方式方面给了您很大的自由度。

这是一个简单的例子

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