2014-12-11 2 views
1

Я работаю над бинарным классификатором, используя Encog (через Java). Я настроил его с помощью SVM или нейронной сети, и я хочу оценить качество различных моделей, используя (частично) область под кривой ROC.Оценка бинарной классификации Encog для ROC

В частности, я бы идеально хотел преобразовать вывод модели в некоторый уровень доверия к прогнозу, который можно использовать для ранжирования в ROC, но мне еще нужно найти что-либо в документации.

В коде, я получаю результаты модели что-то вроде:

MLData result = ((MLRegression) method).compute(pair.getInput()); 
String classification = normHelper.denormalizeOutputVectorToString(result)[0]; 

Как мне получить численное доверие классификации?

+0

Вы должны задать конкретные вопросы; вы, кажется, не спрашиваете вообще! –

ответ

0

Encog не имеет прямой поддержки для кривых ROC. Кривая ROC представляет собой скорее визуализацию, чем фактический тип модели, которая в первую очередь ориентирована на Encog.

Создание кривой ROC для SVM и нейронных сетей несколько отличается. Для нейронной сети вы должны установить пороговые значения для классификационных нейронов. Существует хорошая статья об этом здесь: http://www.lcc.uma.es/~jja/recidiva/048.pdf

В конечном итоге я могу добавить прямую поддержку кривых ROC в Encog в будущем. Они становятся очень распространенной визуализацией.

+0

Благодарим вас за ссылку. Мне придется немного пожевать его. – Adam

+0

С точки зрения SVM, как наивного пользователя SVM, кажется, что я могу переделать проблему классификации в проблему регрессии с двумя классификациями, обозначенными двумя разными значениями. В этой модели классификация затем извлекается простым округлением до ближайшего класса, с тем преимуществом, что в этой методологии я могу использовать расстояние до порога принятия решения в качестве прокси-сервера для уверенности в предсказании. На моем наборе данных это, похоже, дает сопоставимые тарифы TP/FP с использованием стандартного подхода SVM, но я беспокоюсь о том, что я нахожусь на шаткой теоретической основе. Есть предположения? – Adam

1

Я нашел способ уговорить вероятности прогноза из SVM внутри рамки encog. Этот метод основан на эквиваленте опции -b для libSVM (см. http://www.csie.ntu.edu.tw/~cjlin/libsvm/index.html)

Для этого переопределите класс SVM из encog. Конструктор будет включать оценки вероятности через объект smv_parameter (см. Ниже). Затем при выполнении вычисления вызовите метод svm_predict_probability, как показано ниже.

Предостережение: ниже - только фрагмент кода, и для того, чтобы быть полезным, вам, вероятно, потребуется написать другие конструкторы и передать полученные вероятности из приведенных ниже методов. Этот фрагмент основан на версии 3.3.0.

public class MySVMProbability extends SVM { 

public MySVMProbability(SVM method) { 
    super(method.getInputCount(), method.getSVMType(), method.getKernelType()); 
    // Enable probability estimates 
    getParams().probability = 1; 
} 


@Override 
public int classify(final MLData input) { 
    svm_model model = getModel(); 
    if (model == null) { 
     throw new EncogError(
       "Can't use the SVM yet, it has not been trained, " 
       + "and no model exists."); 
    } 

    final svm_node[] formattedInput = makeSparse(input); 
    final double probs[] = new double[svm.svm_get_nr_class(getModel())]; 
    final double d = svm.svm_predict_probability(model, formattedInput, probs); 

    /* probabilities for each class are in probs[] */ 

    return (int) d; 
} 


@Override 
public MLData compute(MLData input) { 
    svm_model model = getModel(); 
    if (model == null) { 
     throw new EncogError(
       "Can't use the SVM yet, it has not been trained, " 
       + "and no model exists."); 
    } 

    final MLData result = new BasicMLData(1); 

    final svm_node[] formattedInput = makeSparse(input); 

    final double probs[] = new double[svm.svm_get_nr_class(getModel())]; 
    final double d = svm.svm_predict_probability(model, formattedInput, probs); 
    /* probabilities for each class are in probs[] */ 
    result.setData(0, d); 

    return result; 
} 
}