in samoa-api/src/main/java/org/apache/samoa/learners/classifiers/trees/ModelAggregatorProcessor.java [472:535]
protected void continueAttemptToSplit(ActiveLearningNode activeLearningNode, FoundNode foundNode) {
AttributeSplitSuggestion bestSuggestion = activeLearningNode.getDistributedBestSuggestion();
AttributeSplitSuggestion secondBestSuggestion = activeLearningNode.getDistributedSecondBestSuggestion();
// compare with null split
double[] preSplitDist = activeLearningNode.getObservedClassDistribution();
AttributeSplitSuggestion nullSplit = new AttributeSplitSuggestion(null, new double[0][],
this.splitCriterion.getMeritOfSplit(preSplitDist, new double[][] { preSplitDist }));
if ((bestSuggestion == null) || (nullSplit.compareTo(bestSuggestion) > 0)) {
secondBestSuggestion = bestSuggestion;
bestSuggestion = nullSplit;
} else {
if ((secondBestSuggestion == null) || (nullSplit.compareTo(secondBestSuggestion) > 0)) {
secondBestSuggestion = nullSplit;
}
}
boolean shouldSplit = false;
if (secondBestSuggestion == null) {
shouldSplit = true;
} else {
double hoeffdingBound = computeHoeffdingBound(
this.splitCriterion.getRangeOfMerit(activeLearningNode.getObservedClassDistribution()), this.splitConfidence,
activeLearningNode.getWeightSeen());
if ((bestSuggestion.merit - secondBestSuggestion.merit > hoeffdingBound) || (hoeffdingBound < tieThreshold)) {
shouldSplit = true;
}
// TODO: add poor attributes removal
}
SplitNode parent = foundNode.getParent();
int parentBranch = foundNode.getParentBranch();
// split if the Hoeffding bound condition is satisfied
if (shouldSplit) {
if (bestSuggestion.splitTest != null) {
SplitNode newSplit = new SplitNode(bestSuggestion.splitTest, activeLearningNode.getObservedClassDistribution());
for (int i = 0; i < bestSuggestion.numSplits(); i++) {
Node newChild = newLearningNode(bestSuggestion.resultingClassDistributionFromSplit(i), this.parallelismHint);
newSplit.setChild(i, newChild);
}
this.activeLeafNodeCount--;
this.decisionNodeCount++;
this.activeLeafNodeCount += bestSuggestion.numSplits();
if (parent == null) {
this.treeRoot = newSplit;
} else {
parent.setChild(parentBranch, newSplit);
}
}
// TODO: add check on the model's memory size
}
// housekeeping
activeLearningNode.endSplitting();
activeLearningNode.setWeightSeenAtLastSplitEvaluation(activeLearningNode.getWeightSeen());
}