double[][] dataZs, double[][] dataWs) throws Exception{
int numAttributes = data.numAttributes();
if (numAttributes < 2) throw new Exception("Can't select Model without non-class attribute");
if (data.numInstances() < m_minNumInstances) return new NoSplit(new Distribution(data));
double bestGain = -Double.MAX_VALUE;
int bestAttribute = -1;
//try split on every attribute
for (int i = 0; i < numAttributes; i++) {
if (i != data.classIndex()) {
//build split
ResidualSplit split = new ResidualSplit(i);
split.buildClassifier(data, dataZs, dataWs);
if (split.checkModel(m_minNumInstances)){
//evaluate split
double gain = split.entropyGain();
if (gain > bestGain) {
bestGain = gain;
bestAttribute = i;
}
}
}
}
if (bestGain >= m_minInfoGain){
//return best split
ResidualSplit split = new ResidualSplit(bestAttribute);
split.buildClassifier(data, dataZs, dataWs);
return split;
} else {
//could not find any split with enough information gain
return new NoSplit(new Distribution(data));
}
}