@Test public void testInformationCategoricalFeature() { ExampleSet exampleSet = examplesForCategoryCounts(new int[][] { {2, 6}, {1, 1}, {0, 1}, }); List<Decision> decisions = Decision.decisionsFromExamples(exampleSet, 0, 100); assertEquals(2, decisions.size()); BitSet categories0 = ((CategoricalDecision) decisions.get(0)).getCategoryIDs(); BitSet categories1 = ((CategoricalDecision) decisions.get(1)).getCategoryIDs(); assertEquals(1, categories0.cardinality()); assertTrue(categories0.get(2)); assertEquals(2, categories1.cardinality()); assertTrue(categories1.get(0)); assertTrue(categories1.get(2)); Pair<Decision,Double> best = CategoricalInformation.bestGain(decisions, exampleSet); assertEquals(categories0, ((CategoricalDecision) best.getFirst()).getCategoryIDs()); assertEquals(Information.entropy(new int[] {3,8}) - (10.0/11.0)*Information.entropy(new int[] {3,7}) - ( 1.0/11.0)*Information.entropy(new int[] {0,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();   }