2015-06-22 2 views
1

У меня возникла странная проблема в обучении SVM с ядром RBF в Matlab. Проблема заключается в том, что при выполнении поиска по сетке с использованием 10-кратной кросс-валидации для значений C и Sigma я всегда получаю значения AUC, равные приблизительно 0,50 (варьируя от 0,48 до 0,54 в зависимости) - я получил это от: [X,Y,T,AUC] = perfcurve(dSet1Label(test),label, 1);, где dSet1Label(test) являются фактическими метками набора тестов, а label - это предсказываемые этикетки. Классификатор предсказывает только мажоритарный класс, составляющий чуть более 90% данных.Matlab - SVM - Все предсказания класса большинства с одинаковым счетом и AUC = .50

После дальнейшего исследования, при взгляде на баллах (полученный из [label,score] = predict(svmStruct, dSet1(test,:));, где svmStruct является моделью обучения на 9/10ths данных и dSet1(test,:) является remaing 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 имеют положительный класс. Эти функции были масштабированы до диапазона [0,1] в стандартном протоколе SVM. Классы представлены {-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: Кажется, что независимо от того, для чего я устанавливаю ограничение на ящик, все точки данных считаются векторами поддержки.

ответ

1

Если у вас есть ошибка реализации (проверьте свой код с синтетическими, хорошо разделенными данными), проблема может возникнуть в дисбалансе класса. Это можно решить, установив стоимость пропускаемой классификации (See this discussion in CV). Я бы воспользовался параметром costfitcsvm, чтобы увеличить стоимость пропускаемой классификации класса меньшинства в 9 раз больше, чем мажоритарный класс, и посмотреть, сохраняется ли проблема. Еще одна проблема, которую следует рассмотреть, - это стратификация классов (см. Документацию по перекрестным ссылкам - вам необходимо определить параметр group, чтобы каждая сводка имела аналогичную прообраз).

+0

Спасибо за ваши предложения. Я займусь этим в ближайшие пару часов или около того. Я попытался немного поиграть с параметром матрицы «Cost», но не был уверен, использую ли я его для правильного взвешивания положительных примеров, которые классифицируются как отрицательные. Он определяется: 'fitcsvm (...., 'Cost', [0,1; 9,0], ....)'. Это правильный способ установить стоимость для положительного, классифицированного как отрицательный? – DMML

+0

похоже, что он работал вместе с моим поиском сетки - для ряда комбинаций параметров я до сих пор получаю .50 AUC, но для других я не получаю чуть ниже 0,7, что является резким улучшением! Спасибо за вашу помощь! Я отмечу, как принято. – DMML

Смежные вопросы