use of org.knime.base.node.mine.treeensemble2.model.TreeNodeNominalCondition in project knime-core by knime.
the class TreeNominalColumnData method updateChildMembershipsMultiway.
private BitSet updateChildMembershipsMultiway(final TreeNodeNominalCondition nomCondition, final DataMemberships parentMemberships) {
String value = nomCondition.getValue();
int att = -1;
final NominalValueRepresentation[] reps = getMetaData().getValues();
for (final NominalValueRepresentation rep : reps) {
if (rep.getNominalValue().equals(value)) {
att = rep.getAssignedInteger();
break;
}
}
if (att == -1) {
throw new IllegalStateException("Unknown value: " + value);
}
ColumnMemberships columnMemberships = parentMemberships.getColumnMemberships(getMetaData().getAttributeIndex());
BitSet inChild = new BitSet(columnMemberships.size());
columnMemberships.reset();
int start = 0;
for (int a = 0; a < att; a++) {
start += m_nominalValueCounts[a];
}
// Make sure that we are using an index >= start
if (!columnMemberships.nextIndexFrom(start)) {
return inChild;
}
boolean reachedEnd = false;
int end = start + m_nominalValueCounts[att];
for (int index = columnMemberships.getIndexInColumn(); index < end; index = columnMemberships.getIndexInColumn()) {
inChild.set(columnMemberships.getIndexInDataMemberships());
if (!columnMemberships.next()) {
reachedEnd = true;
break;
}
}
if (!reachedEnd && containsMissingValues() && nomCondition.acceptsMissings()) {
// move to missing values
for (int i = att; i < reps.length - 1; i++) {
start += m_nominalValueCounts[i];
}
if (columnMemberships.nextIndexFrom(start)) {
do {
inChild.set(columnMemberships.getIndexInDataMemberships());
} while (columnMemberships.next());
}
}
return inChild;
}
use of org.knime.base.node.mine.treeensemble2.model.TreeNodeNominalCondition in project knime-core by knime.
the class NominalMultiwaySplitCandidate method getChildConditions.
/**
* {@inheritDoc}
*/
@Override
public TreeNodeNominalCondition[] getChildConditions() {
TreeNominalColumnMetaData columnMeta = getColumnData().getMetaData();
NominalValueRepresentation[] values = columnMeta.getValues();
final int lengthNonMissing = values[values.length - 1].getNominalValue().equals(NominalValueRepresentation.MISSING_VALUE) ? values.length - 1 : values.length;
List<TreeNodeCondition> resultList = new ArrayList<TreeNodeCondition>(lengthNonMissing);
for (int i = 0; i < lengthNonMissing; i++) {
if (m_sumWeightsAttributes[i] >= TreeColumnData.EPSILON) {
resultList.add(new TreeNodeNominalCondition(columnMeta, i, i == m_missingsGoToChildIdx));
}
}
return resultList.toArray(new TreeNodeNominalCondition[resultList.size()]);
}
use of org.knime.base.node.mine.treeensemble2.model.TreeNodeNominalCondition in project knime-core by knime.
the class TreeNominalColumnDataTest method testCalcBestSplitClassificationMultiWay.
/**
* Tests the method
* {@link TreeNominalColumnData#calcBestSplitClassification(DataMemberships, ClassificationPriors, TreeTargetNominalColumnData, RandomData)}
* using multiway splits
*
* @throws Exception
*/
@Test
public void testCalcBestSplitClassificationMultiWay() throws Exception {
TreeEnsembleLearnerConfiguration config = createConfig(false);
config.setUseBinaryNominalSplits(false);
Pair<TreeNominalColumnData, TreeTargetNominalColumnData> tennisData = tennisData(config);
TreeNominalColumnData columnData = tennisData.getFirst();
TreeTargetNominalColumnData targetData = tennisData.getSecond();
TreeData treeData = createTreeData(tennisData);
assertEquals(SplitCriterion.Gini, config.getSplitCriterion());
double[] rowWeights = new double[SMALL_COLUMN_DATA.length];
Arrays.fill(rowWeights, 1.0);
IDataIndexManager indexManager = new DefaultDataIndexManager(treeData);
DataMemberships dataMemberships = new RootDataMemberships(rowWeights, treeData, indexManager);
ClassificationPriors priors = targetData.getDistribution(rowWeights, config);
SplitCandidate splitCandidate = columnData.calcBestSplitClassification(dataMemberships, priors, targetData, null);
assertNotNull(splitCandidate);
assertThat(splitCandidate, instanceOf(NominalMultiwaySplitCandidate.class));
assertFalse(splitCandidate.canColumnBeSplitFurther());
// manually via libre office calc
assertEquals(0.0744897959, splitCandidate.getGainValue(), 0.00001);
NominalMultiwaySplitCandidate multiWaySplitCandidate = (NominalMultiwaySplitCandidate) splitCandidate;
TreeNodeNominalCondition[] childConditions = multiWaySplitCandidate.getChildConditions();
assertEquals(3, childConditions.length);
assertEquals("S", childConditions[0].getValue());
assertEquals("O", childConditions[1].getValue());
assertEquals("R", childConditions[2].getValue());
}
use of org.knime.base.node.mine.treeensemble2.model.TreeNodeNominalCondition in project knime-core by knime.
the class TreeNominalColumnDataTest method testCalcBestSplitRegressionMultiwayXGBoostMissingValueHandling.
/**
* This method tests the XGBoost missing value handling in case of a regression task and multiway splits.
*
* @throws Exception
*/
@Test
public void testCalcBestSplitRegressionMultiwayXGBoostMissingValueHandling() throws Exception {
final TreeEnsembleLearnerConfiguration config = createConfig(true);
config.setMissingValueHandling(MissingValueHandling.XGBoost);
config.setUseBinaryNominalSplits(false);
final TestDataGenerator dataGen = new TestDataGenerator(config);
final String noMissingCSV = "A, A, A, B, B, B, B, C, C";
final String noMissingsTarget = "1, 2, 2, 7, 6, 5, 2, 3, 1";
TreeNominalColumnData dataCol = dataGen.createNominalAttributeColumn(noMissingCSV, "noMissings", 0);
TreeTargetNumericColumnData targetCol = TestDataGenerator.createNumericTargetColumn(noMissingsTarget);
double[] weights = new double[9];
Arrays.fill(weights, 1.0);
int[] indices = new int[9];
for (int i = 0; i < indices.length; i++) {
indices[i] = i;
}
final RandomData rd = config.createRandomData();
DataMemberships dataMemberships = new MockDataColMem(indices, indices, weights);
// first test the case that there are no missing values during training (we still need to provide a missing value direction for prediction)
SplitCandidate split = dataCol.calcBestSplitRegression(dataMemberships, targetCol.getPriors(weights, config), targetCol, rd);
assertNotNull("SplitCandidate may not be null", split);
assertThat(split, instanceOf(NominalMultiwaySplitCandidate.class));
assertEquals("Wrong gain.", 22.888888, split.getGainValue(), 1e-5);
assertTrue("No missing values in dataCol therefore the missedRows BitSet must be empty.", split.getMissedRows().isEmpty());
NominalMultiwaySplitCandidate nomSplit = (NominalMultiwaySplitCandidate) split;
TreeNodeNominalCondition[] conditions = nomSplit.getChildConditions();
assertEquals("3 nominal values therefore there must be 3 children.", 3, conditions.length);
assertEquals("Wrong value.", "A", conditions[0].getValue());
assertEquals("Wrong value.", "B", conditions[1].getValue());
assertEquals("Wrong value.", "C", conditions[2].getValue());
assertFalse("Missings should go with majority", conditions[0].acceptsMissings());
assertTrue("Missings should go with majority", conditions[1].acceptsMissings());
assertFalse("Missings should go with majority", conditions[2].acceptsMissings());
// test the case that there are missing values during training
final String missingCSV = "A, A, A, B, B, B, B, C, C, ?";
final String missingTarget = "1, 2, 2, 7, 6, 5, 2, 3, 1, 8";
dataCol = dataGen.createNominalAttributeColumn(missingCSV, "missing", 0);
targetCol = TestDataGenerator.createNumericTargetColumn(missingTarget);
weights = new double[10];
Arrays.fill(weights, 1.0);
indices = new int[10];
for (int i = 0; i < indices.length; i++) {
indices[i] = i;
}
dataMemberships = new MockDataColMem(indices, indices, weights);
split = dataCol.calcBestSplitRegression(dataMemberships, targetCol.getPriors(weights, config), targetCol, rd);
assertNotNull("SplitCandidate may not be null.", split);
assertThat(split, instanceOf(NominalMultiwaySplitCandidate.class));
// assertEquals("Wrong gain.", 36.233333333, split.getGainValue(), 1e-5);
assertTrue("Conditions should handle missing values therefore the missedRows BitSet must be empty.", split.getMissedRows().isEmpty());
nomSplit = (NominalMultiwaySplitCandidate) split;
conditions = nomSplit.getChildConditions();
assertEquals("3 values (not counting missing values) therefore there must be 3 children.", 3, conditions.length);
assertEquals("Wrong value.", "A", conditions[0].getValue());
assertEquals("Wrong value.", "B", conditions[1].getValue());
assertEquals("Wrong value.", "C", conditions[2].getValue());
assertFalse("Missings should go with majority", conditions[0].acceptsMissings());
assertTrue("Missings should go with majority", conditions[1].acceptsMissings());
assertFalse("Missings should go with majority", conditions[2].acceptsMissings());
}
use of org.knime.base.node.mine.treeensemble2.model.TreeNodeNominalCondition in project knime-core by knime.
the class TreeNodeNominalConditionTest method testToPMMLPredicate.
/**
* This method tests the {@link TreeNodeNominalCondition#toPMMLPredicate()} method.
*
* @throws Exception
*/
@Test
public void testToPMMLPredicate() throws Exception {
final TreeEnsembleLearnerConfiguration config = new TreeEnsembleLearnerConfiguration(false);
final TestDataGenerator dataGen = new TestDataGenerator(config);
final TreeNominalColumnData col = dataGen.createNominalAttributeColumn("A,A,B,C,C,D", "testcol", 0);
TreeNodeNominalCondition cond = new TreeNodeNominalCondition(col.getMetaData(), 3, false);
PMMLPredicate predicate = cond.toPMMLPredicate();
assertThat(predicate, instanceOf(PMMLSimplePredicate.class));
PMMLSimplePredicate simplePredicate = (PMMLSimplePredicate) predicate;
assertEquals("Wrong operator", PMMLOperator.EQUAL, simplePredicate.getOperator());
assertEquals("Wrong split value", "D", simplePredicate.getThreshold());
cond = new TreeNodeNominalCondition(col.getMetaData(), 0, true);
predicate = cond.toPMMLPredicate();
assertThat(predicate, instanceOf(PMMLCompoundPredicate.class));
PMMLCompoundPredicate compound = (PMMLCompoundPredicate) predicate;
assertEquals("Wrong boolean operator.", PMMLBooleanOperator.OR, compound.getBooleanOperator());
List<PMMLPredicate> preds;
preds = compound.getPredicates();
assertEquals("Wrong number of predicates in compound predicate.", 2, preds.size());
assertThat(preds.get(0), instanceOf(PMMLSimplePredicate.class));
simplePredicate = (PMMLSimplePredicate) preds.get(0);
assertEquals("Wrong operator", PMMLOperator.EQUAL, simplePredicate.getOperator());
assertEquals("Wrong split value", "A", simplePredicate.getThreshold());
assertEquals("Wrong attribute.", col.getMetaData().getAttributeName(), simplePredicate.getSplitAttribute());
assertThat(preds.get(1), instanceOf(PMMLSimplePredicate.class));
simplePredicate = (PMMLSimplePredicate) preds.get(1);
assertEquals("Should be isMissing", PMMLOperator.IS_MISSING, simplePredicate.getOperator());
}
Aggregations