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

Proper way to write the cost function in SVM in Matlab - unable to understand 'Cost' matrix

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

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

c=[0 2.2;1 0];
model = fitcsvm(train_x,train_y,'KernelFunction', 'rbf', 'Cost',c);
[predLabel,score] = predict(model,test_x);

The result is

Precision for label 0: 9.692623e-01
Precision for label 1: NaN
Recall for label 0: 1
Recall for label 1: 0

Accuracy = 96.9%
Average err = 0.03

混淆矩阵为

    473     0
    15     0

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

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

rng(42)
X = randn(1000, 2);
y = rand(1000, 1) >= 0.98;
X(y==1, :) = X(y==1, :) + [2, 2];

由于 class 不平衡,具有高斯核函数的简单 SVM 将无法正常工作:

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

ans =

   979     2
    14     5

正如您已经认识到的那样,'Cost' 参数可用于通过对少数 class 的错误class 设置更高的惩罚来补偿不平衡。在二维情况下,成本矩阵构建如下:

[ Cost(0, 0),    Cost(0, 1)
  Cost(1, 0),    Cost(1, 1) ]

现在,Cost(0, 0) 是将属于 class 0 的样本 class 化为 class 0 的成本。这是一个正确的class化,所以通常成本设置为0。接下来,Cost(0, 1)是class化属于class的点的成本0 为 class 1,即错误的 class化。

在你的例子中,class 0 比 class 1 更有可能发生,所以我们应该对 classifying 施加较低的惩罚来自 class 0(多数)的样本作为 class 1(少数),以及对 class 化 [=51] 样本的高惩罚=] 1(少数)和class 0(多数)。所以Cost(0, 1)应该是low而Cost(1, 0)应该是high。

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

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

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

根据您的结果,类 似乎属于同一个分布。尝试对训练数据进行过采样(使用可用的正样本生成更多正样本)并以此为基础构建模型,然后在测试中测试模型。