package org.neuroph.eval;
import org.neuroph.eval.classification.ConfusionMatrix;
import org.neuroph.eval.classification.Utils;
public abstract class ClassifierEvaluator implements Evaluator {
private final String[] classLabels;
private double threshold; // used for binary classifier but should also be used for multi class
ConfusionMatrix confusionMatrix;
private ClassifierEvaluator(String[] labels) {
this.classLabels = labels;
confusionMatrix = new ConfusionMatrix(labels);
}
@Override
public ConfusionMatrix getResult() {
return confusionMatrix;
}
public double getThreshold() {
return threshold;
}
public final void setThreshold(double threshold) {
this.threshold = threshold;
}
@Override
public void reset() {
confusionMatrix = new ConfusionMatrix(classLabels);
}
/**
* Binary evaluator used for computation of metrics in case when data has only one output result (one output neuron)
*/
public static final class Binary extends ClassifierEvaluator {
public static final String[] CLASS_LABELS = new String[]{"True", "False"};
public Binary(double threshold) {
super(CLASS_LABELS);
setThreshold(threshold);
}
@Override
public void processNetworkResult(double[] networkOutput, double[] desiredOutput) {
boolean actualClass = (desiredOutput[0] > 0); // true id desired output is 1, false otherwise
boolean predictedClass = (networkOutput[0] > getThreshold()); // true if actual output is >= threshold, false otherwise
if (actualClass && predictedClass) {
confusionMatrix.incrementElement(0, 0); // tp
} else if (actualClass && !predictedClass) {
confusionMatrix.incrementElement(0, 1); // fn
} else if (!actualClass && predictedClass) {
confusionMatrix.incrementElement(1, 0); // fp
} else if (!actualClass && !predictedClass) {
confusionMatrix.incrementElement(1, 1); // tn
}
}
}
/**
* Evaluator used for computation of metrics in case when data has
* multiple classes - one vs many classification
*/
public static class MultiClass extends ClassifierEvaluator {
// TODO: use column labels here
public MultiClass(String[] classLabels) {
super(classLabels);
// dataSet.getColumnNames()
}
@Override
public void processNetworkResult(double[] predictedOutput, double[] actualOutput) {
// just get max index
int actualClassIdx = Utils.maxIdx(actualOutput);
int predictedClassIdx = Utils.maxIdx(predictedOutput);
// TODO: use threshold here not only max
confusionMatrix.incrementElement(actualClassIdx, predictedClassIdx);
}
}
}
Ads help maintain this website.