package org.neuroph.eval.classification;
import org.neuroph.eval.classification.ClassificationResult;
import org.neuroph.core.NeuralNetwork;
import org.neuroph.core.data.DataSet;
import org.neuroph.core.data.DataSetRow;
/**
* Class used to test if there is statistical significant difference between two classifiers
*/
public class McNemarTest {
private int[][] contigencyMatrix = new int[2][2];
/**
* @param network1 first trained neurl netowrk
* @param network2 second trained neural network
* @param dataSet data set used for performance evaluation
* @return if there exists significant difference between two classification models
*/
public boolean evaluateNetworks(NeuralNetwork network1, NeuralNetwork network2, DataSet dataSet) {
for (DataSetRow dataRow : dataSet.getRows()) {
forwardPass(network1, dataRow);
forwardPass(network2, dataRow);
double[] networkOutput1 = network1.getOutput();
double[] networkOutput2 = network2.getOutput();
int maxNeuronIdx1 = Utils.maxIdx(networkOutput1);
int maxNeuronIdx2 = Utils.maxIdx(networkOutput2);
ClassificationResult output1 = new ClassificationResult(maxNeuronIdx1, networkOutput1[maxNeuronIdx1]);
ClassificationResult output2 = new ClassificationResult(maxNeuronIdx2, networkOutput2[maxNeuronIdx2]);
// ClassificationResult output1 = ClassificationResult.fromMaxOutput(network1.getOutput());
// ClassificationResult output2 = ClassificationResult.fromMaxOutput(network2.getOutput());
//are their results different
if (output1.getClassIdx() != output2.getClassIdx()) {
//if first one is correct and second incorrect
if (output1.getClassIdx() == getDesiredClass(dataRow.getDesiredOutput())) {
contigencyMatrix[1][0]++;
//if first is incorrect and second is correct
} else {
contigencyMatrix[0][1]++;
}
} else {
//if both are correct
if (output1.getClassIdx() == getDesiredClass(dataRow.getDesiredOutput())) {
contigencyMatrix[1][1]++;
//if both are incorrect
} else {
contigencyMatrix[0][0]++;
}
}
}
printContingencyMatrix();
double a = Math.abs(contigencyMatrix[0][1] - contigencyMatrix[1][0]) - 1;
double hiSquare = (a * a) / (contigencyMatrix[0][1] + contigencyMatrix[1][0]);
System.out.println(hiSquare);
return hiSquare > 3.841;
}
private void printContingencyMatrix() {
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
System.out.print(contigencyMatrix[i][j] + " ");
}
System.out.println();
}
}
private int getDesiredClass(double[] output) {
for (int i = 0; i < output.length; i++) {
if (output[i] == 1) {
return i;
}
}
return -1;
}
private void forwardPass(NeuralNetwork neuralNetwork, DataSetRow dataRow) {
neuralNetwork.setInput(dataRow.getInput());
neuralNetwork.calculate();
}
}
Ads help maintain this website.