@Test public void testInformationNumericFeature() { ExampleSet exampleSet = examplesForNumericValues(new float[][]{ new float[]{1.0f, 2.0f}, new float[]{0.0f, 3.0f}, }); List<Decision> decisions = Decision.decisionsFromExamples(exampleSet, 0, 100); assertEquals(3, decisions.size()); assertEquals(2.5f, ((NumericDecision) decisions.get(0)).getThreshold()); assertEquals(1.5f, ((NumericDecision) decisions.get(1)).getThreshold()); assertEquals(0.5f, ((NumericDecision) decisions.get(2)).getThreshold()); Pair<Decision,Double> best = CategoricalInformation.bestGain(decisions, exampleSet); assertEquals(2.5f, ((NumericDecision) best.getFirst()).getThreshold()); assertEquals(Information.entropy(new int[] {2,2}) - (1.0/4.0)*Information.entropy(new int[] {0,1}) - (3.0/4.0)*Information.entropy(new int[] {2,1}), best.getValue().doubleValue()); }
static Pair<Decision,Double> bestGain(Iterable<Decision> decisions, ExampleSet examples) { int numCategories = examples.getTargetCategoryCount(); int[] countsNegative = new int[numCategories]; List<Example> exampleList = examples.getExamples(); int numExamples = exampleList.size(); for (Example example : exampleList) { int category = ((CategoricalFeature) example.getTarget()).getValueID(); countsNegative[category]++; } int numNegative = numExamples; double entropyAll = Information.entropy(countsNegative); BitSet notYetPositiveExamples = new BitSet(numExamples); notYetPositiveExamples.set(0, numExamples); Decision bestDecision = null; double bestGain = Double.NEGATIVE_INFINITY; int[] countsPositive = new int[numCategories]; int numPositive = 0; for (Decision decision : decisions) { int nextNotYetPositive = -1; while ((nextNotYetPositive = notYetPositiveExamples.nextSetBit(nextNotYetPositive + 1)) >= 0) { Example example = exampleList.get(nextNotYetPositive); if (decision.isPositive(example)) { int category = ((CategoricalFeature) example.getTarget()).getValueID(); countsNegative[category]--; numNegative--; countsPositive[category]++; numPositive++; notYetPositiveExamples.clear(nextNotYetPositive); } } double entropyNegative = Information.entropy(countsNegative); double entropyPositive = Information.entropy(countsPositive); double gain = entropyAll - (numNegative * entropyNegative + numPositive * entropyPositive) / (numNegative + numPositive); if (gain > bestGain) { bestGain = gain; bestDecision = decision; } } return bestDecision == null ? null : new Pair<Decision,Double>(bestDecision, bestGain); }
CategoricalInformation { static Pair<Decision,Double> bestGain(Iterable<Decision> decisions, ExampleSet examples) { int numCategories = examples.getTargetCategoryCount(); int[] countsNegative = new int[numCategories]; List<Example> exampleList = examples.getExamples(); int numExamples = exampleList.size(); for (Example example : exampleList) { int category = ((CategoricalFeature) example.getTarget()).getValueID(); countsNegative[category]++; } int numNegative = numExamples; double entropyAll = Information.entropy(countsNegative); BitSet notYetPositiveExamples = new BitSet(numExamples); notYetPositiveExamples.set(0, numExamples); Decision bestDecision = null; double bestGain = Double.NEGATIVE_INFINITY; int[] countsPositive = new int[numCategories]; int numPositive = 0; for (Decision decision : decisions) { int nextNotYetPositive = -1; while ((nextNotYetPositive = notYetPositiveExamples.nextSetBit(nextNotYetPositive + 1)) >= 0) { Example example = exampleList.get(nextNotYetPositive); if (decision.isPositive(example)) { int category = ((CategoricalFeature) example.getTarget()).getValueID(); countsNegative[category]--; numNegative--; countsPositive[category]++; numPositive++; notYetPositiveExamples.clear(nextNotYetPositive); } } double entropyNegative = Information.entropy(countsNegative); double entropyPositive = Information.entropy(countsPositive); double gain = entropyAll - (numNegative * entropyNegative + numPositive * entropyPositive) / (numNegative + numPositive); if (gain > bestGain) { bestGain = gain; bestDecision = decision; } } return bestDecision == null ? null : new Pair<Decision,Double>(bestDecision, bestGain); } }
CategoricalInformation { static Pair<Decision,Double> bestGain(Iterable<Decision> decisions, ExampleSet examples) { int numCategories = examples.getTargetCategoryCount(); int[] countsNegative = new int[numCategories]; List<Example> exampleList = examples.getExamples(); int numExamples = exampleList.size(); for (Example example : exampleList) { int category = ((CategoricalFeature) example.getTarget()).getValueID(); countsNegative[category]++; } int numNegative = numExamples; double entropyAll = Information.entropy(countsNegative); BitSet notYetPositiveExamples = new BitSet(numExamples); notYetPositiveExamples.set(0, numExamples); Decision bestDecision = null; double bestGain = Double.NEGATIVE_INFINITY; int[] countsPositive = new int[numCategories]; int numPositive = 0; for (Decision decision : decisions) { int nextNotYetPositive = -1; while ((nextNotYetPositive = notYetPositiveExamples.nextSetBit(nextNotYetPositive + 1)) >= 0) { Example example = exampleList.get(nextNotYetPositive); if (decision.isPositive(example)) { int category = ((CategoricalFeature) example.getTarget()).getValueID(); countsNegative[category]--; numNegative--; countsPositive[category]++; numPositive++; notYetPositiveExamples.clear(nextNotYetPositive); } } double entropyNegative = Information.entropy(countsNegative); double entropyPositive = Information.entropy(countsPositive); double gain = entropyAll - (numNegative * entropyNegative + numPositive * entropyPositive) / (numNegative + numPositive); if (gain > bestGain) { bestGain = gain; bestDecision = decision; } } return bestDecision == null ? null : new Pair<Decision,Double>(bestDecision, bestGain); } private  CategoricalInformation(); }
CategoricalInformation { static Pair<Decision,Double> bestGain(Iterable<Decision> decisions, ExampleSet examples) { int numCategories = examples.getTargetCategoryCount(); int[] countsNegative = new int[numCategories]; List<Example> exampleList = examples.getExamples(); int numExamples = exampleList.size(); for (Example example : exampleList) { int category = ((CategoricalFeature) example.getTarget()).getValueID(); countsNegative[category]++; } int numNegative = numExamples; double entropyAll = Information.entropy(countsNegative); BitSet notYetPositiveExamples = new BitSet(numExamples); notYetPositiveExamples.set(0, numExamples); Decision bestDecision = null; double bestGain = Double.NEGATIVE_INFINITY; int[] countsPositive = new int[numCategories]; int numPositive = 0; for (Decision decision : decisions) { int nextNotYetPositive = -1; while ((nextNotYetPositive = notYetPositiveExamples.nextSetBit(nextNotYetPositive + 1)) >= 0) { Example example = exampleList.get(nextNotYetPositive); if (decision.isPositive(example)) { int category = ((CategoricalFeature) example.getTarget()).getValueID(); countsNegative[category]--; numNegative--; countsPositive[category]++; numPositive++; notYetPositiveExamples.clear(nextNotYetPositive); } } double entropyNegative = Information.entropy(countsNegative); double entropyPositive = Information.entropy(countsPositive); double gain = entropyAll - (numNegative * entropyNegative + numPositive * entropyPositive) / (numNegative + numPositive); if (gain > bestGain) { bestGain = gain; bestDecision = decision; } } return bestDecision == null ? null : new Pair<Decision,Double>(bestDecision, bestGain); } private  CategoricalInformation();  }
CategoricalInformation { static Pair<Decision,Double> bestGain(Iterable<Decision> decisions, ExampleSet examples) { int numCategories = examples.getTargetCategoryCount(); int[] countsNegative = new int[numCategories]; List<Example> exampleList = examples.getExamples(); int numExamples = exampleList.size(); for (Example example : exampleList) { int category = ((CategoricalFeature) example.getTarget()).getValueID(); countsNegative[category]++; } int numNegative = numExamples; double entropyAll = Information.entropy(countsNegative); BitSet notYetPositiveExamples = new BitSet(numExamples); notYetPositiveExamples.set(0, numExamples); Decision bestDecision = null; double bestGain = Double.NEGATIVE_INFINITY; int[] countsPositive = new int[numCategories]; int numPositive = 0; for (Decision decision : decisions) { int nextNotYetPositive = -1; while ((nextNotYetPositive = notYetPositiveExamples.nextSetBit(nextNotYetPositive + 1)) >= 0) { Example example = exampleList.get(nextNotYetPositive); if (decision.isPositive(example)) { int category = ((CategoricalFeature) example.getTarget()).getValueID(); countsNegative[category]--; numNegative--; countsPositive[category]++; numPositive++; notYetPositiveExamples.clear(nextNotYetPositive); } } double entropyNegative = Information.entropy(countsNegative); double entropyPositive = Information.entropy(countsPositive); double gain = entropyAll - (numNegative * entropyNegative + numPositive * entropyPositive) / (numNegative + numPositive); if (gain > bestGain) { bestGain = gain; bestDecision = decision; } } return bestDecision == null ? null : new Pair<Decision,Double>(bestDecision, bestGain); } private  CategoricalInformation();   }