在Matlab中用SVM编写代价函数的正确方法-无法理解';成本';矩阵

在Matlab中用SVM编写代价函数的正确方法-无法理解';成本';矩阵,matlab,machine-learning,deep-learning,classification,svm,Matlab,Machine Learning,Deep Learning,Classification,Svm,我想将SVM应用于不平衡的数据集,并建议可以通过调整fitcsvm函数的参数来实现。虽然,对于不平衡数据,SVM可能不是一个好的选择,但我希望看到教育目的的结果 我如何调整SVM中的参数,以便对真实类(标记为1)的误分类错误施加更大的惩罚,因为我的数据自然是不平衡的,与0(false)相比,1)的数量更少。只有2%被标记为1 数据集有1473个样本(98%)标记为0,27个样本(2%)标记为1 训练数据有1000个样本标记为0,并且 12个样本为1 测试数据有473个样本(97%)为0,15个

我想将SVM应用于不平衡的数据集,并建议可以通过调整
fitcsvm
函数的参数来实现。虽然,对于不平衡数据,SVM可能不是一个好的选择,但我希望看到教育目的的结果

我如何调整SVM中的参数,以便对真实类(标记为
1
)的误分类错误施加更大的惩罚,因为我的数据自然是不平衡的,与
0
(false)相比,
1
)的数量更少。只有2%被标记为
1

  • 数据集有1473个样本(98%)标记为
    0
    ,27个样本(2%)标记为
    1

  • 训练数据有1000个样本标记为
    0
    ,并且 12个样本为
    1

  • 测试数据有473个样本(97%)为
    0
    ,15个样本(3%)为
    1
    。我使用成本矩阵,
    c
    1
    施加了两次惩罚,如下所示:
结果是

混淆矩阵是

    473     0
    15     0
predict
向量中的答案都是
1
标签。显然,成本矩阵无法正常工作。如果我要惩罚0(多数类)或1(少数类)的错误分类,我无法完全理解查看成本矩阵。为什么第一行和第一列元素=0,而另一个是2。
请提供帮助。

这可以使用一些测试数据显示,例如:

rng(42)
X = randn(1000, 2);
y = rand(1000, 1) >= 0.98;
X(y==1, :) = X(y==1, :) + [2, 2];
由于类别不平衡,使用高斯核函数的简单SVM将无法正常工作:

model = fitcsvm(X, y, 'KernelFunction', 'rbf')
confusionmat(y, model.predict(X))

ans =

   979     2
    14     5
正如您已经认识到的,
“Cost”
参数可以通过对少数类的错误分类施加更高的惩罚来补偿不平衡。在二维情况下,成本矩阵如下所示:

[ Cost(0, 0),    Cost(0, 1)
  Cost(1, 0),    Cost(1, 1) ]
现在,
Cost(0,0)
是将属于类
0
的样本分类为类
0
的成本。这是一个正确的分类,因此通常成本设置为0。接下来,
成本(0,1)
是将属于类
0
的点分类为类
1
的成本,即错误分类

在您的示例中,类
0
比类
1
更可能发生,因此我们应该对将类
0
(多数)中的样本分类为类
1
(少数)施加较低的惩罚,并对将类
1
(少数)中的样本分类为类
0
施加较高的惩罚(大多数)。因此
成本(0,1)
应该较低,而
成本(1,0)
应该较高

通过设置
c=[0,2.2;1,0]
,您做了相反的事情-您建议
fitcsvm
函数将少数样本分类为多数样本,而不是相反:

c = [0, 2.2; 1, 0];
model = fitcsvm(X, y, 'KernelFunction', 'rbf', 'Cost', c);
confusionmat(y, model.predict(X))

ans =

   981     0
    19     0
如果在成本矩阵
c
中使用相同的权重,但切换
cost(0,1)
cost(1,0)
,则会产生所需的效果:

c = [0, 1; 2.2, 0];
model = fitcsvm(X, y, 'KernelFunction', 'rbf', 'Cost', c);
confusionmat(y, model.predict(X))

ans =

   973     8
     7    12

这确实改善了我们的结果:总的来说,我们有相似数量的错误分类:15个而不是16个总的错误分类,但是我们的19个少数群体样本中有12个在新模型中是正确的,而之前只有5个。

根据您的结果,似乎两个群体属于相同的分布。尝试过采样您的培训数据(使用可用的阳性样本生成更多的阳性样本)并在此基础上构建您的模型,然后在测试中测试您的模型。

感谢您的回答和如此简单易懂的说明。您能澄清以下几点吗?(1)在我的数据集中,实际上只有2%是真正的正类。通过包含成本和不包含成本,我在混淆矩阵和精度方面得到了相同的结果。我使用不同的成本值进行了检查,如2.2、3、4、5,但没有效果。因此,这种方法是否可能不适合我的数据集?(2)成本值是否有一个最大值和最小值的范围?如何决定是放2还是3等?以及(3)一般来说,一旦对模型进行了培训,我该如何使用培训后的模型?我应该在看不见的数据上使用培训后的模型,但它在Matlab中的功能是什么?我发现从2.2到49,成本值的分类没有变化,融合矩阵保持不变,这是
[473,0;15,0]
。当我将成本从2.2增加到50时,我才看到了变化,并得到了少数类
1
的所有正确预测,但随后类
0
预测变得很差。因此,我如何知道错误分类成本值增加多少?
c = [0, 2.2; 1, 0];
model = fitcsvm(X, y, 'KernelFunction', 'rbf', 'Cost', c);
confusionmat(y, model.predict(X))

ans =

   981     0
    19     0
c = [0, 1; 2.2, 0];
model = fitcsvm(X, y, 'KernelFunction', 'rbf', 'Cost', c);
confusionmat(y, model.predict(X))

ans =

   973     8
     7    12