Matlab -- SVM -- 所有多数 Class 具有相同分数和 AUC = .50 的预测

Matlab -- SVM -- All Majority Class Predictions with Same Score and AUC = .50

我在 Matlab 中使用 RBF 内核训练 SVM 时遇到了一个奇怪的问题。问题是,在进行网格搜索时,使用 10 折交叉验证,对于 C 和 Sigma 值,我总是得到大约等于 .50 的 AUC 值(在 .48 和 .54 之间变化,具体取决于)——我得到了这个from: [X,Y,T,AUC] = perfcurve(dSet1Label(test),label, 1); 其中 dSet1Label(test) 是实际测试集标签,label 是预测标签。 classifier 仅预测大多数 class,占数据的 90% 以上。

经过进一步调查,在查看分数时(从 [label,score] = predict(svmStruct, dSet1(test,:)); 获得,其中 svmStruct 是在 9/10 的数据上训练的模型,dSet1(test,:) 是剩余的 1/ 10) 他们都一样:

0.8323   -0.8323
0.8323   -0.8323
0.8323   -0.8323
0.8323   -0.8323
0.8323   -0.8323
0.8323   -0.8323
0.8323   -0.8323
0.8323   -0.8323
0.8323   -0.8323
  .         .
  .         .
  .         .
0.8323   -0.8323

数据由 443 个特征和 6,453 个实例组成,其中 542 个是阳性 class。根据标准 SVM 协议,这些功能已扩展到 [0,1] 的范围。 classes 由 {-1,1}.

表示

我的代码如下:

load('datafile.m');
boxVals = [1,2,5,10,20,50,100,200,500,1000];
rbfVals = [.0001,.01,.1,1,2,3,5,10,20];
[m,n] = size(dataset1);
[c,v] = size(boxVals);
[e,r] = size(rbfVals);
auc_holder = [];
accuracy_holder = [];
for i = 1:v
     curBox = boxVals(i)
     for j = 1:r
         curRBF = rbfVals(j)
         valInd = crossvalind('Kfold', m, 10);
         temp_auc = [];
         temp_acc = [];
         cp = classperf(dSet1Label);
         for k = 1:10
             test = (valInd==k); train = ~test;
             svmStruct = fitcsvm(dSet1(train,:), dSet1Label(train), 'KernelFunction', 'rbf', 'BoxConstraint', curBox, 'KernelScale', curRBF);
             [label,score] = predict(svmStruct, dSet1(test,:));
             accuracy = sum(dSet1Label(test) == label)/numel(dSet1Label(test));
             [X,Y,T,AUC] = perfcurve(dSet1Label(test),label, 1);
             temp_auc = [temp_auc AUC];
             temp_acc = [temp_acc accuracy];
         end
         avg_auc = mean(temp_auc);
         avg_acc = mean(temp_acc);
         auc_holder = [auc_holder avg_auc];
         accuracy_holder = [accuracy_holder avg_acc];
     end
end

谢谢!

*编辑 1:看来,无论我将框约束设置为什么,所有数据点都被视为支持向量。

除非您有一些实施错误(使用合成的、分离良好的数据测试您的代码),否则问题可能在于 class 不平衡。这可以通过调整 missclassification cost (See this discussion in CV) 来解决。我会使用 fitcsvmcost 参数来增加少数 class 的未命中 class 化成本,使其比多数 class 大 9 倍,并且查看问题是否仍然存在。另一个需要考虑的问题是 class 分层(请参阅 crossvalind 文档 - 您必须定义一个 group 参数,以便每个折叠都有相似的 class 比例)。